diff options
Diffstat (limited to 'gio/gthreadedsocketservice.c')
-rw-r--r-- | gio/gthreadedsocketservice.c | 70 |
1 files changed, 37 insertions, 33 deletions
diff --git a/gio/gthreadedsocketservice.c b/gio/gthreadedsocketservice.c index e0c111c10..b330196e3 100644 --- a/gio/gthreadedsocketservice.c +++ b/gio/gthreadedsocketservice.c @@ -62,42 +62,45 @@ G_DEFINE_TYPE_WITH_PRIVATE (GThreadedSocketService, g_threaded_socket_service, G_TYPE_SOCKET_SERVICE) -enum +typedef enum { - PROP_0, - PROP_MAX_THREADS -}; + PROP_MAX_THREADS = 1, +} GThreadedSocketServiceProperty; G_LOCK_DEFINE_STATIC(job_count); typedef struct { - GSocketConnection *connection; - GObject *source_object; + GThreadedSocketService *service; /* (owned) */ + GSocketConnection *connection; /* (owned) */ + GObject *source_object; /* (owned) (nullable) */ } GThreadedSocketServiceData; static void -g_threaded_socket_service_func (gpointer _data, - gpointer user_data) +g_threaded_socket_service_data_free (GThreadedSocketServiceData *data) { - GThreadedSocketService *threaded = user_data; - GThreadedSocketServiceData *data = _data; + g_clear_object (&data->service); + g_clear_object (&data->connection); + g_clear_object (&data->source_object); + g_slice_free (GThreadedSocketServiceData, data); +} + +static void +g_threaded_socket_service_func (gpointer job_data, + gpointer user_data) +{ + GThreadedSocketServiceData *data = job_data; gboolean result; - g_signal_emit (threaded, g_threaded_socket_service_run_signal, + g_signal_emit (data->service, g_threaded_socket_service_run_signal, 0, data->connection, data->source_object, &result); - g_object_unref (data->connection); - if (data->source_object) - g_object_unref (data->source_object); - g_slice_free (GThreadedSocketServiceData, data); - G_LOCK (job_count); - if (threaded->priv->job_count-- == threaded->priv->max_threads) - g_socket_service_start (G_SOCKET_SERVICE (threaded)); + if (data->service->priv->job_count-- == data->service->priv->max_threads) + g_socket_service_start (G_SOCKET_SERVICE (data->service)); G_UNLOCK (job_count); - g_object_unref (threaded); + g_threaded_socket_service_data_free (data); } static gboolean @@ -107,28 +110,27 @@ g_threaded_socket_service_incoming (GSocketService *service, { GThreadedSocketService *threaded; GThreadedSocketServiceData *data; + GError *local_error = NULL; threaded = G_THREADED_SOCKET_SERVICE (service); - data = g_slice_new (GThreadedSocketServiceData); - - /* Ref the socket service for the thread */ - g_object_ref (service); - + data = g_slice_new0 (GThreadedSocketServiceData); + data->service = g_object_ref (threaded); data->connection = g_object_ref (connection); - if (source_object) - data->source_object = g_object_ref (source_object); - else - data->source_object = NULL; + data->source_object = (source_object != NULL) ? g_object_ref (source_object) : NULL; G_LOCK (job_count); if (++threaded->priv->job_count == threaded->priv->max_threads) g_socket_service_stop (service); G_UNLOCK (job_count); - g_thread_pool_push (threaded->priv->thread_pool, data, NULL); - + if (!g_thread_pool_push (threaded->priv->thread_pool, data, &local_error)) + { + g_warning ("Error handling incoming socket: %s", local_error->message); + g_threaded_socket_service_data_free (data); + } + g_clear_error (&local_error); return FALSE; } @@ -147,7 +149,7 @@ g_threaded_socket_service_constructed (GObject *object) service->priv->thread_pool = g_thread_pool_new (g_threaded_socket_service_func, - service, + NULL, service->priv->max_threads, FALSE, NULL); @@ -159,6 +161,8 @@ g_threaded_socket_service_finalize (GObject *object) { GThreadedSocketService *service = G_THREADED_SOCKET_SERVICE (object); + /* All jobs in the pool hold a reference to this #GThreadedSocketService, so + * this should only be called once the pool is empty: */ g_thread_pool_free (service->priv->thread_pool, FALSE, FALSE); G_OBJECT_CLASS (g_threaded_socket_service_parent_class) @@ -173,7 +177,7 @@ g_threaded_socket_service_get_property (GObject *object, { GThreadedSocketService *service = G_THREADED_SOCKET_SERVICE (object); - switch (prop_id) + switch ((GThreadedSocketServiceProperty) prop_id) { case PROP_MAX_THREADS: g_value_set_int (value, service->priv->max_threads); @@ -192,7 +196,7 @@ g_threaded_socket_service_set_property (GObject *object, { GThreadedSocketService *service = G_THREADED_SOCKET_SERVICE (object); - switch (prop_id) + switch ((GThreadedSocketServiceProperty) prop_id) { case PROP_MAX_THREADS: service->priv->max_threads = g_value_get_int (value); |