From 44f1b8154a57621ecd79cd7da8e905fb18b49e56 Mon Sep 17 00:00:00 2001 From: Alan Fitton Date: Wed, 13 Apr 2011 12:24:26 +0000 Subject: spawn requests from a thread pool --- src/dispatch.c | 46 +++++++++++++++++++++++++--------------------- src/dispatch.h | 8 +++++--- src/http.c | 1 - src/trg-client.c | 1 + src/trg-client.h | 1 + src/trg-main-window.c | 3 +++ src/trg-torrent-model.c | 1 - 7 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/dispatch.c b/src/dispatch.c index e102aed..70a6cc6 100644 --- a/src/dispatch.c +++ b/src/dispatch.c @@ -27,7 +27,7 @@ #include "http.h" #include "json.h" -static gpointer dispatch_async_threadfunc(gpointer ptr); +static void dispatch_async_threadfunc(gpointer task, gpointer user_data); JsonObject *dispatch(trg_client * client, JsonNode * req, int *status) { @@ -40,13 +40,13 @@ JsonObject *dispatch(trg_client * client, JsonNode * req, int *status) serialized = trg_serialize(req); json_node_free(req); #ifdef DEBUG - if (g_getenv("TRG_SHOW_OUTGOING") != NULL) + if (g_getenv("TRG_SHOW_OUTGOING")) g_printf("=>(outgoing)=> %s\n", serialized); #endif response = trg_http_perform(client, serialized); g_free(serialized); - if (status != NULL) + if (status) *status = response->status; if (response->status != CURLE_OK) { @@ -57,56 +57,60 @@ JsonObject *dispatch(trg_client * client, JsonNode * req, int *status) deserialized = trg_deserialize(response, &decode_error); http_response_free(response); - if (decode_error != NULL) { + if (decode_error) { g_printf("JSON decoding error: %s\n", decode_error->message); g_error_free(decode_error); - if (status != NULL) + if (status) *status = FAIL_JSON_DECODE; return NULL; } result = json_object_get_member(deserialized, "result"); - if (status != NULL - && (result == NULL - || g_strcmp0(json_node_get_string(result), "success") != 0)) + if (status + && (!result + || g_strcmp0(json_node_get_string(result), "success"))) *status = FAIL_RESPONSE_UNSUCCESSFUL; return deserialized; } -static gpointer dispatch_async_threadfunc(gpointer ptr) +static void dispatch_async_threadfunc(gpointer task, gpointer user_data) { - struct dispatch_async_args *args = (struct dispatch_async_args *) ptr; + trg_client *client = (trg_client*)user_data; + struct DispatchAsyncData *args = (struct DispatchAsyncData*)task; + int status; - JsonObject *result = dispatch(args->client, args->req, &status); + JsonObject *result = dispatch(client, args->req, &status); if (args->callback) args->callback(result, status, args->data); g_free(args); - return NULL; } -GThread *dispatch_async(trg_client * client, JsonNode * req, +GThreadPool *dispatch_init_pool(trg_client *client) +{ + GThreadPool *pool = g_thread_pool_new((GFunc)dispatch_async_threadfunc, client, DISPATCH_POOL_SIZE, FALSE, NULL); + return pool; +} + +gboolean dispatch_async(trg_client * client, JsonNode * req, void (*callback) (JsonObject *, int, gpointer), gpointer data) { GError *error = NULL; - GThread *thread; - struct dispatch_async_args *args = - g_new(struct dispatch_async_args, 1); + struct DispatchAsyncData *args = + g_new(struct DispatchAsyncData, 1); args->callback = callback; args->data = data; args->req = req; - args->client = client; - thread = - g_thread_create(dispatch_async_threadfunc, args, FALSE, &error); + g_thread_pool_push(client->pool, args, &error); if (error) { g_printf("thread creation error: %s\n", error->message); g_error_free(error); g_free(args); - return NULL; + return FALSE; } else { - return thread; + return TRUE; } } diff --git a/src/dispatch.h b/src/dispatch.h index cf4c908..e5a35e9 100644 --- a/src/dispatch.h +++ b/src/dispatch.h @@ -25,16 +25,18 @@ #define FAIL_JSON_DECODE -2 #define FAIL_RESPONSE_UNSUCCESSFUL -3 -struct dispatch_async_args { +#define DISPATCH_POOL_SIZE 4 + +struct DispatchAsyncData { gpointer *data; JsonNode *req; - trg_client *client; void (*callback) (JsonObject *, int, gpointer); }; JsonObject *dispatch(trg_client * client, JsonNode * req, int *status); -GThread *dispatch_async(trg_client * client, JsonNode * req, +gboolean dispatch_async(trg_client * client, JsonNode * req, void (*callback) (JsonObject *, int, gpointer), gpointer data); +GThreadPool *dispatch_init_pool(trg_client *client); #endif /* DISPATCH_H_ */ diff --git a/src/http.c b/src/http.c index 6e4e08b..793f1cd 100644 --- a/src/http.c +++ b/src/http.c @@ -88,7 +88,6 @@ static struct http_response *trg_http_perform_inner(trg_client * tc, curl_easy_setopt(handle, CURLOPT_PROXY, tc->proxy); } - if (tc->session_id) { headers = curl_slist_append(headers, tc->session_id); curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); diff --git a/src/trg-client.c b/src/trg-client.c index 14f9041..af02bc0 100644 --- a/src/trg-client.c +++ b/src/trg-client.c @@ -48,6 +48,7 @@ trg_client *trg_init_client() client->activeOnlyUpdate = gconf_client_get_bool(client->gconf, TRG_GCONF_KEY_UPDATE_ACTIVE_ONLY, NULL); + client->pool = dispatch_init_pool(client); return client; } diff --git a/src/trg-client.h b/src/trg-client.h index 480d828..4a587f9 100644 --- a/src/trg-client.h +++ b/src/trg-client.h @@ -49,6 +49,7 @@ typedef struct { char *password; char *proxy; GHashTable *torrentTable; + GThreadPool *pool; GConfClient *gconf; GMutex *updateMutex; } trg_client; diff --git a/src/trg-main-window.c b/src/trg-main-window.c index eb16d8d..bafa3e6 100644 --- a/src/trg-main-window.c +++ b/src/trg-main-window.c @@ -873,6 +873,9 @@ TRANSMISSION_MIN_SUPPORTED, version); response_unref(response); } +/* + * The callback for a torrent-get response. + */ static void on_torrent_get(JsonObject * response, int mode, int status, gpointer data) { diff --git a/src/trg-torrent-model.c b/src/trg-torrent-model.c index 2f1859b..c9a8f36 100644 --- a/src/trg-torrent-model.c +++ b/src/trg-torrent-model.c @@ -393,7 +393,6 @@ void trg_torrent_model_update(TrgTorrentModel * model, trg_client * tc, JsonObject *args, *t; GList *li; - GList *newTorrents; gint64 id; gint64 *idCopy; JsonArray *removedTorrents; -- cgit v1.2.3