Added NEW_GLIB_THREAD_API and OLD_GLIB_THREAD_API macros to test Glib thread API pre or post version 2.32.

Separate thread primative defines in utils/fluid_sys.h for new and old Glib thread API.
g_atomic_int_add is now used in place of depricated g_atomic_int_exchange_and_add if Glib >= 2.30.
Added name field to new_fluid_thread() function for setting the thread name and updated all uses of this function.
new_fluid_thread updated to use new Glib thread API.
Removed notify parameter from fluid_private_set() since it wasn't being used and complicates things with the new Glib thread API.
This commit is contained in:
Element Green 2013-08-19 23:10:43 +00:00
parent b65ae14ccf
commit 8ab1a20bc4
9 changed files with 137 additions and 33 deletions

View file

@ -233,7 +233,7 @@ new_fluid_shell(fluid_settings_t* settings, fluid_cmd_handler_t* handler,
fluid_shell_init(shell, settings, handler, in, out);
if (thread) {
shell->thread = new_fluid_thread((fluid_thread_func_t) fluid_shell_run, shell,
shell->thread = new_fluid_thread("shell", (fluid_thread_func_t) fluid_shell_run, shell,
0, TRUE);
if (shell->thread == NULL) {
delete_fluid_shell(shell);
@ -1982,7 +1982,7 @@ new_fluid_client(fluid_server_t* server, fluid_settings_t* settings,
client->settings = settings;
client->handler = handler;
client->thread = new_fluid_thread((fluid_thread_func_t) fluid_client_run, client,
client->thread = new_fluid_thread("client", (fluid_thread_func_t) fluid_client_run, client,
0, FALSE);
if (client->thread == NULL) {

View file

@ -303,7 +303,7 @@ new_fluid_alsa_audio_driver2(fluid_settings_t* settings,
}
/* Create the audio thread */
dev->thread = new_fluid_thread (fluid_alsa_formats[i].run, dev, realtime_prio, FALSE);
dev->thread = new_fluid_thread ("alsa-audio", fluid_alsa_formats[i].run, dev, realtime_prio, FALSE);
if (!dev->thread)
goto error_recovery;
@ -617,7 +617,7 @@ new_fluid_alsa_rawmidi_driver(fluid_settings_t* settings,
g_atomic_int_set(&dev->should_quit, 0);
/* create the MIDI thread */
dev->thread = new_fluid_thread (fluid_alsa_midi_run, dev, realtime_prio, FALSE);
dev->thread = new_fluid_thread ("alsa-midi-raw", fluid_alsa_midi_run, dev, realtime_prio, FALSE);
if (!dev->thread)
goto error_recovery;
@ -890,7 +890,7 @@ new_fluid_alsa_seq_driver(fluid_settings_t* settings,
g_atomic_int_set(&dev->should_quit, 0);
/* create the MIDI thread */
dev->thread = new_fluid_thread (fluid_alsa_seq_run, dev, realtime_prio, FALSE);
dev->thread = new_fluid_thread ("alsa-midi-seq", fluid_alsa_seq_run, dev, realtime_prio, FALSE);
if (portname) FLUID_FREE (portname);
if (id) FLUID_FREE (id);

View file

@ -226,7 +226,7 @@ new_fluid_oss_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth)
}
/* Create the audio thread */
dev->thread = new_fluid_thread (fluid_oss_audio_run, dev, realtime_prio, FALSE);
dev->thread = new_fluid_thread ("oss-audio", fluid_oss_audio_run, dev, realtime_prio, FALSE);
if (!dev->thread)
goto error_recovery;
@ -350,7 +350,7 @@ new_fluid_oss_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func,
}
/* Create the audio thread */
dev->thread = new_fluid_thread (fluid_oss_audio_run2, dev, realtime_prio, FALSE);
dev->thread = new_fluid_thread ("oss-audio", fluid_oss_audio_run2, dev, realtime_prio, FALSE);
if (!dev->thread)
goto error_recovery;
@ -574,7 +574,7 @@ new_fluid_oss_midi_driver(fluid_settings_t* settings,
dev->status = FLUID_MIDI_READY;
/* create MIDI thread */
dev->thread = new_fluid_thread (fluid_oss_midi_run, dev, realtime_prio, FALSE);
dev->thread = new_fluid_thread ("oss-midi", fluid_oss_midi_run, dev, realtime_prio, FALSE);
if (!dev->thread)
goto error_recovery;

View file

@ -158,7 +158,7 @@ new_fluid_pulse_audio_driver2(fluid_settings_t* settings,
FLUID_LOG(FLUID_INFO, "Using PulseAudio driver");
/* Create the audio thread */
dev->thread = new_fluid_thread (func ? fluid_pulse_audio_run2 : fluid_pulse_audio_run,
dev->thread = new_fluid_thread ("pulse-audio", func ? fluid_pulse_audio_run2 : fluid_pulse_audio_run,
dev, realtime_prio, FALSE);
if (!dev->thread)
goto error_recovery;

View file

@ -222,7 +222,7 @@ new_fluid_winmidi_driver(fluid_settings_t* settings,
}
/* Create thread which processes re-adding SYSEX buffers */
dev->sysExAddThread = new_fluid_thread (fluid_winmidi_add_sysex_thread,
dev->sysExAddThread = new_fluid_thread ("winmidi-sysex", fluid_winmidi_add_sysex_thread,
dev, 0, FALSE);
if (!dev->sysExAddThread)
{

View file

@ -887,6 +887,7 @@ fluid_rvoice_mixer_set_threads(fluid_rvoice_mixer_t* mixer, int thread_count,
int prio_level)
{
#ifdef ENABLE_MIXER_THREADS
char name[16];
int i;
// Kill all existing threads first
@ -928,7 +929,8 @@ fluid_rvoice_mixer_set_threads(fluid_rvoice_mixer_t* mixer, int thread_count,
if (!fluid_mixer_buffers_init(b, mixer))
return;
fluid_atomic_int_set(&b->ready, THREAD_BUF_NODATA);
b->thread = new_fluid_thread(fluid_mixer_thread_func, b, prio_level, 0);
g_snprintf (name, sizeof (name), "mixer%d", i);
b->thread = new_fluid_thread(name, fluid_mixer_thread_func, b, prio_level, 0);
if (!b->thread)
return;
}

View file

@ -4480,7 +4480,7 @@ fluid_synth_tuning_iteration_start(fluid_synth_t* synth)
{
fluid_return_if_fail (synth != NULL);
fluid_synth_api_enter(synth);
fluid_private_set (synth->tuning_iter, FLUID_INT_TO_POINTER (0), NULL);
fluid_private_set (synth->tuning_iter, FLUID_INT_TO_POINTER (0));
fluid_synth_api_exit(synth);
}
@ -4525,9 +4525,9 @@ fluid_synth_tuning_iteration_next(fluid_synth_t* synth, int* bank, int* prog)
*prog = p;
if (p < 127) fluid_private_set (synth->tuning_iter,
FLUID_INT_TO_POINTER (b << 8 | (p + 1)), NULL);
FLUID_INT_TO_POINTER (b << 8 | (p + 1)));
else fluid_private_set (synth->tuning_iter,
FLUID_INT_TO_POINTER ((b + 1) << 8), NULL);
FLUID_INT_TO_POINTER ((b + 1) << 8));
FLUID_API_RETURN(1);
}

View file

@ -571,6 +571,8 @@ void fluid_profiling_print(void)
*
*/
#if OLD_GLIB_THREAD_API
/* Rather than inline this one, we just declare it as a function, to prevent
* GCC warning about inline failure. */
fluid_cond_t *
@ -580,6 +582,8 @@ new_fluid_cond (void)
return g_cond_new ();
}
#endif
static gpointer
fluid_thread_high_prio (gpointer data)
{
@ -603,7 +607,7 @@ fluid_thread_high_prio (gpointer data)
* @return New thread pointer or NULL on error
*/
fluid_thread_t *
new_fluid_thread (fluid_thread_func_t func, void *data, int prio_level, int detach)
new_fluid_thread (const char *name, fluid_thread_func_t func, void *data, int prio_level, int detach)
{
GThread *thread;
fluid_thread_info_t *info;
@ -611,10 +615,12 @@ new_fluid_thread (fluid_thread_func_t func, void *data, int prio_level, int deta
g_return_val_if_fail (func != NULL, NULL);
#if OLD_GLIB_THREAD_API
/* Make sure g_thread_init has been called.
* FIXME - Probably not a good idea in a shared library,
* but what can we do *and* remain backwards compatible? */
if (!g_thread_supported ()) g_thread_init (NULL);
#endif
if (prio_level > 0)
{
@ -629,17 +635,30 @@ new_fluid_thread (fluid_thread_func_t func, void *data, int prio_level, int deta
info->func = func;
info->data = data;
info->prio_level = prio_level;
#if NEW_GLIB_THREAD_API
thread = g_thread_try_new (name, fluid_thread_high_prio, info, &err);
#else
thread = g_thread_create (fluid_thread_high_prio, info, detach == FALSE, &err);
#endif
}
#if NEW_GLIB_THREAD_API
else thread = g_thread_try_new (name, (GThreadFunc)func, data, &err);
#else
else thread = g_thread_create ((GThreadFunc)func, data, detach == FALSE, &err);
#endif
if (!thread)
{
FLUID_LOG(FLUID_ERR, "Failed to create the thread: %s",
fluid_gerror_message (err));
g_clear_error (&err);
return NULL;
}
#if NEW_GLIB_THREAD_API
if (detach) g_thread_unref (thread); // Release thread reference, if caller wants to detach
#endif
return thread;
}
@ -726,7 +745,7 @@ new_fluid_timer (int msec, fluid_timer_callback_t callback, void* data,
if (new_thread)
{
timer->thread = new_fluid_thread (fluid_timer_run, timer, high_priority
timer->thread = new_fluid_thread ("timer", fluid_timer_run, timer, high_priority
? FLUID_SYS_TIMER_HIGH_PRIO_LEVEL : 0, FALSE);
if (!timer->thread)
{
@ -1037,7 +1056,7 @@ new_fluid_server_socket(int port, fluid_server_func_t func, void* data)
server_socket->data = data;
server_socket->cont = 1;
server_socket->thread = new_fluid_thread(fluid_server_socket_run, server_socket,
server_socket->thread = new_fluid_thread("server", fluid_server_socket_run, server_socket,
0, FALSE);
if (server_socket->thread == NULL) {
FLUID_FREE(server_socket);
@ -1187,7 +1206,7 @@ new_fluid_server_socket(int port, fluid_server_func_t func, void* data)
server_socket->data = data;
server_socket->cont = 1;
server_socket->thread = new_fluid_thread(fluid_server_socket_run, server_socket,
server_socket->thread = new_fluid_thread("server", fluid_server_socket_run, server_socket,
0, FALSE);
if (server_socket->thread == NULL)
{

View file

@ -124,8 +124,86 @@ int delete_fluid_timer(fluid_timer_t* timer);
int fluid_timer_join(fluid_timer_t* timer);
int fluid_timer_stop(fluid_timer_t* timer);
// Macros to use for pre-processor if statements to test which Glib thread API we have (pre or post 2.32)
#define NEW_GLIB_THREAD_API (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 32))
#define OLD_GLIB_THREAD_API (GLIB_MAJOR_VERSION < 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 32))
/* Muteces */
#if NEW_GLIB_THREAD_API
/* glib 2.32 and newer */
/* Regular mutex */
typedef GMutex fluid_mutex_t;
#define FLUID_MUTEX_INIT { 0 }
#define fluid_mutex_init(_m) g_mutex_init (&(_m))
#define fluid_mutex_destroy(_m) g_mutex_clear (&(_m))
#define fluid_mutex_lock(_m) g_mutex_lock(&(_m))
#define fluid_mutex_unlock(_m) g_mutex_unlock(&(_m))
/* Recursive lock capable mutex */
typedef GRecMutex fluid_rec_mutex_t;
#define fluid_rec_mutex_init(_m) g_rec_mutex_init(&(_m))
#define fluid_rec_mutex_destroy(_m) g_rec_mutex_clear(&(_m))
#define fluid_rec_mutex_lock(_m) g_rec_mutex_lock(&(_m))
#define fluid_rec_mutex_unlock(_m) g_rec_mutex_unlock(&(_m))
/* Dynamically allocated mutex suitable for fluid_cond_t use */
typedef GMutex fluid_cond_mutex_t;
#define fluid_cond_mutex_lock(m) g_mutex_lock(m)
#define fluid_cond_mutex_unlock(m) g_mutex_unlock(m)
static FLUID_INLINE fluid_cond_mutex_t *
new_fluid_cond_mutex (void)
{
GMutex *mutex;
mutex = g_new (GMutex, 1);
g_mutex_init (mutex);
return (mutex);
}
static FLUID_INLINE void
delete_fluid_cond_mutex (fluid_cond_mutex_t *m)
{
g_mutex_clear (m);
g_free (m);
}
/* Thread condition signaling */
typedef GCond fluid_cond_t;
#define fluid_cond_signal(cond) g_cond_signal(cond)
#define fluid_cond_broadcast(cond) g_cond_broadcast(cond)
#define fluid_cond_wait(cond, mutex) g_cond_wait(cond, mutex)
static FLUID_INLINE fluid_cond_t *
new_fluid_cond (void)
{
GCond *cond;
cond = g_new (GCond, 1);
g_cond_init (cond);
return (cond);
}
static FLUID_INLINE void
delete_fluid_cond (fluid_cond_t *cond)
{
g_cond_clear (cond);
g_free (cond);
}
/* Thread private data */
typedef GPrivate fluid_private_t;
#define fluid_private_init(_priv) memset (&_priv, 0, sizeof (_priv))
#define fluid_private_free(_priv)
#define fluid_private_get(_priv) g_private_get(&(_priv))
#define fluid_private_set(_priv, _data) g_private_set(&(_priv), _data)
#else
/* glib prior to 2.32 */
/* Regular mutex */
typedef GStaticMutex fluid_mutex_t;
#define FLUID_MUTEX_INIT G_STATIC_MUTEX_INIT
@ -162,9 +240,7 @@ new_fluid_cond_mutex (void)
return g_mutex_new ();
}
/* Thread condition signaling */
typedef GCond fluid_cond_t;
fluid_cond_t *new_fluid_cond (void);
#define delete_fluid_cond(cond) g_cond_free(cond)
@ -172,6 +248,19 @@ fluid_cond_t *new_fluid_cond (void);
#define fluid_cond_broadcast(cond) g_cond_broadcast(cond)
#define fluid_cond_wait(cond, mutex) g_cond_wait(cond, mutex)
/* Thread private data */
typedef GStaticPrivate fluid_private_t;
#define fluid_private_get(_priv) g_static_private_get(&(_priv))
#define fluid_private_set(_priv, _data) g_static_private_set(&(_priv), _data)
#define fluid_private_free(_priv) g_static_private_free(&(_priv))
#define fluid_private_init(_priv) G_STMT_START { \
if (!g_thread_supported ()) g_thread_init (NULL); \
g_static_private_init (&(_priv)); \
} G_STMT_END;
#endif
/* Atomic operations */
@ -182,8 +271,14 @@ fluid_cond_t *new_fluid_cond (void);
#define fluid_atomic_int_dec_and_test(_pi) g_atomic_int_dec_and_test(_pi)
#define fluid_atomic_int_compare_and_exchange(_pi, _old, _new) \
g_atomic_int_compare_and_exchange(_pi, _old, _new)
#if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 30)
#define fluid_atomic_int_exchange_and_add(_pi, _add) \
g_atomic_int_add(_pi, _add)
#else
#define fluid_atomic_int_exchange_and_add(_pi, _add) \
g_atomic_int_exchange_and_add(_pi, _add)
#endif
#define fluid_atomic_pointer_get(_pp) g_atomic_pointer_get(_pp)
#define fluid_atomic_pointer_set(_pp, val) g_atomic_pointer_set(_pp, val)
@ -209,18 +304,6 @@ fluid_atomic_float_get(volatile float *fptr)
}
/* Thread private data */
typedef GStaticPrivate fluid_private_t;
#define fluid_private_get(_priv) g_static_private_get(&(_priv))
#define fluid_private_set(_priv, _data, _notify) g_static_private_set(&(_priv), _data, _notify)
#define fluid_private_free(_priv) g_static_private_free(&(_priv))
#define fluid_private_init(_priv) G_STMT_START { \
if (!g_thread_supported ()) g_thread_init (NULL); \
g_static_private_init (&(_priv)); \
} G_STMT_END;
/* Threads */
typedef GThread fluid_thread_t;
@ -230,7 +313,7 @@ typedef void (*fluid_thread_func_t)(void* data);
#define fluid_thread_id_t GThread * /* Data type for a thread ID */
#define fluid_thread_get_id() g_thread_self() /* Get unique "ID" for current thread */
fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void *data,
fluid_thread_t* new_fluid_thread(const char *name, fluid_thread_func_t func, void *data,
int prio_level, int detach);
void delete_fluid_thread(fluid_thread_t* thread);
void fluid_thread_self_set_prio (int prio_level);