summaryrefslogtreecommitdiff
path: root/gio/gthreadedsocketservice.c
diff options
context:
space:
mode:
Diffstat (limited to 'gio/gthreadedsocketservice.c')
-rw-r--r--gio/gthreadedsocketservice.c70
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);