From: phantomjinx <pha...@us...> - 2012-06-01 08:18:47
|
commit 525bfe4b174b2037dd9ea34c37867748b0a06162 Author: phantomjinx <p.g...@ph...> Date: Thu May 31 23:33:37 2012 +0100 Modifications due to change in gthreads API * Threading API in glib-2.0 < 2.31 has been deprecated so must be migrated to new API. * Preserves backward compatibility with glib-2.0 < 2.31 configure.ac | 15 +- libgtkpod/autodetection.c | 43 +++++- libgtkpod/file_convert.c | 189 +++++++++++++++++++-------- libgtkpod/file_itunesdb.c | 128 +++++++++++++++--- libgtkpod/prefs.c | 41 +++++- libgtkpod/tools.c | 99 ++++++++++++--- plugins/sjcd/libjuicer/sj-metadata-getter.c | 14 ++- src/main.c | 6 + 8 files changed, 424 insertions(+), 111 deletions(-) --- diff --git a/configure.ac b/configure.ac index ed37002..fd60c35 100644 --- a/configure.ac +++ b/configure.ac @@ -38,8 +38,8 @@ AC_CANONICAL_HOST AC_SEARCH_LIBS([strerror],[cposix]) AC_DIAGNOSE([obsolete],[AM_PROG_CC_STDC: - your code should no longer depend upon `am_cv_prog_cc_stdc', but upon - `ac_cv_prog_cc_stdc'. Remove this warning and the assignment when + your code should no longer depend upon am_cv_prog_cc_stdc, but upon + ac_cv_prog_cc_stdc. Remove this warning and the assignment when you adjust the code. You can also remove the above call to AC_PROG_CC if you already called it elsewhere.]) am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc @@ -110,17 +110,18 @@ PKG_CHECK_MODULES(MUSICBRAINZ4, libmusicbrainz4 >= 4.0.0, [have_mb4="yes"], [hav GTK_CLEANLINESS_FLAGS="-DG_DISABLE_SINGLE_INCLUDES -DGDK_PIXBUF_DISABLE_SINGLE_INCLUDES -DGTK_DISABLE_SINGLE_INCLUDES -DGSEAL_ENABLE" AC_MSG_CHECKING(for using DISABLE_DEPRECATED flags) -if expr "$LIBGTKPOD_VERSION" : '.*~' >/dev/null; then + +dnl if expr "$LIBGTKPOD_VERSION" : '.*~' >/dev/null; then dnl The version contains a tilde so this is not a release dnl Thus, we can add in disable deprecated flags to avoid dnl using deprecated functions - GTK_CLEANLINESS_FLAGS="$GTK_CLEANLINESS_FLAGS -DG_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED" - AC_MSG_RESULT(yes) -else +dnl GTK_CLEANLINESS_FLAGS="$GTK_CLEANLINESS_FLAGS -DG_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED" +dnl AC_MSG_RESULT(yes) +dnl else dnl The version is a release so do not include deprecated dnl flags. AC_MSG_RESULT(no) -fi +dnl fi dnl Force C99 mode (no implicit int declarations) CFLAGS="$CFLAGS -std=gnu99 -Werror-implicit-function-declaration" diff --git a/libgtkpod/autodetection.c b/libgtkpod/autodetection.c index e0bc5b0..48b9f4c 100644 --- a/libgtkpod/autodetection.c +++ b/libgtkpod/autodetection.c @@ -106,13 +106,42 @@ typedef struct _AutoDetect AutoDetect; static gboolean ad_timeout_cb(gpointer data); struct _AutoDetect { +#if GLIB_CHECK_VERSION(2,31,0) + GMutex mutex; /* shared lock */ +#else GMutex *mutex; /* shared lock */ +#endif + GList *new_ipod_uris; /* list of new mounts */ guint timeout_id; }; static AutoDetect *autodetect; +static void _create_mutex(AutoDetect *ad) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_init(&ad->mutex); +#else + ad->mutex = g_mutex_new (); +#endif +} + +static void _lock_mutex(AutoDetect *ad) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_lock (&ad->mutex); +#else + g_mutex_lock (ad->mutex); +#endif +} + +static void _unlock_mutex(AutoDetect *ad) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_unlock (&ad->mutex); +#else + g_mutex_unlock (ad->mutex); +#endif +} + /* adapted from rb-ipod-plugin.c (rhythmbox ipod plugin) */ static gboolean ad_mount_is_ipod(GMount *mount) { gboolean result = FALSE; @@ -146,9 +175,9 @@ static void ad_volume_mounted_cb(GVolumeMonitor *volumemonitor, GMount *mount, A if (uri) { debug ("mounted iPod: '%s'\n", uri); - g_mutex_lock (ad->mutex); + _lock_mutex(ad); ad->new_ipod_uris = g_list_prepend(ad->new_ipod_uris, uri); - g_mutex_unlock (ad->mutex); + _unlock_mutex(ad); } else { fprintf(stderr, "ERROR: could not get activation root!\n"); @@ -167,7 +196,7 @@ void autodetection_init() { g_once (&g_type_init_once, (GThreadFunc)g_type_init, NULL); autodetect = g_new0 (AutoDetect, 1); - autodetect->mutex = g_mutex_new (); + _create_mutex(autodetect); /* Check if an iPod is already mounted and add it to the list */ mounts = g_volume_monitor_get_mounts(g_volume_monitor_get()); @@ -198,7 +227,7 @@ static gboolean ad_timeout_cb(gpointer data) { /* Don't interfere with a blocked display -- try again later */ if (!widgets_blocked) { gdk_threads_enter(); - g_mutex_lock (ad->mutex); + _lock_mutex(ad); while (ad->new_ipod_uris) { iTunesDB *itdb = NULL, *loaded_itdb = NULL; @@ -211,7 +240,7 @@ static gboolean ad_timeout_cb(gpointer data) { ad->new_ipod_uris = g_list_delete_link(ad->new_ipod_uris, gl); - g_mutex_unlock (ad->mutex); + _unlock_mutex(ad); g_return_val_if_fail (mount_uri, (gdk_threads_leave(), release_widgets(), TRUE)); @@ -276,9 +305,9 @@ static gboolean ad_timeout_cb(gpointer data) { g_free(mount_uri); g_free(displaymp); - g_mutex_lock (ad->mutex); + _lock_mutex(ad); } - g_mutex_unlock (ad->mutex); + _unlock_mutex(ad); gdk_threads_leave(); } diff --git a/libgtkpod/file_convert.c b/libgtkpod/file_convert.c index 5dbc27e..567c1a9 100644 --- a/libgtkpod/file_convert.c +++ b/libgtkpod/file_convert.c @@ -110,6 +110,8 @@ processed next. */ +#define CONVERSION_THREAD "Conversion Thread" + /* Preferences keys */ const gchar *FILE_CONVERT_CACHEDIR = "file_convert_cachedir"; const gchar *FILE_CONVERT_MAXDIRSIZE = "file_convert_maxdirsize"; @@ -163,32 +165,37 @@ struct GaplessData { }; struct _Conversion { - GMutex *mutex; /* shared lock */ +#if GLIB_CHECK_VERSION(2,31,0) + GMutex mutex; /* mutex for this struct */ + GCond finished_cond; /* signals if a new track is added to the finished list */ + GCond dirsize_cond; /* signal when dirsize has been updated */ + GCond prune_cond; /* signal when dir has been pruned */ +#else + GMutex *mutex; /* mutex for this struct */ + GCond *finished_cond; /* signals if a new track is added to the finished list */ + GCond *dirsize_cond; /* signal when dirsize has been updated */ + GCond *prune_cond; /* signal when dir has been pruned */ +#endif + GList *scheduled; /* tracks scheduled for conversion */ GList *processing; /* tracks currently being converted */ GList *failed; /* tracks with failed conversion */ - GList *converted; /* tracks successfully converted but not - yet unscheduled */ - GList *finished; /* tracks unscheduled but not yet - transferred */ - GCond *finished_cond; /* signals if a new track is added to the - finished list */ + GList *converted; /* tracks successfully converted but not yet unscheduled */ + GList *finished; /* tracks unscheduled but not yet transferred */ + gchar *cachedir; /* directory for converted files */ gchar *template; /* name template to use for converted files */ gint max_threads_num; /* maximum number of allowed threads */ GList *threads; /* list of threads */ gint threads_num; /* number of threads currently running */ - gboolean conversion_force; /* force a new thread to start even if - the dirsize is too large */ + gboolean conversion_force; /* force a new thread to start even if the dirsize is too large */ gint64 max_dirsize; /* maximum size of cache directory in bytes */ gint64 dirsize; /* current size of cache directory in bytes */ gboolean dirsize_in_progress; /* currently determining dirsize */ - GCond *dirsize_cond; /* signal when dirsize has been updated */ gboolean prune_in_progress; /* currently pruning directory */ - GCond *prune_cond; /* signal when dir has been pruned */ - gboolean force_prune_in_progress; /* do another prune right after - the current process finishes */ + gboolean force_prune_in_progress; /* do another prune right after the current process finishes */ guint timeout_id; + /* data for log display */ GtkWidget *log_window; /* display log window */ gboolean log_window_hidden; /* whether the window was closed */ @@ -201,9 +208,9 @@ struct _Conversion { GList *pages; /* list with pages currently added */ GtkStatusbar *log_statusbar; /* statusbar of log display */ guint log_context_id; /* context ID for statusbar */ + /* data for background transfer */ - GList *transfer_itdbs; /* list with TransferItdbs for background - transfer */ + GList *transfer_itdbs; /* list with TransferItdbs for background transfer */ gchar *last_error_msg; /* keep a record of the last error message */ }; @@ -259,6 +266,103 @@ enum { static Conversion *conversion = NULL; +static GThread *_create_thread(GThreadFunc func, gpointer userdata) { +#if GLIB_CHECK_VERSION(2,31,0) + return g_thread_new (CONVERSION_THREAD, func, userdata); +#else + return g_thread_create_full(func, + userdata, + 0, /* stack size */ + FALSE, /* joinable */ + TRUE, /* bound */ + G_THREAD_PRIORITY_NORMAL, NULL); /* error */ +#endif +} + +static void _create_mutex(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_init(&c->mutex); +#else + c->mutex = g_mutex_new (); +#endif +} + +static gboolean _try_lock(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + return g_mutex_trylock(&c->mutex); +#else + return g_mutex_trylock(c->mutex); +#endif +} + +static void _lock_mutex(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_lock (&c->mutex); +#else + g_mutex_lock (c->mutex); +#endif +} + +static void _unlock_mutex(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_unlock (&c->mutex); +#else + g_mutex_unlock (c->mutex); +#endif +} + +static void _create_cond(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_init(&c->finished_cond); + g_cond_init(&c->dirsize_cond); + g_cond_init(&c->prune_cond); +#else + c->finished_cond = g_cond_new (); + c->dirsize_cond = g_cond_new (); + c->prune_cond = g_cond_new (); +#endif +} + +static void _broadcast_prune_cond(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_broadcast (&c->prune_cond); +#else + g_cond_broadcast (c->prune_cond); +#endif +} + +static void _broadcast_dirsize_cond(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_broadcast (&c->dirsize_cond); +#else + g_cond_broadcast (c->dirsize_cond); +#endif +} + +static void _broadcast_finished_cond(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_broadcast (&c->finished_cond); +#else + g_cond_broadcast (c->finished_cond); +#endif +} + +static void _wait_prune_cond(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_wait (&c->prune_cond, &c->mutex); +#else + g_cond_wait (c->prune_cond, c->mutex); +#endif +} + +static void _wait_dirsize_cond(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_wait (&c->dirsize_cond, &c->mutex); +#else + g_cond_wait (c->dirsize_cond, c->mutex); +#endif +} + /* Set up conversion infrastructure. Must only be called once. */ void file_convert_init() { GtkBuilder *log_builder; @@ -268,11 +372,9 @@ void file_convert_init() { return; conversion = g_new0 (Conversion, 1); - conversion->mutex = g_mutex_new (); + _create_mutex(conversion); - conversion->finished_cond = g_cond_new (); - conversion->dirsize_cond = g_cond_new (); - conversion->prune_cond = g_cond_new (); + _create_cond(conversion); conversion_setup_cachedir(conversion); if (!prefs_get_string_value(FILE_CONVERT_TEMPLATE, NULL)) { @@ -347,12 +449,12 @@ void file_convert_shutdown() { static void file_convert_lock(Conversion *conv) { debug ("Locking conversion"); - g_mutex_lock(conv->mutex); + _lock_mutex(conv); } static void file_convert_unlock(Conversion *conv) { debug("Unlocking conversion"); - g_mutex_unlock(conv->mutex); + _unlock_mutex(conv); } /* This is called just before gtkpod closes down */ @@ -626,12 +728,7 @@ static void conversion_prefs_changed(Conversion *conv) { if ((conv->dirsize == CONV_DIRSIZE_INVALID) || (conv->dirsize > conv->max_dirsize)) { /* Prune dir of unused files if size is too big, calculate and set the size of the directory. Do all that in the background. */ - g_thread_create_full(conversion_prune_dir, - conv, /* user data */ - 0, /* stack size */ - FALSE, /* joinable */ - TRUE, /* bound */ - G_THREAD_PRIORITY_NORMAL, NULL); /* error */ + _create_thread(conversion_prune_dir, conv); } background_transfer = prefs_get_int(FILE_CONVERT_BACKGROUND_TRANSFER); @@ -1291,11 +1388,7 @@ static gboolean conversion_scheduler_unlocked(Conversion *conv) { GList *gl; GThread *thread; - thread = g_thread_create_full(conversion_thread, conv, /* user data */ - 0, /* stack size */ - FALSE, /* joinable */ - TRUE, /* bound */ - G_THREAD_PRIORITY_LOW, NULL); /* error */ + thread = _create_thread(conversion_thread, conv); /* Add thread to thread list. Use first available slot */ gl = g_list_find(conv->threads, NULL); @@ -1438,7 +1531,7 @@ static gboolean conversion_scheduler_unlocked(Conversion *conv) { g_return_val_if_fail (tr && tr->itdb && tr->userdata, TRUE); etr = tr->userdata; /* broadcast finished track */ - g_cond_broadcast (conv->finished_cond); + _broadcast_finished_cond(conv); tri = transfer_get_tri(conv, tr->itdb); g_return_val_if_fail (tri, TRUE); @@ -1477,11 +1570,7 @@ static gboolean conversion_scheduler_unlocked(Conversion *conv) { g_return_val_if_fail (tri, TRUE); if (tri->scheduled) { if ((tri->thread == NULL) && (tri->transfer == TRUE) && (tri->status != FILE_TRANSFER_DISK_FULL)) { /* start new thread */ - tri->thread = g_thread_create_full(transfer_thread, tri, /* user data */ - 0, /* stack size */ - FALSE, /* joinable */ - TRUE, /* bound */ - G_THREAD_PRIORITY_LOW, NULL); /* error */ + tri->thread = _create_thread(transfer_thread, tri); } } @@ -1579,7 +1668,7 @@ static gboolean conversion_scheduler(gpointer data) { // debug ("conversion_scheduler enter\n"); gdk_threads_enter(); - if (!g_mutex_trylock(conv->mutex)) { + if (!_try_lock(conv)) { gdk_threads_leave(); /* Do not destroy the timeout function by returning FALSE */ return TRUE; @@ -1608,7 +1697,7 @@ static gpointer conversion_update_dirsize(gpointer data) { file_convert_lock(conv); if (conv->dirsize_in_progress) { /* another thread is already working on the directory size. We'll wait until it has finished and just return. */ - g_cond_wait (conv->dirsize_cond, conv->mutex); + _wait_dirsize_cond(conv); file_convert_unlock(conv); debug ("%p update_dirsize concurrent exit\n", g_thread_self ()); return NULL; @@ -1635,7 +1724,7 @@ static gpointer conversion_update_dirsize(gpointer data) { /* We're finished doing the directory upgrade. Unset the flag and broadcast to all threads waiting to wake them up. */ conv->dirsize_in_progress = FALSE; - g_cond_broadcast (conv->dirsize_cond); + _broadcast_dirsize_cond(conv); file_convert_unlock(conv); debug ("%p update_dirsize exit\n", g_thread_self ()); @@ -1734,7 +1823,7 @@ static gpointer conversion_prune_dir(gpointer data) { file_convert_lock(conv); if (conv->prune_in_progress) { /* another thread is already working on the directory prune. We'll wait until it has finished and just return. */ - g_cond_wait (conv->prune_cond, conv->mutex); + _wait_prune_cond(conv); file_convert_unlock(conv); return NULL; } @@ -1766,7 +1855,7 @@ static gpointer conversion_prune_dir(gpointer data) { for (gl = conv->transfer_itdbs; gl; gl = gl->next) { TransferItdb *tri = gl->data; g_return_val_if_fail (tri, (conv->prune_in_progress = FALSE, - g_cond_broadcast (conv->prune_cond), + _broadcast_prune_cond(conv), file_convert_unlock(conv), NULL)); conversion_prune_needed_add(hash_needed_files, tri->scheduled); @@ -1795,11 +1884,11 @@ static gpointer conversion_prune_dir(gpointer data) { for (gl = files; gl && (dirsize > maxsize); gl = gl->next) { struct conversion_prune_file *cpf = gl->data; g_return_val_if_fail (cpf, (conv->prune_in_progress = FALSE, - g_cond_broadcast (conv->prune_cond), + _broadcast_prune_cond(conv), NULL)); g_return_val_if_fail (cpf->filename, (conv->prune_in_progress = FALSE, - g_cond_broadcast (conv->prune_cond), + _broadcast_prune_cond(conv), NULL)); if (g_hash_table_lookup(hash_needed_files, cpf->filename) == NULL) { /* file is not among those remove */ if (g_remove(cpf->filename) == 0) { @@ -1821,7 +1910,7 @@ static gpointer conversion_prune_dir(gpointer data) { file_convert_lock(conv); conv->prune_in_progress = FALSE; - g_cond_broadcast (conv->prune_cond); + _broadcast_prune_cond(conv); file_convert_unlock(conv); debug ("%p prune_dir exit\n", g_thread_self ()); @@ -2677,7 +2766,7 @@ static gpointer transfer_force_prune_dir(gpointer data) { return NULL; } conv->force_prune_in_progress = TRUE; - g_cond_wait (conv->prune_cond, conv->mutex); + _wait_prune_cond(conv); conv->force_prune_in_progress = FALSE; } @@ -2861,11 +2950,7 @@ static gpointer transfer_thread(gpointer data) { if (conv->dirsize > conv->max_dirsize) { /* we just transferred a track -- there should be space available again -> force a directory prune */ - g_thread_create_full(transfer_force_prune_dir, conv, /* user data */ - 0, /* stack size */ - FALSE, /* joinable */ - TRUE, /* bound */ - G_THREAD_PRIORITY_NORMAL, NULL); /* error */ + _create_thread(transfer_force_prune_dir, conv); } } diff --git a/libgtkpod/file_itunesdb.c b/libgtkpod/file_itunesdb.c index 921fe69..f3f96f6 100644 --- a/libgtkpod/file_itunesdb.c +++ b/libgtkpod/file_itunesdb.c @@ -52,6 +52,8 @@ #define debug(s) printf(__FILE__":" TO_STR(__LINE__) ":" s) #define debugx(s,...) printf(__FILE__":" TO_STR(__LINE__) ":" s,__VA_ARGS__) +#define TRANSFER_THREAD "Transfer Data Thread" + #define WRITE_EXTENDED_INFO TRUE /* #define WRITE_EXTENDED_INFO prefs_get_int("write_extended_info") */ @@ -82,9 +84,15 @@ struct track_extended_info { }; typedef struct { +#if GLIB_CHECK_VERSION(2,31,0) + GMutex mutex; /* mutex for this struct */ + GCond finished_cond; /* used to signal end of thread */ +#else GMutex *mutex; /* mutex for this struct */ - gboolean abort; /* TRUE = abort */ GCond *finished_cond; /* used to signal end of thread */ +#endif + + gboolean abort; /* TRUE = abort */ gboolean finished; /* background thread has finished */ Track *track; /* Current track */ const gchar *filename; /* Filename to copy/remove */ @@ -100,6 +108,83 @@ static float extendedinfoversion = 0.0; /* Some declarations */ static gboolean gp_write_itdb(iTunesDB *itdb); +static GThread *_create_thread(GThreadFunc func, gpointer userdata) { +#if GLIB_CHECK_VERSION(2,31,0) + return g_thread_new (TRANSFER_THREAD, func, userdata); +#else + return g_thread_create (func, userdata, TRUE, NULL); +#endif +} + +static void _create_mutex(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_init(&td->mutex); +#else + td->mutex = g_mutex_new (); +#endif +} + +static void _lock_mutex(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_lock (&td->mutex); +#else + g_mutex_lock (td->mutex); +#endif +} + +static void _unlock_mutex(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_unlock (&td->mutex); +#else + g_mutex_unlock (td->mutex); +#endif +} + +static void _clear_mutex(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_clear (&td->mutex); +#else + if (td->mutex) + g_mutex_free (td->mutex); +#endif +} + +static void _create_cond(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_init(&td->finished_cond); +#else + td->finished_cond = g_cond_new (); +#endif +} + +static void _cond_signal(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_signal (&td->finished_cond); +#else + g_cond_signal (td->finished_cond); +#endif +} + +static void _cond_timed_wait(TransferData *td, glong timeout) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_wait_until (&td->finished_cond, &td->mutex, (gint64) timeout); +#else + GTimeVal gtime; + g_get_current_time(>ime); + g_time_val_add(>ime, timeout); + g_cond_timed_wait (td->finished_cond, td->mutex, >ime); +#endif +} + +static void _clear_cond(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_clear (&td->finished_cond); +#else + if (td->finished_cond) + g_cond_free (td->finished_cond); +#endif +} + /* fills in extended info if available */ /* num/total are used to give updates in case the sha1 checksums have to be matched against the files which is very time consuming */ @@ -1181,17 +1266,18 @@ gboolean gp_create_extended_info(iTunesDB *itdb) { TransferData *transfer_data_new(void) { TransferData *transfer_data; transfer_data = g_new0 (TransferData, 1); - transfer_data->mutex = g_mutex_new (); - transfer_data->finished_cond = g_cond_new (); + + _create_mutex(transfer_data); + _create_cond(transfer_data); + transfer_data->current_progress = 0; return transfer_data; } void transfer_data_free(TransferData *transfer_data) { - if (transfer_data->mutex) - g_mutex_free (transfer_data->mutex); - if (transfer_data->finished_cond) - g_cond_free (transfer_data->finished_cond); + _clear_mutex(transfer_data); + _clear_cond(transfer_data); + g_free(transfer_data); } @@ -1202,10 +1288,15 @@ static gpointer th_remove(gpointer userdata) { gint result; result = g_remove(td->filename); - g_mutex_lock (td->mutex); + + _lock_mutex(td); + td->finished = TRUE; /* signal that thread will end */ - g_cond_signal (td->finished_cond); - g_mutex_unlock (td->mutex); + + _cond_signal(td); + + _unlock_mutex(td); + return GINT_TO_POINTER(result); } @@ -1330,31 +1421,26 @@ static gboolean delete_files(iTunesDB *itdb, TransferData *td) { td->finished = FALSE; td->filename = filename; - g_mutex_lock (td->mutex); + _lock_mutex (td); - thread = g_thread_create (th_remove, td, TRUE, NULL); + thread = _create_thread(th_remove, td); do { - GTimeVal gtime; - td->current_progress = set_progress(start, n, count, 0, td->current_progress, "deletion completed"); - g_mutex_unlock (td->mutex); + _unlock_mutex (td); while (widgets_blocked && gtk_events_pending()) gtk_main_iteration(); - g_mutex_lock (td->mutex); + _lock_mutex (td); /* wait a maximum of 20 ms or until cond is signaled */ - g_get_current_time(>ime); - g_time_val_add(>ime, 20000); - g_cond_timed_wait (td->finished_cond, - td->mutex, >ime); + _cond_timed_wait(td, 20000); } while (!td->finished); - g_mutex_unlock (td->mutex); + _unlock_mutex (td); rmres = GPOINTER_TO_INT(g_thread_join (thread)); diff --git a/libgtkpod/prefs.c b/libgtkpod/prefs.c index 249d71d..97ffc38 100644 --- a/libgtkpod/prefs.c +++ b/libgtkpod/prefs.c @@ -99,7 +99,39 @@ struct sub_data { /* Pointer to preferences hash table */ static GHashTable *prefs_table = NULL; + +#if GLIB_CHECK_VERSION(2,31,0) +static GMutex prefs_table_mutex; +#else static GMutex *prefs_table_mutex = NULL; +#endif + +static void _create_mutex() { +#if GLIB_CHECK_VERSION(2,31,0) + // As it is static the mutex needs no initialisation +#else + if (!prefs_table_mutex) + prefs_table_mutex = g_mutex_new (); +#endif +} + +static void _lock_mutex() { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_lock (&prefs_table_mutex); +#else + g_return_if_fail (prefs_table_mutex); + g_mutex_lock (prefs_table_mutex); +#endif +} + +static void _unlock_mutex() { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_unlock (&prefs_table_mutex); +#else + g_return_if_fail (prefs_table_mutex); + g_mutex_unlock (prefs_table_mutex); +#endif +} /* * Functions used by this module only @@ -119,14 +151,12 @@ enum { /* Lock the prefs table. If the table is already locked the calling * thread will remain blocked until the lock is released by the other thread. */ static void lock_prefs_table() { - g_return_if_fail (prefs_table_mutex); - g_mutex_lock (prefs_table_mutex); + _lock_mutex(); } /* Unlock the prefs table again. */ static void unlock_prefs_table() { - g_return_if_fail (prefs_table_mutex); - g_mutex_unlock (prefs_table_mutex); + _unlock_mutex(); } /* Set default preferences */ @@ -873,8 +903,7 @@ static void cleanup_keys() { /* Initialize the prefs table and read configuration */ void prefs_init(int argc, char *argv[]) { - if (!prefs_table_mutex) - prefs_table_mutex = g_mutex_new (); + _create_mutex(); lock_prefs_table(); diff --git a/libgtkpod/tools.c b/libgtkpod/tools.c index 6847444..19e15e1 100644 --- a/libgtkpod/tools.c +++ b/libgtkpod/tools.c @@ -45,6 +45,8 @@ #include <unistd.h> #include <glib/gi18n-lib.h> +#define TOOLS_THREAD "Tools Thread" + /* Structure to keep all necessary information */ struct nm { Track *track; /* track to be normalised */ @@ -67,11 +69,81 @@ enum { ------------------------------------------------------------ */ #ifdef G_THREADS_ENABLED + +#if GLIB_CHECK_VERSION(2,31,0) +static GMutex mutex; +static GCond cond; +#else static GMutex *mutex = NULL; static GCond *cond = NULL; +#endif + static gboolean mutex_data = FALSE; #endif +static GThread *_create_thread(GThreadFunc func, gpointer userdata) { +#if GLIB_CHECK_VERSION(2,31,0) + return g_thread_new (TOOLS_THREAD, func, userdata); +#else + return g_thread_create (func, userdata, TRUE, NULL); +#endif +} + +static void _create_cond() { +#if GLIB_CHECK_VERSION(2,31,0) + // As it is static the cond needs no initialisation +#else + if (!cond) + cond = g_cond_new (); +#endif +} + +static void _cond_signal() { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_signal (&cond); +#else + g_cond_signal (cond); +#endif +} + +static void _cond_timed_wait(glong timeout) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_wait_until (&cond, &mutex, (gint64) timeout); +#else + GTimeVal gtime; + g_get_current_time(>ime); + g_time_val_add(>ime, timeout); + g_cond_timed_wait (cond, mutex, >ime); +#endif +} + +static void _create_mutex() { +#if GLIB_CHECK_VERSION(2,31,0) + // As it is static the mutex needs no initialisation +#else + if (!mutex) + mutex = g_mutex_new (); +#endif +} + +static void _lock_mutex() { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_lock (&mutex); +#else + g_return_if_fail (mutex); + g_mutex_lock (mutex); +#endif +} + +static void _unlock_mutex() { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_unlock (&mutex); +#else + g_return_if_fail (mutex); + g_mutex_unlock (mutex); +#endif +} + /* Run @command on @track_path. * * Command may include options, like "mp3gain -q -k %s" @@ -283,10 +355,10 @@ static gboolean nm_get_soundcheck(Track *track, GError **error) { static gpointer th_nm_get_soundcheck(gpointer data) { struct nm *nm = data; gboolean success = nm_get_soundcheck(nm->track, &(nm->error)); - g_mutex_lock(mutex); + _lock_mutex(); mutex_data = TRUE; /* signal that thread will end */ - g_cond_signal(cond); - g_mutex_unlock(mutex); + _cond_signal(); + _unlock_mutex(); return GUINT_TO_POINTER(success); } #endif @@ -342,11 +414,9 @@ void nm_tracks_list(GList *list) { #ifdef G_THREADS_ENABLED GThread *thread = NULL; - GTimeVal gtime; - if (!mutex) - mutex = g_mutex_new (); - if (!cond) - cond = g_cond_new (); + + _create_mutex(); + _create_cond(); #endif block_widgets(); @@ -380,21 +450,18 @@ void nm_tracks_list(GList *list) { #ifdef G_THREADS_ENABLED mutex_data = FALSE; - thread = g_thread_create (th_nm_get_soundcheck, nm, TRUE, NULL); + thread = _create_thread(th_nm_get_soundcheck, nm); if (thread) { - g_mutex_lock(mutex); + _lock_mutex(); do { while (widgets_blocked && gtk_events_pending()) gtk_main_iteration(); - /* wait a maximum of 10 ms */ - - g_get_current_time(>ime); - g_time_val_add(>ime, 20000); - g_cond_timed_wait(cond, mutex, >ime); + /* wait a maximum of 20 ms */ + _cond_timed_wait(20000); } while (!mutex_data); success = GPOINTER_TO_UINT(g_thread_join (thread)); - g_mutex_unlock(mutex); + _unlock_mutex(); } else { g_warning("Thread creation failed, falling back to default.\n"); diff --git a/plugins/sjcd/libjuicer/sj-metadata-getter.c b/plugins/sjcd/libjuicer/sj-metadata-getter.c index 11002fa..820248a 100644 --- a/plugins/sjcd/libjuicer/sj-metadata-getter.c +++ b/plugins/sjcd/libjuicer/sj-metadata-getter.c @@ -38,6 +38,8 @@ #include "sj-metadata-gvfs.h" #include "sj-error.h" +#define SJ_METADATA_THREAD "SJ MetaData Thread" + enum { METADATA, LAST_SIGNAL @@ -94,7 +96,7 @@ static void sj_metadata_getter_finalize (GObject *object) { SjMetadataGetterPrivate *priv = GETTER_PRIVATE (object); - + g_free (priv->url); g_free (priv->cdrom); g_free (priv->proxy_host); @@ -240,13 +242,21 @@ lookup_cd (SjMetadataGetter *mdg) return NULL; } +static GThread *_create_thread(GThreadFunc func, gpointer userdata, GError **error) { +#if GLIB_CHECK_VERSION(2,31,0) + return g_thread_new (SJ_METADATA_THREAD, func, userdata); +#else + return g_thread_create (func, userdata, TRUE, error); +#endif +} + gboolean sj_metadata_getter_list_albums (SjMetadataGetter *mdg, GError **error) { GThread *thread; g_object_ref (mdg); - thread = g_thread_create ((GThreadFunc)lookup_cd, mdg, TRUE, error); + thread = _create_thread((GThreadFunc)lookup_cd, mdg, error); if (thread == NULL) { g_set_error (error, SJ_ERROR, SJ_ERROR_INTERNAL_ERROR, diff --git a/src/main.c b/src/main.c index 2197894..8be6dfe 100644 --- a/src/main.c +++ b/src/main.c @@ -58,8 +58,14 @@ main (int argc, char *argv[]) #endif #ifdef G_THREADS_ENABLED + +#if GLIB_CHECK_VERSION(2,31,0) + /* No longer need to init threads manually anymore */ +#else /* this must be called before gtk_init () */ g_thread_init (NULL); +#endif + /* FIXME: this call causes gtkpod to freeze as soon as tracks should be displayed */ gdk_threads_init (); |