From ee2f3c09788862612219acd93cec3d8d619cc7d1 Mon Sep 17 00:00:00 2001 From: jocelyn Date: Thu, 5 Mar 2009 21:45:58 +0100 Subject: [PATCH] Replace g_thread by g_thread_pool All g_thread are replaced by a single g_thread_pool, which gives the ability to easily limit the number of running threads, and will make it possible to wait for all threads to finish correctly before exisiting viking. --- src/background.c | 28 +++++++++++++++++++--------- src/background.h | 1 + src/vikmapslayer.c | 7 +++++-- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/background.c b/src/background.c index 624d78b..b9ca150 100644 --- a/src/background.c +++ b/src/background.c @@ -25,6 +25,8 @@ #include "vikstatus.h" #include "background.h" +static GThreadPool *thread_pool = NULL; + static GtkWidget *bgwindow = NULL; static GtkWidget *bgtreeview = NULL; static GtkListStore *bgstore = NULL; @@ -55,7 +57,7 @@ static void background_thread_update () g_slist_foreach ( statusbars_to_update, (GFunc) a_background_update_status, buf ); } -void a_background_thread_progress ( gpointer callbackdata, gdouble fraction ) +int a_background_thread_progress ( gpointer callbackdata, gdouble fraction ) { gpointer *args = (gpointer *) callbackdata; a_background_testcancel ( callbackdata ); @@ -65,7 +67,7 @@ void a_background_thread_progress ( gpointer callbackdata, gdouble fraction ) args[6] = GINT_TO_POINTER(GPOINTER_TO_INT(args[6])-1); bgitemcount--; - background_thread_update(); + return background_thread_update(); } static void thread_die ( gpointer args[6] ) @@ -82,11 +84,9 @@ static void thread_die ( gpointer args[6] ) g_free ( args[5] ); /* free iter */ g_free ( args ); - - g_thread_exit ( NULL ); } -void a_background_testcancel ( gpointer callbackdata ) +int a_background_testcancel ( gpointer callbackdata ) { gpointer *args = (gpointer *) callbackdata; if ( args[0] ) @@ -94,11 +94,11 @@ void a_background_testcancel ( gpointer callbackdata ) vik_thr_free_func cleanup = args[4]; if ( cleanup ) cleanup ( args[2] ); - thread_die( args ); + return -1; } + return 0; } - -void thread_helper ( gpointer args[6] ) +void thread_helper ( gpointer args[6], gpointer user_data ) { /* unpack args */ vik_thr_func func = args[1]; @@ -141,7 +141,7 @@ void a_background_thread ( GtkWindow *parent, const gchar *message, vik_thr_func -1 ); /* run the thread in the background */ - g_thread_create( (GThreadFunc) thread_helper, args, FALSE, NULL ); + g_thread_pool_push( thread_pool, args, NULL ); } void a_background_show_window () @@ -194,6 +194,10 @@ static void bgwindow_response (GtkDialog *dialog, gint arg1 ) void a_background_init() { + /* initialize thread pool */ + gint max_threads = 10; /* limit maximum number of threads running at one time */ + thread_pool = g_thread_pool_new ( (GFunc) thread_helper, NULL, max_threads, FALSE, NULL ); + GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkWidget *scrolled_window; @@ -232,6 +236,12 @@ void a_background_init() } +void a_background_uninit() +{ + /* wait until all running threads stop */ + g_thread_pool_free ( thread_pool, TRUE, TRUE ); +} + void a_background_add_status(VikStatusbar *vs) { statusbars_to_update = g_slist_prepend(statusbars_to_update,vs); diff --git a/src/background.h b/src/background.h index 6bbb49f..09af6b1 100644 --- a/src/background.h +++ b/src/background.h @@ -36,6 +36,7 @@ void a_background_thread_progress ( gpointer callbackdata, gdouble fraction ); void a_background_testcancel ( gpointer callbackdata ); void a_background_show_window (); void a_background_init (); +void a_background_uninit (); void a_background_add_status(VikStatusbar *vs); void a_background_remove_status(VikStatusbar *vs); diff --git a/src/vikmapslayer.c b/src/vikmapslayer.c index 5668757..934da6e 100644 --- a/src/vikmapslayer.c +++ b/src/vikmapslayer.c @@ -778,7 +778,7 @@ static void weak_ref_cb(gpointer ptr, GObject * dead_vml) g_mutex_unlock(mdi->mutex); } -static void map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata ) +static int map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata ) { guint donemaps = 0; gint x, y; @@ -793,7 +793,9 @@ static void map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata ) mdi->mapcoord.scale, mdi->mapcoord.z, x, y ); donemaps++; - a_background_thread_progress ( threaddata, ((gdouble)donemaps) / mdi->mapstoget ); /* this also calls testcancel */ + int res = a_background_thread_progress ( threaddata, ((gdouble)donemaps) / mdi->mapstoget ); /* this also calls testcancel */ + if (res != 0) + return -1; if ( mdi->redownload == REDOWNLOAD_ALL) g_remove ( mdi->filename_buf ); @@ -850,6 +852,7 @@ static void map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata ) if (mdi->map_layer_alive) g_object_weak_unref(G_OBJECT(mdi->vml), weak_ref_cb, mdi); g_mutex_unlock(mdi->mutex); + return 0; } static void mdi_cancel_cleanup ( MapDownloadInfo *mdi ) -- 2.11.4.GIT