Replaced pthread and system time primitives with std::mutex, std::chrono, and std::this_thread::sleep_for, and fixed the thread iterator loop to continue iterating properly on object removal
parent
71dcd91c6b
commit
cf3318c2c9
|
@ -2,14 +2,12 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <time.h>
|
#include <mutex>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#define SF2PACK
|
#define SF2PACK
|
||||||
|
|
||||||
|
@ -35,12 +33,12 @@ static bool is_gs_reset(const unsigned char * data, unsigned long size)
|
||||||
struct Cached_SoundFont
|
struct Cached_SoundFont
|
||||||
{
|
{
|
||||||
unsigned long ref_count;
|
unsigned long ref_count;
|
||||||
time_t time_released;
|
std::chrono::time_point<std::chrono::steady_clock> time_released;
|
||||||
HSOUNDFONT handle;
|
HSOUNDFONT handle;
|
||||||
Cached_SoundFont() : handle( 0 ) { }
|
Cached_SoundFont() : handle( 0 ) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
static pthread_mutex_t Cache_Lock;
|
static std::mutex Cache_Lock;
|
||||||
|
|
||||||
static std::map<std::string, Cached_SoundFont> Cache_List;
|
static std::map<std::string, Cached_SoundFont> Cache_List;
|
||||||
|
|
||||||
|
@ -52,7 +50,6 @@ static void cache_run();
|
||||||
|
|
||||||
static void cache_init()
|
static void cache_init()
|
||||||
{
|
{
|
||||||
pthread_mutex_init( &Cache_Lock, NULL );
|
|
||||||
Cache_Thread = new std::thread( cache_run );
|
Cache_Thread = new std::thread( cache_run );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +69,7 @@ static HSOUNDFONT cache_open( const char * path )
|
||||||
{
|
{
|
||||||
HSOUNDFONT font = NULL;
|
HSOUNDFONT font = NULL;
|
||||||
|
|
||||||
pthread_mutex_lock( &Cache_Lock );
|
std::lock_guard<std::mutex> lock( Cache_Lock );
|
||||||
|
|
||||||
Cached_SoundFont & entry = Cache_List[ path ];
|
Cached_SoundFont & entry = Cache_List[ path ];
|
||||||
|
|
||||||
|
@ -92,60 +89,59 @@ static HSOUNDFONT cache_open( const char * path )
|
||||||
else
|
else
|
||||||
font = entry.handle;
|
font = entry.handle;
|
||||||
|
|
||||||
pthread_mutex_unlock( &Cache_Lock );
|
|
||||||
|
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cache_close( HSOUNDFONT handle )
|
static void cache_close( HSOUNDFONT handle )
|
||||||
{
|
{
|
||||||
pthread_mutex_lock( &Cache_Lock );
|
std::lock_guard<std::mutex> lock( Cache_Lock );
|
||||||
|
|
||||||
for ( auto it = Cache_List.begin(); it != Cache_List.end(); ++it )
|
for ( auto it = Cache_List.begin(); it != Cache_List.end(); ++it )
|
||||||
{
|
{
|
||||||
if ( it->second.handle == handle )
|
if ( it->second.handle == handle )
|
||||||
{
|
{
|
||||||
if ( --it->second.ref_count == 0 )
|
if ( --it->second.ref_count == 0 )
|
||||||
time( &it->second.time_released );
|
it->second.time_released = std::chrono::steady_clock::now();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock( &Cache_Lock );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cache_run()
|
static void cache_run()
|
||||||
{
|
{
|
||||||
|
std::chrono::milliseconds dura( 250 );
|
||||||
|
|
||||||
Cache_Running = true;
|
Cache_Running = true;
|
||||||
|
|
||||||
while ( Cache_Running )
|
while ( Cache_Running )
|
||||||
{
|
{
|
||||||
time_t now;
|
std::chrono::time_point<std::chrono::steady_clock> now = std::chrono::steady_clock::now();
|
||||||
time( &now );
|
|
||||||
|
|
||||||
pthread_mutex_lock( &Cache_Lock );
|
|
||||||
|
|
||||||
for ( auto it = Cache_List.begin(); it != Cache_List.end(); ++it )
|
|
||||||
{
|
{
|
||||||
if ( it->second.ref_count == 0 )
|
std::lock_guard<std::mutex> lock( Cache_Lock );
|
||||||
|
for ( auto it = Cache_List.begin(); it != Cache_List.end(); )
|
||||||
{
|
{
|
||||||
if ( difftime( it->second.time_released, now ) >= 10.0 )
|
if ( it->second.ref_count == 0 )
|
||||||
{
|
{
|
||||||
BASS_MIDI_FontFree( it->second.handle );
|
std::chrono::duration<double> elapsed = now - it->second.time_released;
|
||||||
Cache_List.erase( it );
|
if ( elapsed.count() >= 10.0 )
|
||||||
|
{
|
||||||
|
BASS_MIDI_FontFree( it->second.handle );
|
||||||
|
it = Cache_List.erase( it );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock( &Cache_Lock );
|
std::this_thread::sleep_for( dura );
|
||||||
|
|
||||||
usleep( 250000 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class Bass_Initializer
|
static class Bass_Initializer
|
||||||
{
|
{
|
||||||
pthread_mutex_t lock;
|
std::mutex lock;
|
||||||
|
|
||||||
bool initialized;
|
bool initialized;
|
||||||
|
|
||||||
|
@ -154,7 +150,6 @@ static class Bass_Initializer
|
||||||
public:
|
public:
|
||||||
Bass_Initializer() : initialized(false)
|
Bass_Initializer() : initialized(false)
|
||||||
{
|
{
|
||||||
pthread_mutex_init( &lock, NULL );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~Bass_Initializer()
|
~Bass_Initializer()
|
||||||
|
@ -164,14 +159,11 @@ public:
|
||||||
cache_deinit();
|
cache_deinit();
|
||||||
BASS_Free();
|
BASS_Free();
|
||||||
}
|
}
|
||||||
pthread_mutex_destroy( &lock );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_initialized()
|
bool check_initialized()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&lock);
|
std::lock_guard<std::mutex> lock( this->lock );
|
||||||
bool initialized = this->initialized;
|
|
||||||
pthread_mutex_unlock(&lock);
|
|
||||||
return initialized;
|
return initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,8 +185,7 @@ public:
|
||||||
|
|
||||||
bool initialize()
|
bool initialize()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&lock);
|
std::lock_guard<std::mutex> lock( this->lock );
|
||||||
bool initialized = this->initialized;
|
|
||||||
if ( !initialized )
|
if ( !initialized )
|
||||||
{
|
{
|
||||||
#ifdef SF2PACK
|
#ifdef SF2PACK
|
||||||
|
@ -211,10 +202,8 @@ public:
|
||||||
BASS_SetConfigPtr( BASS_CONFIG_MIDI_DEFFONT, NULL );
|
BASS_SetConfigPtr( BASS_CONFIG_MIDI_DEFFONT, NULL );
|
||||||
BASS_SetConfig( BASS_CONFIG_MIDI_VOICES, 256 );
|
BASS_SetConfig( BASS_CONFIG_MIDI_VOICES, 256 );
|
||||||
cache_init();
|
cache_init();
|
||||||
this->initialized = initialized;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&lock);
|
|
||||||
return initialized;
|
return initialized;
|
||||||
}
|
}
|
||||||
} g_initializer;
|
} g_initializer;
|
||||||
|
|
Loading…
Reference in New Issue