[gnome-builder: 37/139] libide-threading: add new threading static library
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder: 37/139] libide-threading: add new threading static library
- Date: Thu, 10 Jan 2019 04:20:26 +0000 (UTC)
commit 884baf7358e75aee5fb11316164368c10153e98d
Author: Christian Hergert <chergert redhat com>
Date: Wed Jan 9 16:20:27 2019 -0800
libide-threading: add new threading static library
The new threading static library moves subprocesses and tasks into a
space to help plugins and Builder-core to manage multi-processing
features.
src/libide/subprocess/ide-breakout-subprocess.h | 26 --
src/libide/subprocess/meson.build | 25 --
.../ide-flatpak-subprocess-private.h} | 10 +-
.../ide-flatpak-subprocess.c} | 330 ++++++++++-----------
src/libide/threading/ide-gtask-private.h | 37 +++
src/libide/threading/ide-gtask.c | 180 +++++++++++
.../ide-simple-subprocess-private.h} | 10 +-
.../ide-simple-subprocess.c | 10 +-
.../ide-subprocess-launcher.c | 52 ++--
.../ide-subprocess-launcher.h | 19 +-
.../ide-subprocess-supervisor.c | 6 +-
.../ide-subprocess-supervisor.h | 10 +-
.../{subprocess => threading}/ide-subprocess.c | 5 +-
.../{subprocess => threading}/ide-subprocess.h | 121 ++++----
src/libide/threading/ide-task.c | 45 ++-
src/libide/threading/ide-task.h | 8 +-
src/libide/threading/ide-thread-pool.c | 21 +-
src/libide/threading/ide-thread-pool.h | 9 +-
src/libide/threading/ide-thread-private.h | 1 +
src/libide/threading/libide-threading.h | 35 +++
src/libide/threading/meson.build | 80 ++++-
21 files changed, 659 insertions(+), 381 deletions(-)
---
diff --git a/src/libide/subprocess/ide-breakout-subprocess-private.h
b/src/libide/threading/ide-flatpak-subprocess-private.h
similarity index 85%
rename from src/libide/subprocess/ide-breakout-subprocess-private.h
rename to src/libide/threading/ide-flatpak-subprocess-private.h
index ee414aed3..64628c69b 100644
--- a/src/libide/subprocess/ide-breakout-subprocess-private.h
+++ b/src/libide/threading/ide-flatpak-subprocess-private.h
@@ -1,4 +1,4 @@
-/* ide-breakout-subprocess-private.h
+/* ide-flatpak-subprocess-private.h
*
* Copyright 2016-2019 Christian Hergert <chergert redhat com>
*
@@ -20,17 +20,21 @@
#pragma once
-#include "subprocess/ide-breakout-subprocess.h"
+#include "ide-subprocess.h"
G_BEGIN_DECLS
+#define IDE_TYPE_FLATPAK_SUBPROCESS (ide_flatpak_subprocess_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeFlatpakSubprocess, ide_flatpak_subprocess, IDE, FLATPAK_SUBPROCESS, GObject)
+
typedef struct
{
gint source_fd;
gint dest_fd;
} IdeBreakoutFdMapping;
-IdeSubprocess *_ide_breakout_subprocess_new (const gchar *cwd,
+IdeSubprocess *_ide_flatpak_subprocess_new (const gchar *cwd,
const gchar * const *argv,
const gchar * const *env,
GSubprocessFlags flags,
diff --git a/src/libide/subprocess/ide-breakout-subprocess.c b/src/libide/threading/ide-flatpak-subprocess.c
similarity index 82%
rename from src/libide/subprocess/ide-breakout-subprocess.c
rename to src/libide/threading/ide-flatpak-subprocess.c
index d628397fa..981dc185c 100644
--- a/src/libide/subprocess/ide-breakout-subprocess.c
+++ b/src/libide/threading/ide-flatpak-subprocess.c
@@ -14,31 +14,29 @@
* Ryan Lortie <desrt desrt ca>
* Alexander Larsson <alexl redhat com>
* Christian Hergert <chergert redhat com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*/
-#define G_LOG_DOMAIN "ide-breakout-subprocess"
+#define G_LOG_DOMAIN "ide-flatpak-subprocess"
#include "config.h"
-#include <dazzle.h>
#include <errno.h>
#include <fcntl.h>
#include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h>
#include <gio/gunixfdlist.h>
#include <glib-unix.h>
+#include <libide-core.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
-#include "ide-debug.h"
-
-#include "application/ide-application.h"
-#include "subprocess/ide-breakout-subprocess.h"
-#include "subprocess/ide-breakout-subprocess-private.h"
-#include "util/ide-glib.h"
+#include "ide-flatpak-subprocess-private.h"
+#include "ide-gtask-private.h"
#ifndef FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV
# define FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV (1 << 0)
@@ -53,9 +51,7 @@
* for all subprocesses so that we can have exit-on-close => false).
*/
-DZL_DEFINE_COUNTER (instances, "Subprocess", "HostCommand Instances", "Number of IdeBreakoutSubprocess
instances")
-
-struct _IdeBreakoutSubprocess
+struct _IdeFlatpakSubprocess
{
GObject parent_instance;
@@ -172,12 +168,12 @@ enum {
N_PROPS
};
-static void ide_breakout_subprocess_sync_complete (IdeBreakoutSubprocess *self,
+static void ide_flatpak_subprocess_sync_complete (IdeFlatpakSubprocess *self,
GAsyncResult **result);
-static void ide_breakout_subprocess_sync_done (GObject *object,
+static void ide_flatpak_subprocess_sync_done (GObject *object,
GAsyncResult *result,
gpointer user_data);
-static CommunicateState *ide_breakout_subprocess_communicate_internal (IdeBreakoutSubprocess *subprocess,
+static CommunicateState *ide_flatpak_subprocess_communicate_internal (IdeFlatpakSubprocess *subprocess,
gboolean add_nul,
GBytes *stdin_buf,
GCancellable *cancellable,
@@ -187,54 +183,54 @@ static CommunicateState *ide_breakout_subprocess_communicate_internal (IdeBreako
static GParamSpec *properties [N_PROPS];
static const gchar *
-ide_breakout_subprocess_get_identifier (IdeSubprocess *subprocess)
+ide_flatpak_subprocess_get_identifier (IdeSubprocess *subprocess)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
return self->identifier;
}
static GInputStream *
-ide_breakout_subprocess_get_stdout_pipe (IdeSubprocess *subprocess)
+ide_flatpak_subprocess_get_stdout_pipe (IdeSubprocess *subprocess)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
return self->stdout_pipe;
}
static GInputStream *
-ide_breakout_subprocess_get_stderr_pipe (IdeSubprocess *subprocess)
+ide_flatpak_subprocess_get_stderr_pipe (IdeSubprocess *subprocess)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
return self->stderr_pipe;
}
static GOutputStream *
-ide_breakout_subprocess_get_stdin_pipe (IdeSubprocess *subprocess)
+ide_flatpak_subprocess_get_stdin_pipe (IdeSubprocess *subprocess)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
return self->stdin_pipe;
}
static void
-ide_breakout_subprocess_wait_cb (GObject *object,
+ide_flatpak_subprocess_wait_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)object;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)object;
gboolean *completed = user_data;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (completed != NULL);
ide_subprocess_wait_finish (IDE_SUBPROCESS (self), result, NULL);
@@ -246,13 +242,13 @@ ide_breakout_subprocess_wait_cb (GObject *object,
}
static gboolean
-ide_breakout_subprocess_wait (IdeSubprocess *subprocess,
+ide_flatpak_subprocess_wait (IdeSubprocess *subprocess,
GCancellable *cancellable,
GError **error)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_object_ref (self);
@@ -277,7 +273,7 @@ ide_breakout_subprocess_wait (IdeSubprocess *subprocess,
ide_subprocess_wait_async (IDE_SUBPROCESS (self),
cancellable,
- ide_breakout_subprocess_wait_cb,
+ ide_flatpak_subprocess_wait_cb,
&completed);
while (!completed)
@@ -295,20 +291,20 @@ cleanup:
}
static void
-ide_breakout_subprocess_wait_async (IdeSubprocess *subprocess,
+ide_flatpak_subprocess_wait_async (IdeSubprocess *subprocess,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
g_autoptr(GTask) task = NULL;
g_autoptr(GMutexLocker) locker = NULL;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
task = g_task_new (self, cancellable, callback, user_data);
- g_task_set_source_tag (task, ide_breakout_subprocess_wait_async);
+ g_task_set_source_tag (task, ide_flatpak_subprocess_wait_async);
g_task_set_priority (task, G_PRIORITY_DEFAULT_IDLE);
locker = g_mutex_locker_new (&self->waiter_mutex);
@@ -323,28 +319,28 @@ ide_breakout_subprocess_wait_async (IdeSubprocess *subprocess,
}
static gboolean
-ide_breakout_subprocess_wait_finish (IdeSubprocess *subprocess,
+ide_flatpak_subprocess_wait_finish (IdeSubprocess *subprocess,
GAsyncResult *result,
GError **error)
{
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (subprocess));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (subprocess));
g_assert (G_IS_TASK (result));
return g_task_propagate_boolean (G_TASK (result), error);
}
static void
-ide_breakout_subprocess_communicate_utf8_async (IdeSubprocess *subprocess,
+ide_flatpak_subprocess_communicate_utf8_async (IdeSubprocess *subprocess,
const char *stdin_buf,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
g_autoptr(GBytes) stdin_bytes = NULL;
size_t stdin_buf_len = 0;
- g_return_if_fail (IDE_IS_BREAKOUT_SUBPROCESS (subprocess));
+ g_return_if_fail (IDE_IS_FLATPAK_SUBPROCESS (subprocess));
g_return_if_fail (stdin_buf == NULL || (self->flags & G_SUBPROCESS_FLAGS_STDIN_PIPE));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
@@ -352,7 +348,7 @@ ide_breakout_subprocess_communicate_utf8_async (IdeSubprocess *subprocess,
stdin_buf_len = strlen (stdin_buf);
stdin_bytes = g_bytes_new (stdin_buf, stdin_buf_len);
- ide_breakout_subprocess_communicate_internal (self, TRUE, stdin_bytes, cancellable, callback, user_data);
+ ide_flatpak_subprocess_communicate_internal (self, TRUE, stdin_bytes, cancellable, callback, user_data);
}
static gboolean
@@ -398,7 +394,7 @@ communicate_result_validate_utf8 (const char *stream_name,
}
static gboolean
-ide_breakout_subprocess_communicate_utf8_finish (IdeSubprocess *subprocess,
+ide_flatpak_subprocess_communicate_utf8_finish (IdeSubprocess *subprocess,
GAsyncResult *result,
char **stdout_buf,
char **stderr_buf,
@@ -409,7 +405,7 @@ ide_breakout_subprocess_communicate_utf8_finish (IdeSubprocess *subprocess,
IDE_ENTRY;
- g_return_val_if_fail (IDE_IS_BREAKOUT_SUBPROCESS (subprocess), FALSE);
+ g_return_val_if_fail (IDE_IS_FLATPAK_SUBPROCESS (subprocess), FALSE);
g_return_val_if_fail (g_task_is_valid (result, subprocess), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -434,14 +430,14 @@ ide_breakout_subprocess_communicate_utf8_finish (IdeSubprocess *subprocess,
}
static gboolean
-ide_breakout_subprocess_communicate_utf8 (IdeSubprocess *subprocess,
+ide_flatpak_subprocess_communicate_utf8 (IdeSubprocess *subprocess,
const char *stdin_buf,
GCancellable *cancellable,
char **stdout_buf,
char **stderr_buf,
GError **error)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
g_autoptr(GAsyncResult) result = NULL;
g_autoptr(GBytes) stdin_bytes = NULL;
size_t stdin_buf_len = 0;
@@ -449,7 +445,7 @@ ide_breakout_subprocess_communicate_utf8 (IdeSubprocess *subprocess,
IDE_ENTRY;
- g_return_val_if_fail (IDE_IS_BREAKOUT_SUBPROCESS (subprocess), FALSE);
+ g_return_val_if_fail (IDE_IS_FLATPAK_SUBPROCESS (subprocess), FALSE);
g_return_val_if_fail (stdin_buf == NULL || (self->flags & G_SUBPROCESS_FLAGS_STDIN_PIPE), FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -458,44 +454,44 @@ ide_breakout_subprocess_communicate_utf8 (IdeSubprocess *subprocess,
stdin_buf_len = strlen (stdin_buf);
stdin_bytes = g_bytes_new (stdin_buf, stdin_buf_len);
- ide_breakout_subprocess_communicate_internal (self,
+ ide_flatpak_subprocess_communicate_internal (self,
TRUE,
stdin_bytes,
cancellable,
- ide_breakout_subprocess_sync_done,
+ ide_flatpak_subprocess_sync_done,
&result);
- ide_breakout_subprocess_sync_complete (self, &result);
+ ide_flatpak_subprocess_sync_complete (self, &result);
success = ide_subprocess_communicate_utf8_finish (subprocess, result, stdout_buf, stderr_buf, error);
IDE_RETURN (success);
}
static gboolean
-ide_breakout_subprocess_get_successful (IdeSubprocess *subprocess)
+ide_flatpak_subprocess_get_successful (IdeSubprocess *subprocess)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
return WIFEXITED (self->status) && WEXITSTATUS (self->status) == 0;
}
static gboolean
-ide_breakout_subprocess_get_if_exited (IdeSubprocess *subprocess)
+ide_flatpak_subprocess_get_if_exited (IdeSubprocess *subprocess)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
return WIFEXITED (self->status);
}
static gint
-ide_breakout_subprocess_get_exit_status (IdeSubprocess *subprocess)
+ide_flatpak_subprocess_get_exit_status (IdeSubprocess *subprocess)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (self->client_has_exited);
if (!WIFEXITED (self->status))
@@ -505,47 +501,47 @@ ide_breakout_subprocess_get_exit_status (IdeSubprocess *subprocess)
}
static gboolean
-ide_breakout_subprocess_get_if_signaled (IdeSubprocess *subprocess)
+ide_flatpak_subprocess_get_if_signaled (IdeSubprocess *subprocess)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (self->client_has_exited == TRUE);
return WIFSIGNALED (self->status);
}
static gint
-ide_breakout_subprocess_get_term_sig (IdeSubprocess *subprocess)
+ide_flatpak_subprocess_get_term_sig (IdeSubprocess *subprocess)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (self->client_has_exited == TRUE);
return WTERMSIG (self->status);
}
static gint
-ide_breakout_subprocess_get_status (IdeSubprocess *subprocess)
+ide_flatpak_subprocess_get_status (IdeSubprocess *subprocess)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (self->client_has_exited == TRUE);
return self->status;
}
static void
-ide_breakout_subprocess_send_signal (IdeSubprocess *subprocess,
+ide_flatpak_subprocess_send_signal (IdeSubprocess *subprocess,
gint signal_num)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
IDE_ENTRY;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
/* Signal delivery is not guaranteed, so we can drop this on the floor. */
if (self->client_has_exited || self->connection == NULL)
@@ -567,15 +563,15 @@ ide_breakout_subprocess_send_signal (IdeSubprocess *subprocess,
}
static void
-ide_breakout_subprocess_force_exit (IdeSubprocess *subprocess)
+ide_flatpak_subprocess_force_exit (IdeSubprocess *subprocess)
{
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (subprocess));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (subprocess));
- ide_breakout_subprocess_send_signal (subprocess, SIGKILL);
+ ide_flatpak_subprocess_send_signal (subprocess, SIGKILL);
}
static void
-ide_breakout_subprocess_sync_complete (IdeBreakoutSubprocess *self,
+ide_flatpak_subprocess_sync_complete (IdeFlatpakSubprocess *self,
GAsyncResult **result)
{
g_autoptr(GMainContext) free_me = NULL;
@@ -583,7 +579,7 @@ ide_breakout_subprocess_sync_complete (IdeBreakoutSubprocess *self,
IDE_ENTRY;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (result != NULL);
g_assert (*result == NULL || G_IS_ASYNC_RESULT (*result));
@@ -606,16 +602,16 @@ ide_breakout_subprocess_sync_complete (IdeBreakoutSubprocess *self,
}
static void
-ide_breakout_subprocess_sync_done (GObject *object,
+ide_flatpak_subprocess_sync_done (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)object;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)object;
GAsyncResult **ret = user_data;
IDE_ENTRY;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (ret != NULL);
g_assert (*ret == NULL);
g_assert (G_IS_ASYNC_RESULT (result));
@@ -671,7 +667,7 @@ ide_subprocess_communicate_made_progress (GObject *source_object,
gpointer user_data)
{
CommunicateState *state;
- IdeBreakoutSubprocess *subprocess;
+ IdeFlatpakSubprocess *subprocess;
g_autoptr(GError) error = NULL;
g_autoptr(GTask) task = user_data;
gpointer source;
@@ -739,7 +735,7 @@ ide_subprocess_communicate_made_progress (GObject *source_object,
}
static CommunicateState *
-ide_breakout_subprocess_communicate_internal (IdeBreakoutSubprocess *subprocess,
+ide_flatpak_subprocess_communicate_internal (IdeFlatpakSubprocess *subprocess,
gboolean add_nul,
GBytes *stdin_buf,
GCancellable *cancellable,
@@ -751,11 +747,11 @@ ide_breakout_subprocess_communicate_internal (IdeBreakoutSubprocess *subprocess,
IDE_ENTRY;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (subprocess));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (subprocess));
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
task = g_task_new (subprocess, cancellable, callback, user_data);
- g_task_set_source_tag (task, ide_breakout_subprocess_communicate_internal);
+ g_task_set_source_tag (task, ide_flatpak_subprocess_communicate_internal);
g_task_set_priority (task, G_PRIORITY_DEFAULT_IDLE);
state = g_slice_new0 (CommunicateState);
@@ -816,22 +812,22 @@ ide_breakout_subprocess_communicate_internal (IdeBreakoutSubprocess *subprocess,
}
static void
-ide_breakout_subprocess_communicate_async (IdeSubprocess *subprocess,
+ide_flatpak_subprocess_communicate_async (IdeSubprocess *subprocess,
GBytes *stdin_buf,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
- ide_breakout_subprocess_communicate_internal (self, FALSE, stdin_buf, cancellable, callback, user_data);
+ ide_flatpak_subprocess_communicate_internal (self, FALSE, stdin_buf, cancellable, callback, user_data);
}
static gboolean
-ide_breakout_subprocess_communicate_finish (IdeSubprocess *subprocess,
+ide_flatpak_subprocess_communicate_finish (IdeSubprocess *subprocess,
GAsyncResult *result,
GBytes **stdout_buf,
GBytes **stderr_buf,
@@ -843,7 +839,7 @@ ide_breakout_subprocess_communicate_finish (IdeSubprocess *subprocess,
IDE_ENTRY;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (subprocess));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (subprocess));
g_assert (G_IS_TASK (task));
g_object_ref (task);
@@ -873,31 +869,31 @@ ide_breakout_subprocess_communicate_finish (IdeSubprocess *subprocess,
}
static gboolean
-ide_breakout_subprocess_communicate (IdeSubprocess *subprocess,
+ide_flatpak_subprocess_communicate (IdeSubprocess *subprocess,
GBytes *stdin_buf,
GCancellable *cancellable,
GBytes **stdout_buf,
GBytes **stderr_buf,
GError **error)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)subprocess;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
g_autoptr(GAsyncResult) result = NULL;
gboolean ret;
IDE_ENTRY;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
- ide_breakout_subprocess_communicate_internal (self,
+ ide_flatpak_subprocess_communicate_internal (self,
FALSE,
stdin_buf,
cancellable,
- ide_breakout_subprocess_sync_done,
+ ide_flatpak_subprocess_sync_done,
&result);
- ide_breakout_subprocess_sync_complete (self, &result);
+ ide_flatpak_subprocess_sync_complete (self, &result);
- ret = ide_breakout_subprocess_communicate_finish (subprocess, result, stdout_buf, stderr_buf, error);
+ ret = ide_flatpak_subprocess_communicate_finish (subprocess, result, stdout_buf, stderr_buf, error);
IDE_RETURN (ret);
}
@@ -905,37 +901,37 @@ ide_breakout_subprocess_communicate (IdeSubprocess *subprocess,
static void
subprocess_iface_init (IdeSubprocessInterface *iface)
{
- iface->get_identifier = ide_breakout_subprocess_get_identifier;
- iface->get_stdout_pipe = ide_breakout_subprocess_get_stdout_pipe;
- iface->get_stderr_pipe = ide_breakout_subprocess_get_stderr_pipe;
- iface->get_stdin_pipe = ide_breakout_subprocess_get_stdin_pipe;
- iface->wait = ide_breakout_subprocess_wait;
- iface->wait_async = ide_breakout_subprocess_wait_async;
- iface->wait_finish = ide_breakout_subprocess_wait_finish;
- iface->get_successful = ide_breakout_subprocess_get_successful;
- iface->get_if_exited = ide_breakout_subprocess_get_if_exited;
- iface->get_exit_status = ide_breakout_subprocess_get_exit_status;
- iface->get_if_signaled = ide_breakout_subprocess_get_if_signaled;
- iface->get_term_sig = ide_breakout_subprocess_get_term_sig;
- iface->get_status = ide_breakout_subprocess_get_status;
- iface->send_signal = ide_breakout_subprocess_send_signal;
- iface->force_exit = ide_breakout_subprocess_force_exit;
- iface->communicate = ide_breakout_subprocess_communicate;
- iface->communicate_utf8 = ide_breakout_subprocess_communicate_utf8;
- iface->communicate_async = ide_breakout_subprocess_communicate_async;
- iface->communicate_finish = ide_breakout_subprocess_communicate_finish;
- iface->communicate_utf8_async = ide_breakout_subprocess_communicate_utf8_async;
- iface->communicate_utf8_finish = ide_breakout_subprocess_communicate_utf8_finish;
+ iface->get_identifier = ide_flatpak_subprocess_get_identifier;
+ iface->get_stdout_pipe = ide_flatpak_subprocess_get_stdout_pipe;
+ iface->get_stderr_pipe = ide_flatpak_subprocess_get_stderr_pipe;
+ iface->get_stdin_pipe = ide_flatpak_subprocess_get_stdin_pipe;
+ iface->wait = ide_flatpak_subprocess_wait;
+ iface->wait_async = ide_flatpak_subprocess_wait_async;
+ iface->wait_finish = ide_flatpak_subprocess_wait_finish;
+ iface->get_successful = ide_flatpak_subprocess_get_successful;
+ iface->get_if_exited = ide_flatpak_subprocess_get_if_exited;
+ iface->get_exit_status = ide_flatpak_subprocess_get_exit_status;
+ iface->get_if_signaled = ide_flatpak_subprocess_get_if_signaled;
+ iface->get_term_sig = ide_flatpak_subprocess_get_term_sig;
+ iface->get_status = ide_flatpak_subprocess_get_status;
+ iface->send_signal = ide_flatpak_subprocess_send_signal;
+ iface->force_exit = ide_flatpak_subprocess_force_exit;
+ iface->communicate = ide_flatpak_subprocess_communicate;
+ iface->communicate_utf8 = ide_flatpak_subprocess_communicate_utf8;
+ iface->communicate_async = ide_flatpak_subprocess_communicate_async;
+ iface->communicate_finish = ide_flatpak_subprocess_communicate_finish;
+ iface->communicate_utf8_async = ide_flatpak_subprocess_communicate_utf8_async;
+ iface->communicate_utf8_finish = ide_flatpak_subprocess_communicate_utf8_finish;
}
static gboolean
sigterm_handler (gpointer user_data)
{
- IdeBreakoutSubprocess *self = user_data;
+ IdeFlatpakSubprocess *self = user_data;
IDE_ENTRY;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_dbus_connection_call_sync (self->connection,
"org.freedesktop.Flatpak",
@@ -955,11 +951,11 @@ sigterm_handler (gpointer user_data)
static gboolean
sigint_handler (gpointer user_data)
{
- IdeBreakoutSubprocess *self = user_data;
+ IdeFlatpakSubprocess *self = user_data;
IDE_ENTRY;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_dbus_connection_call_sync (self->connection,
"org.freedesktop.Flatpak",
@@ -1031,14 +1027,14 @@ maybe_create_output_stream (GOutputStream **ret,
}
static void
-ide_breakout_subprocess_complete_command_locked (IdeBreakoutSubprocess *self,
+ide_flatpak_subprocess_complete_command_locked (IdeFlatpakSubprocess *self,
gint exit_status)
{
GList *waiting;
IDE_ENTRY;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (G_IS_DBUS_CONNECTION (self->connection));
self->client_has_exited = TRUE;
@@ -1052,8 +1048,8 @@ ide_breakout_subprocess_complete_command_locked (IdeBreakoutSubprocess *self,
g_clear_pointer (&self->identifier, g_free);
/* Remove our sources used for signal propagation */
- dzl_clear_source (&self->sigint_id);
- dzl_clear_source (&self->sigterm_id);
+ g_clear_handle_id (&self->sigint_id, g_source_remove);
+ g_clear_handle_id (&self->sigterm_id, g_source_remove);
/* Complete async workers */
waiting = g_steal_pointer (&self->waiting);
@@ -1090,8 +1086,8 @@ host_command_exited_cb (GDBusConnection *connection,
GVariant *parameters,
gpointer user_data)
{
- g_autoptr(IdeBreakoutSubprocess) finalize_protect = NULL;
- IdeBreakoutSubprocess *self = user_data;
+ g_autoptr(IdeFlatpakSubprocess) finalize_protect = NULL;
+ IdeFlatpakSubprocess *self = user_data;
g_autoptr(GMutexLocker) locker = NULL;
guint32 client_pid = 0;
guint32 exit_status = 0;
@@ -1099,7 +1095,7 @@ host_command_exited_cb (GDBusConnection *connection,
IDE_ENTRY;
g_assert (G_IS_DBUS_CONNECTION (connection));
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
finalize_protect = g_object_ref (self);
@@ -1124,19 +1120,19 @@ host_command_exited_cb (GDBusConnection *connection,
self->exited_subscription = 0;
}
- ide_breakout_subprocess_complete_command_locked (self, exit_status);
+ ide_flatpak_subprocess_complete_command_locked (self, exit_status);
IDE_EXIT;
}
static void
-ide_breakout_subprocess_cancelled (IdeBreakoutSubprocess *self,
+ide_flatpak_subprocess_cancelled (IdeFlatpakSubprocess *self,
GCancellable *cancellable)
{
IDE_ENTRY;
g_assert (G_IS_CANCELLABLE (cancellable));
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
ide_subprocess_force_exit (IDE_SUBPROCESS (self));
@@ -1156,7 +1152,7 @@ maybe_close (gint *fd)
}
static void
-ide_breakout_subprocess_connection_closed (IdeBreakoutSubprocess *self,
+ide_flatpak_subprocess_connection_closed (IdeFlatpakSubprocess *self,
gboolean remote_peer_vanished,
const GError *error,
GDBusConnection *connection)
@@ -1165,7 +1161,7 @@ ide_breakout_subprocess_connection_closed (IdeBreakoutSubprocess *self,
IDE_ENTRY;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (G_IS_DBUS_CONNECTION (connection));
locker = g_mutex_locker_new (&self->waiter_mutex);
@@ -1173,17 +1169,17 @@ ide_breakout_subprocess_connection_closed (IdeBreakoutSubprocess *self,
IDE_TRACE_MSG ("Synthesizing failure for client pid %u", (guint)self->client_pid);
self->exited_subscription = 0;
- ide_breakout_subprocess_complete_command_locked (self, -1);
+ ide_flatpak_subprocess_complete_command_locked (self, -1);
IDE_EXIT;
}
static gboolean
-ide_breakout_subprocess_initable_init (GInitable *initable,
+ide_flatpak_subprocess_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)initable;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)initable;
g_autoptr(GVariantBuilder) fd_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{uh}"));
g_autoptr(GVariantBuilder) env_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{ss}"));
g_autoptr(GUnixFDList) fd_list = g_unix_fd_list_new ();
@@ -1200,7 +1196,7 @@ ide_breakout_subprocess_initable_init (GInitable *initable,
IDE_ENTRY;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
/*
@@ -1459,7 +1455,7 @@ ide_breakout_subprocess_initable_init (GInitable *initable,
self->connection_closed_handler =
g_signal_connect_object (self->connection,
"closed",
- G_CALLBACK (ide_breakout_subprocess_connection_closed),
+ G_CALLBACK (ide_flatpak_subprocess_connection_closed),
self,
G_CONNECT_SWAPPED);
@@ -1512,11 +1508,11 @@ ide_breakout_subprocess_initable_init (GInitable *initable,
{
g_signal_connect_object (cancellable,
"cancelled",
- G_CALLBACK (ide_breakout_subprocess_cancelled),
+ G_CALLBACK (ide_flatpak_subprocess_cancelled),
self,
G_CONNECT_SWAPPED);
if (g_cancellable_is_cancelled (cancellable) && !self->client_has_exited)
- ide_breakout_subprocess_force_exit (IDE_SUBPROCESS (self));
+ ide_flatpak_subprocess_force_exit (IDE_SUBPROCESS (self));
}
ret = TRUE;
@@ -1541,19 +1537,19 @@ cleanup_fds:
static void
initiable_iface_init (GInitableIface *iface)
{
- iface->init = ide_breakout_subprocess_initable_init;
+ iface->init = ide_flatpak_subprocess_initable_init;
}
-G_DEFINE_TYPE_EXTENDED (IdeBreakoutSubprocess, ide_breakout_subprocess, G_TYPE_OBJECT, 0,
+G_DEFINE_TYPE_EXTENDED (IdeFlatpakSubprocess, ide_flatpak_subprocess, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initiable_iface_init)
G_IMPLEMENT_INTERFACE (IDE_TYPE_SUBPROCESS, subprocess_iface_init))
static void
-ide_breakout_subprocess_dispose (GObject *object)
+ide_flatpak_subprocess_dispose (GObject *object)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)object;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)object;
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (self));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
if (self->exited_subscription != 0)
{
@@ -1569,16 +1565,16 @@ ide_breakout_subprocess_dispose (GObject *object)
if (self->waiting != NULL)
g_warning ("improper disposal while async operations are active!");
- dzl_clear_source (&self->sigint_id);
- dzl_clear_source (&self->sigterm_id);
+ g_clear_handle_id (&self->sigint_id, g_source_remove);
+ g_clear_handle_id (&self->sigterm_id, g_source_remove);
- G_OBJECT_CLASS (ide_breakout_subprocess_parent_class)->dispose (object);
+ G_OBJECT_CLASS (ide_flatpak_subprocess_parent_class)->dispose (object);
}
static void
-ide_breakout_subprocess_finalize (GObject *object)
+ide_flatpak_subprocess_finalize (GObject *object)
{
- IdeBreakoutSubprocess *self = (IdeBreakoutSubprocess *)object;
+ IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)object;
IDE_ENTRY;
@@ -1614,20 +1610,18 @@ ide_breakout_subprocess_finalize (GObject *object)
close (self->fd_mapping[i].source_fd);
g_clear_pointer (&self->fd_mapping, g_free);
- G_OBJECT_CLASS (ide_breakout_subprocess_parent_class)->finalize (object);
-
- DZL_COUNTER_DEC (instances);
+ G_OBJECT_CLASS (ide_flatpak_subprocess_parent_class)->finalize (object);
IDE_EXIT;
}
static void
-ide_breakout_subprocess_get_property (GObject *object,
+ide_flatpak_subprocess_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
- IdeBreakoutSubprocess *self = IDE_BREAKOUT_SUBPROCESS (object);
+ IdeFlatpakSubprocess *self = IDE_FLATPAK_SUBPROCESS (object);
switch (prop_id)
{
@@ -1653,12 +1647,12 @@ ide_breakout_subprocess_get_property (GObject *object,
}
static void
-ide_breakout_subprocess_set_property (GObject *object,
+ide_flatpak_subprocess_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
- IdeBreakoutSubprocess *self = IDE_BREAKOUT_SUBPROCESS (object);
+ IdeFlatpakSubprocess *self = IDE_FLATPAK_SUBPROCESS (object);
switch (prop_id)
{
@@ -1684,14 +1678,14 @@ ide_breakout_subprocess_set_property (GObject *object,
}
static void
-ide_breakout_subprocess_class_init (IdeBreakoutSubprocessClass *klass)
+ide_flatpak_subprocess_class_init (IdeFlatpakSubprocessClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = ide_breakout_subprocess_dispose;
- object_class->finalize = ide_breakout_subprocess_finalize;
- object_class->get_property = ide_breakout_subprocess_get_property;
- object_class->set_property = ide_breakout_subprocess_set_property;
+ object_class->dispose = ide_flatpak_subprocess_dispose;
+ object_class->finalize = ide_flatpak_subprocess_finalize;
+ object_class->get_property = ide_flatpak_subprocess_get_property;
+ object_class->set_property = ide_flatpak_subprocess_set_property;
properties [PROP_CWD] =
g_param_spec_string ("cwd",
@@ -1726,12 +1720,10 @@ ide_breakout_subprocess_class_init (IdeBreakoutSubprocessClass *klass)
}
static void
-ide_breakout_subprocess_init (IdeBreakoutSubprocess *self)
+ide_flatpak_subprocess_init (IdeFlatpakSubprocess *self)
{
IDE_ENTRY;
- DZL_COUNTER_INC (instances);
-
self->stdin_fd = -1;
self->stdout_fd = -1;
self->stderr_fd = -1;
@@ -1743,7 +1735,7 @@ ide_breakout_subprocess_init (IdeBreakoutSubprocess *self)
}
IdeSubprocess *
-_ide_breakout_subprocess_new (const gchar *cwd,
+_ide_flatpak_subprocess_new (const gchar *cwd,
const gchar * const *argv,
const gchar * const *env,
GSubprocessFlags flags,
@@ -1756,12 +1748,12 @@ _ide_breakout_subprocess_new (const gchar *cwd,
GCancellable *cancellable,
GError **error)
{
- g_autoptr(IdeBreakoutSubprocess) ret = NULL;
+ g_autoptr(IdeFlatpakSubprocess) ret = NULL;
g_return_val_if_fail (argv != NULL, NULL);
g_return_val_if_fail (argv[0] != NULL, NULL);
- ret = g_object_new (IDE_TYPE_BREAKOUT_SUBPROCESS,
+ ret = g_object_new (IDE_TYPE_FLATPAK_SUBPROCESS,
"cwd", cwd,
"argv", argv,
"env", env,
diff --git a/src/libide/threading/ide-gtask-private.h b/src/libide/threading/ide-gtask-private.h
new file mode 100644
index 000000000..006e58759
--- /dev/null
+++ b/src/libide/threading/ide-gtask-private.h
@@ -0,0 +1,37 @@
+/* ide-gtask-private.h
+ *
+ * Copyright 2018-2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+void ide_g_task_return_boolean_from_main (GTask *task,
+ gboolean value);
+void ide_g_task_return_int_from_main (GTask *task,
+ gint value);
+void ide_g_task_return_pointer_from_main (GTask *task,
+ gpointer value,
+ GDestroyNotify notify);
+void ide_g_task_return_error_from_main (GTask *task,
+ GError *error);
+
+G_END_DECLS
diff --git a/src/libide/threading/ide-gtask.c b/src/libide/threading/ide-gtask.c
new file mode 100644
index 000000000..4373ab0fa
--- /dev/null
+++ b/src/libide/threading/ide-gtask.c
@@ -0,0 +1,180 @@
+/* ide-gtask.c
+ *
+ * Copyright 2016-2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-gtask"
+
+#include "config.h"
+
+#include "ide-gtask-private.h"
+
+typedef struct
+{
+ GType type;
+ GTask *task;
+ union {
+ gboolean v_bool;
+ gint v_int;
+ GError *v_error;
+ struct {
+ gpointer pointer;
+ GDestroyNotify destroy;
+ } v_ptr;
+ } u;
+} TaskState;
+
+static gboolean
+do_return (gpointer user_data)
+{
+ TaskState *state = user_data;
+
+ switch (state->type)
+ {
+ case G_TYPE_INT:
+ g_task_return_int (state->task, state->u.v_int);
+ break;
+
+ case G_TYPE_BOOLEAN:
+ g_task_return_boolean (state->task, state->u.v_bool);
+ break;
+
+ case G_TYPE_POINTER:
+ g_task_return_pointer (state->task, state->u.v_ptr.pointer, state->u.v_ptr.destroy);
+ state->u.v_ptr.pointer = NULL;
+ state->u.v_ptr.destroy = NULL;
+ break;
+
+ default:
+ if (state->type == G_TYPE_ERROR)
+ {
+ g_task_return_error (state->task, g_steal_pointer (&state->u.v_error));
+ break;
+ }
+
+ g_assert_not_reached ();
+ }
+
+ g_clear_object (&state->task);
+ g_slice_free (TaskState, state);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+task_state_attach (TaskState *state)
+{
+ GMainContext *main_context;
+ GSource *source;
+
+ g_assert (state != NULL);
+ g_assert (G_IS_TASK (state->task));
+
+ main_context = g_task_get_context (state->task);
+
+ source = g_timeout_source_new (0);
+ g_source_set_callback (source, do_return, state, NULL);
+ g_source_set_name (source, "[ide] ide_g_task_return_from_main");
+ g_source_attach (source, main_context);
+ g_source_unref (source);
+}
+
+/**
+ * ide_g_task_return_boolean_from_main:
+ *
+ * This is just like g_task_return_boolean() except that it enforces
+ * that the current stack return to the main context before dispatching
+ * the callback.
+ *
+ * Since: 3.32
+ */
+void
+ide_g_task_return_boolean_from_main (GTask *task,
+ gboolean value)
+{
+ TaskState *state;
+
+ g_return_if_fail (G_IS_TASK (task));
+
+ state = g_slice_new0 (TaskState);
+ state->type = G_TYPE_BOOLEAN;
+ state->task = g_object_ref (task);
+ state->u.v_bool = !!value;
+
+ task_state_attach (state);
+}
+
+void
+ide_g_task_return_int_from_main (GTask *task,
+ gint value)
+{
+ TaskState *state;
+
+ g_return_if_fail (G_IS_TASK (task));
+
+ state = g_slice_new0 (TaskState);
+ state->type = G_TYPE_INT;
+ state->task = g_object_ref (task);
+ state->u.v_int = value;
+
+ task_state_attach (state);
+}
+
+void
+ide_g_task_return_pointer_from_main (GTask *task,
+ gpointer value,
+ GDestroyNotify notify)
+{
+ TaskState *state;
+
+ g_return_if_fail (G_IS_TASK (task));
+
+ state = g_slice_new0 (TaskState);
+ state->type = G_TYPE_POINTER;
+ state->task = g_object_ref (task);
+ state->u.v_ptr.pointer = value;
+ state->u.v_ptr.destroy = notify;
+
+ task_state_attach (state);
+}
+
+/**
+ * ide_g_task_return_error_from_main:
+ * @task: a #GTask
+ * @error: (transfer full): a #GError.
+ *
+ * Like g_task_return_error() but ensures we return to the main loop before
+ * dispatching the result.
+ *
+ * Since: 3.32
+ */
+void
+ide_g_task_return_error_from_main (GTask *task,
+ GError *error)
+{
+ TaskState *state;
+
+ g_return_if_fail (G_IS_TASK (task));
+
+ state = g_slice_new0 (TaskState);
+ state->type = G_TYPE_ERROR;
+ state->task = g_object_ref (task);
+ state->u.v_error = error;
+
+ task_state_attach (state);
+}
diff --git a/src/libide/subprocess/ide-simple-subprocess.h
b/src/libide/threading/ide-simple-subprocess-private.h
similarity index 87%
rename from src/libide/subprocess/ide-simple-subprocess.h
rename to src/libide/threading/ide-simple-subprocess-private.h
index d53b3040b..e1624830c 100644
--- a/src/libide/subprocess/ide-simple-subprocess.h
+++ b/src/libide/threading/ide-simple-subprocess-private.h
@@ -1,4 +1,4 @@
-/* ide-simple-subprocess.h
+/* ide-simple-subprocess-private.h
*
* Copyright 2016-2019 Christian Hergert <chergert redhat com>
*
@@ -20,7 +20,7 @@
#pragma once
-#include "subprocess/ide-subprocess.h"
+#include "ide-subprocess.h"
G_BEGIN_DECLS
@@ -28,6 +28,12 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (IdeSimpleSubprocess, ide_simple_subprocess, IDE, SIMPLE_SUBPROCESS, GObject)
+struct _IdeSimpleSubprocess
+{
+ GObject parent_instance;
+ GSubprocess *subprocess;
+};
+
IdeSubprocess *ide_simple_subprocess_new (GSubprocess *subprocess);
G_END_DECLS
diff --git a/src/libide/subprocess/ide-simple-subprocess.c b/src/libide/threading/ide-simple-subprocess.c
similarity index 98%
rename from src/libide/subprocess/ide-simple-subprocess.c
rename to src/libide/threading/ide-simple-subprocess.c
index 81f99dd77..d6d7a8f92 100644
--- a/src/libide/subprocess/ide-simple-subprocess.c
+++ b/src/libide/threading/ide-simple-subprocess.c
@@ -22,15 +22,9 @@
#include "config.h"
-#include "ide-debug.h"
+#include <libide-core.h>
-#include "subprocess/ide-simple-subprocess.h"
-
-struct _IdeSimpleSubprocess
-{
- GObject parent_instance;
- GSubprocess *subprocess;
-};
+#include "ide-simple-subprocess-private.h"
static void subprocess_iface_init (IdeSubprocessInterface *iface);
diff --git a/src/libide/subprocess/ide-subprocess-launcher.c b/src/libide/threading/ide-subprocess-launcher.c
similarity index 96%
rename from src/libide/subprocess/ide-subprocess-launcher.c
rename to src/libide/threading/ide-subprocess-launcher.c
index 09a08c434..6e7f7aacf 100644
--- a/src/libide/subprocess/ide-subprocess-launcher.c
+++ b/src/libide/threading/ide-subprocess-launcher.c
@@ -22,9 +22,9 @@
#include "config.h"
-#include <dazzle.h>
-#include <fcntl.h>
#include <errno.h>
+#include <fcntl.h>
+#include <libide-core.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
@@ -33,15 +33,13 @@
#include <sys/types.h>
#include <unistd.h>
-#include "ide-debug.h"
+#include "ide-environment.h"
+#include "ide-environment-variable.h"
+#include "ide-flatpak-subprocess-private.h"
+#include "ide-simple-subprocess-private.h"
+#include "ide-subprocess-launcher.h"
-#include "buildsystem/ide-environment-variable.h"
-#include "buildsystem/ide-environment.h"
-#include "subprocess/ide-breakout-subprocess.h"
-#include "subprocess/ide-breakout-subprocess-private.h"
-#include "subprocess/ide-simple-subprocess.h"
-#include "subprocess/ide-subprocess-launcher.h"
-#include "util/ide-flatpak.h"
+#define is_flatpak() (ide_get_process_kind() == IDE_PROCESS_KIND_FLATPAK)
typedef struct
{
@@ -145,7 +143,7 @@ ide_subprocess_launcher_kill_host_process (GCancellable *cancellable,
IDE_ENTRY;
g_assert (G_IS_CANCELLABLE (cancellable));
- g_assert (IDE_IS_BREAKOUT_SUBPROCESS (subprocess));
+ g_assert (IDE_IS_FLATPAK_SUBPROCESS (subprocess));
g_signal_handlers_disconnect_by_func (cancellable,
G_CALLBACK (ide_subprocess_launcher_kill_host_process),
@@ -165,19 +163,19 @@ ide_subprocess_launcher_new (GSubprocessFlags flags)
}
static gboolean
-should_use_breakout_process (IdeSubprocessLauncher *self)
+should_use_flatpak_process (IdeSubprocessLauncher *self)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
g_assert (IDE_IS_SUBPROCESS_LAUNCHER (self));
- if (g_getenv ("IDE_USE_BREAKOUT_SUBPROCESS") != NULL)
+ if (g_getenv ("IDE_USE_FLATPAK_SUBPROCESS") != NULL)
return TRUE;
if (!priv->run_on_host)
return FALSE;
- return ide_is_flatpak ();
+ return is_flatpak ();
}
static void
@@ -223,7 +221,7 @@ ide_subprocess_launcher_spawn_host_worker (GTask *task,
if (priv->stderr_fd != -1)
stderr_fd = dup (priv->stderr_fd);
- process = _ide_breakout_subprocess_new (priv->cwd,
+ process = _ide_flatpak_subprocess_new (priv->cwd,
(const gchar * const *)priv->argv->pdata,
(const gchar * const *)priv->environ,
priv->flags,
@@ -383,6 +381,8 @@ ide_subprocess_launcher_real_spawn (IdeSubprocessLauncher *self,
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
g_autoptr(GTask) task = NULL;
+ IdeSubprocess *ret;
+ GError *local_error = NULL;
g_assert (IDE_IS_SUBPROCESS_LAUNCHER (self));
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
@@ -390,7 +390,7 @@ ide_subprocess_launcher_real_spawn (IdeSubprocessLauncher *self,
task = g_task_new (self, cancellable, NULL, NULL);
g_task_set_source_tag (task, ide_subprocess_launcher_real_spawn);
- if (priv->clear_env || (ide_is_flatpak () && priv->run_on_host))
+ if (priv->clear_env || (is_flatpak () && priv->run_on_host))
{
/*
* Many things break without at least PATH, HOME, etc. being set.
@@ -404,12 +404,22 @@ ide_subprocess_launcher_real_spawn (IdeSubprocessLauncher *self,
ide_subprocess_launcher_setenv (self, "LANG", g_getenv ("LANG"), FALSE);
}
- if (should_use_breakout_process (self))
+ if (should_use_flatpak_process (self))
ide_subprocess_launcher_spawn_host_worker (task, self, NULL, cancellable);
else
ide_subprocess_launcher_spawn_worker (task, self, NULL, cancellable);
- return g_task_propagate_pointer (task, error);
+ ret = g_task_propagate_pointer (task, &local_error);
+
+ if (!ret && !local_error)
+ local_error = g_error_new (G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "An unkonwn error occurred while spawning");
+
+ if (local_error != NULL)
+ g_propagate_error (error, g_steal_pointer (&local_error));
+
+ return g_steal_pointer (&ret);
}
static void
@@ -724,10 +734,10 @@ ide_subprocess_launcher_set_cwd (IdeSubprocessLauncher *self,
g_return_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self));
- if (dzl_str_empty0 (cwd))
+ if (ide_str_empty0 (cwd))
cwd = ".";
- if (!dzl_str_equal0 (priv->cwd, cwd))
+ if (!ide_str_equal0 (priv->cwd, cwd))
{
g_free (priv->cwd);
priv->cwd = g_strdup (cwd);
@@ -766,7 +776,7 @@ ide_subprocess_launcher_overlay_environment (IdeSubprocessLauncher *self,
key = ide_environment_variable_get_key (var);
value = ide_environment_variable_get_value (var);
- if (!dzl_str_empty0 (key))
+ if (!ide_str_empty0 (key))
ide_subprocess_launcher_setenv (self, key, value ?: "", TRUE);
}
}
diff --git a/src/libide/subprocess/ide-subprocess-launcher.h b/src/libide/threading/ide-subprocess-launcher.h
similarity index 96%
rename from src/libide/subprocess/ide-subprocess-launcher.h
rename to src/libide/threading/ide-subprocess-launcher.h
index 8e8b41af7..7f64e8780 100644
--- a/src/libide/subprocess/ide-subprocess-launcher.h
+++ b/src/libide/threading/ide-subprocess-launcher.h
@@ -20,11 +20,15 @@
#pragma once
-#include <gio/gio.h>
+#if !defined (IDE_THREADING_INSIDE) && !defined (IDE_THREADING_COMPILATION)
+# error "Only <libide-threading.h> can be included directly."
+#endif
-#include "ide-version-macros.h"
+#include <gio/gio.h>
+#include <libide-core.h>
-#include "ide-types.h"
+#include "ide-subprocess.h"
+#include "ide-environment.h"
G_BEGIN_DECLS
@@ -42,14 +46,7 @@ struct _IdeSubprocessLauncherClass
GError **error);
/*< private >*/
- gpointer _reserved1;
- gpointer _reserved2;
- gpointer _reserved3;
- gpointer _reserved4;
- gpointer _reserved5;
- gpointer _reserved6;
- gpointer _reserved7;
- gpointer _reserved8;
+ gpointer _reserved[8];
};
IDE_AVAILABLE_IN_3_32
diff --git a/src/libide/subprocess/ide-subprocess-supervisor.c
b/src/libide/threading/ide-subprocess-supervisor.c
similarity index 99%
rename from src/libide/subprocess/ide-subprocess-supervisor.c
rename to src/libide/threading/ide-subprocess-supervisor.c
index 1ce55d6f4..d6f72fce5 100644
--- a/src/libide/subprocess/ide-subprocess-supervisor.c
+++ b/src/libide/threading/ide-subprocess-supervisor.c
@@ -22,10 +22,10 @@
#include "config.h"
-#include "ide-debug.h"
+#include <libide-core.h>
-#include "subprocess/ide-subprocess.h"
-#include "subprocess/ide-subprocess-supervisor.h"
+#include "ide-subprocess.h"
+#include "ide-subprocess-supervisor.h"
/*
* We will rate limit supervision to once per RATE_LIMIT_THRESHOLD_SECONDS
diff --git a/src/libide/subprocess/ide-subprocess-supervisor.h
b/src/libide/threading/ide-subprocess-supervisor.h
similarity index 91%
rename from src/libide/subprocess/ide-subprocess-supervisor.h
rename to src/libide/threading/ide-subprocess-supervisor.h
index 80b412f79..7d69349c0 100644
--- a/src/libide/subprocess/ide-subprocess-supervisor.h
+++ b/src/libide/threading/ide-subprocess-supervisor.h
@@ -20,10 +20,14 @@
#pragma once
-#include "ide-version-macros.h"
+#if !defined (IDE_THREADING_INSIDE) && !defined (IDE_THREADING_COMPILATION)
+# error "Only <libide-threading.h> can be included directly."
+#endif
-#include "subprocess/ide-subprocess.h"
-#include "subprocess/ide-subprocess-launcher.h"
+#include <libide-core.h>
+
+#include "ide-subprocess.h"
+#include "ide-subprocess-launcher.h"
G_BEGIN_DECLS
diff --git a/src/libide/subprocess/ide-subprocess.c b/src/libide/threading/ide-subprocess.c
similarity index 99%
rename from src/libide/subprocess/ide-subprocess.c
rename to src/libide/threading/ide-subprocess.c
index eedcb2cda..c2af9c13f 100644
--- a/src/libide/subprocess/ide-subprocess.c
+++ b/src/libide/threading/ide-subprocess.c
@@ -23,10 +23,9 @@
#include "config.h"
#include <string.h>
+#include <libide-core.h>
-#include "ide-debug.h"
-
-#include "subprocess/ide-subprocess.h"
+#include "ide-subprocess.h"
G_DEFINE_INTERFACE (IdeSubprocess, ide_subprocess, G_TYPE_OBJECT)
diff --git a/src/libide/subprocess/ide-subprocess.h b/src/libide/threading/ide-subprocess.h
similarity index 56%
rename from src/libide/subprocess/ide-subprocess.h
rename to src/libide/threading/ide-subprocess.h
index 45e65bfd9..583592a88 100644
--- a/src/libide/subprocess/ide-subprocess.h
+++ b/src/libide/threading/ide-subprocess.h
@@ -20,9 +20,12 @@
#pragma once
-#include <gio/gio.h>
+#if !defined (IDE_THREADING_INSIDE) && !defined (IDE_THREADING_COMPILATION)
+# error "Only <libide-threading.h> can be included directly."
+#endif
-#include "ide-version-macros.h"
+#include <gio/gio.h>
+#include <libide-core.h>
G_BEGIN_DECLS
@@ -93,85 +96,85 @@ struct _IdeSubprocessInterface
};
IDE_AVAILABLE_IN_3_32
-const gchar *ide_subprocess_get_identifier (IdeSubprocess *self);
+const gchar *ide_subprocess_get_identifier (IdeSubprocess *self);
IDE_AVAILABLE_IN_3_32
-GInputStream *ide_subprocess_get_stdout_pipe (IdeSubprocess *self);
+GInputStream *ide_subprocess_get_stdout_pipe (IdeSubprocess *self);
IDE_AVAILABLE_IN_3_32
-GInputStream *ide_subprocess_get_stderr_pipe (IdeSubprocess *self);
+GInputStream *ide_subprocess_get_stderr_pipe (IdeSubprocess *self);
IDE_AVAILABLE_IN_3_32
-GOutputStream *ide_subprocess_get_stdin_pipe (IdeSubprocess *self);
+GOutputStream *ide_subprocess_get_stdin_pipe (IdeSubprocess *self);
IDE_AVAILABLE_IN_3_32
-gboolean ide_subprocess_wait (IdeSubprocess *self,
- GCancellable *cancellable,
- GError **error);
+gboolean ide_subprocess_wait (IdeSubprocess *self,
+ GCancellable *cancellable,
+ GError **error);
IDE_AVAILABLE_IN_3_32
-gboolean ide_subprocess_wait_check (IdeSubprocess *self,
- GCancellable *cancellable,
- GError **error);
+gboolean ide_subprocess_wait_check (IdeSubprocess *self,
+ GCancellable *cancellable,
+ GError **error);
IDE_AVAILABLE_IN_3_32
-void ide_subprocess_wait_async (IdeSubprocess *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
+void ide_subprocess_wait_async (IdeSubprocess *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
IDE_AVAILABLE_IN_3_32
-gboolean ide_subprocess_wait_finish (IdeSubprocess *self,
- GAsyncResult *result,
- GError **error);
+gboolean ide_subprocess_wait_finish (IdeSubprocess *self,
+ GAsyncResult *result,
+ GError **error);
IDE_AVAILABLE_IN_3_32
-void ide_subprocess_wait_check_async (IdeSubprocess *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
+void ide_subprocess_wait_check_async (IdeSubprocess *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
IDE_AVAILABLE_IN_3_32
-gboolean ide_subprocess_wait_check_finish (IdeSubprocess *self,
- GAsyncResult *result,
- GError **error);
+gboolean ide_subprocess_wait_check_finish (IdeSubprocess *self,
+ GAsyncResult *result,
+ GError **error);
IDE_AVAILABLE_IN_3_32
-gboolean ide_subprocess_check_exit_status (IdeSubprocess *self,
- GError **error);
+gboolean ide_subprocess_check_exit_status (IdeSubprocess *self,
+ GError **error);
IDE_AVAILABLE_IN_3_32
-gboolean ide_subprocess_get_successful (IdeSubprocess *self);
+gboolean ide_subprocess_get_successful (IdeSubprocess *self);
IDE_AVAILABLE_IN_3_32
-gboolean ide_subprocess_get_if_exited (IdeSubprocess *self);
+gboolean ide_subprocess_get_if_exited (IdeSubprocess *self);
IDE_AVAILABLE_IN_3_32
-gint ide_subprocess_get_exit_status (IdeSubprocess *self);
+gint ide_subprocess_get_exit_status (IdeSubprocess *self);
IDE_AVAILABLE_IN_3_32
-gboolean ide_subprocess_get_if_signaled (IdeSubprocess *self);
+gboolean ide_subprocess_get_if_signaled (IdeSubprocess *self);
IDE_AVAILABLE_IN_3_32
-gint ide_subprocess_get_term_sig (IdeSubprocess *self);
+gint ide_subprocess_get_term_sig (IdeSubprocess *self);
IDE_AVAILABLE_IN_3_32
-gint ide_subprocess_get_status (IdeSubprocess *self);
+gint ide_subprocess_get_status (IdeSubprocess *self);
IDE_AVAILABLE_IN_3_32
-void ide_subprocess_send_signal (IdeSubprocess *self,
- gint signal_num);
+void ide_subprocess_send_signal (IdeSubprocess *self,
+ gint signal_num);
IDE_AVAILABLE_IN_3_32
-void ide_subprocess_force_exit (IdeSubprocess *self);
+void ide_subprocess_force_exit (IdeSubprocess *self);
IDE_AVAILABLE_IN_3_32
-gboolean ide_subprocess_communicate (IdeSubprocess *self,
- GBytes *stdin_buf,
- GCancellable *cancellable,
- GBytes **stdout_buf,
- GBytes **stderr_buf,
- GError **error);
+gboolean ide_subprocess_communicate (IdeSubprocess *self,
+ GBytes *stdin_buf,
+ GCancellable *cancellable,
+ GBytes **stdout_buf,
+ GBytes **stderr_buf,
+ GError **error);
IDE_AVAILABLE_IN_3_32
-gboolean ide_subprocess_communicate_utf8 (IdeSubprocess *self,
- const gchar *stdin_buf,
- GCancellable *cancellable,
- gchar **stdout_buf,
- gchar **stderr_buf,
- GError **error);
+gboolean ide_subprocess_communicate_utf8 (IdeSubprocess *self,
+ const gchar *stdin_buf,
+ GCancellable *cancellable,
+ gchar **stdout_buf,
+ gchar **stderr_buf,
+ GError **error);
IDE_AVAILABLE_IN_3_32
-void ide_subprocess_communicate_async (IdeSubprocess *self,
- GBytes *stdin_buf,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
+void ide_subprocess_communicate_async (IdeSubprocess *self,
+ GBytes *stdin_buf,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
IDE_AVAILABLE_IN_3_32
-gboolean ide_subprocess_communicate_finish (IdeSubprocess *self,
- GAsyncResult *result,
- GBytes **stdout_buf,
- GBytes **stderr_buf,
- GError **error);
+gboolean ide_subprocess_communicate_finish (IdeSubprocess *self,
+ GAsyncResult *result,
+ GBytes **stdout_buf,
+ GBytes **stderr_buf,
+ GError **error);
IDE_AVAILABLE_IN_3_32
void ide_subprocess_communicate_utf8_async (IdeSubprocess *self,
const gchar *stdin_buf,
diff --git a/src/libide/threading/ide-task.c b/src/libide/threading/ide-task.c
index 185c92361..f32ebc460 100644
--- a/src/libide/threading/ide-task.c
+++ b/src/libide/threading/ide-task.c
@@ -21,11 +21,18 @@
#include "config.h"
-#include <dazzle.h>
+#include <libide-core.h>
-#include "threading/ide-task.h"
-#include "threading/ide-thread-pool.h"
-#include "threading/ide-thread-private.h"
+#include "ide-task.h"
+#include "ide-thread-pool.h"
+#include "ide-thread-private.h"
+
+/* From GDK_PRIORITY_REDRAW */
+#define PRIORITY_REDRAW (G_PRIORITY_HIGH_IDLE + 20)
+
+#if 0
+# define ENABLE_TIME_CHART
+#endif
/**
* SECTION:ide-task
@@ -237,6 +244,11 @@ typedef struct
*/
gpointer source_tag;
+#ifdef ENABLE_TIME_CHART
+ /* The time the task was created */
+ gint64 begin_time;
+#endif
+
/*
* Our priority for scheduling tasks in the particular workqueue.
*/
@@ -320,8 +332,6 @@ static void ide_task_release (IdeTask *self,
G_DEFINE_AUTOPTR_CLEANUP_FUNC (IdeTaskData, ide_task_data_free);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (IdeTaskResult, ide_task_result_free);
-DZL_DEFINE_COUNTER (instances, "Tasks", "Instances", "Number of active tasks")
-
G_DEFINE_TYPE_WITH_CODE (IdeTask, ide_task, G_TYPE_OBJECT,
G_ADD_PRIVATE (IdeTask)
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, async_result_init_iface))
@@ -623,8 +633,6 @@ ide_task_finalize (GObject *object)
g_mutex_clear (&priv->mutex);
G_OBJECT_CLASS (ide_task_parent_class)->finalize (object);
-
- DZL_COUNTER_DEC (instances);
}
static void
@@ -676,14 +684,12 @@ ide_task_init (IdeTask *self)
{
IdeTaskPrivate *priv = ide_task_get_instance_private (self);
- DZL_COUNTER_INC (instances);
-
g_mutex_init (&priv->mutex);
priv->check_cancellable = TRUE;
priv->release_on_propagate = TRUE;
priv->priority = G_PRIORITY_DEFAULT;
- priv->complete_priority = GDK_PRIORITY_REDRAW + 1;
+ priv->complete_priority = PRIORITY_REDRAW + 1;
priv->main_context = g_main_context_ref_thread_default ();
priv->global_link.data = self;
@@ -764,13 +770,16 @@ IdeTask *
priv->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
priv->callback = callback;
priv->user_data = user_data;
+#ifdef ENABLE_TIME_CHART
+ priv->begin_time = g_get_monotonic_time ();
+#endif
return g_steal_pointer (&self);
}
/**
* ide_task_is_valid:
- * @self: (nullable) (type Ide.Task): a #IdeTask
+ * @self: (nullable) (type IdeTask): a #IdeTask
* @source_object: (nullable): a #GObject or %NULL
*
* Checks if @source_object matches the object the task was created with.
@@ -979,6 +988,12 @@ ide_task_return_cb (gpointer user_data)
self = g_steal_pointer (&result->task);
priv = ide_task_get_instance_private (self);
+#ifdef ENABLE_TIME_CHART
+ g_message ("TASK-END: %s: duration=%lf",
+ priv->name,
+ (g_get_monotonic_time () - priv->begin_time) / (gdouble)G_USEC_PER_SEC);
+#endif
+
g_mutex_lock (&priv->mutex);
g_assert (priv->return_source != 0);
@@ -2061,6 +2076,10 @@ ide_task_set_name (IdeTask *self,
g_mutex_lock (&priv->mutex);
priv->name = name;
g_mutex_unlock (&priv->mutex);
+
+#ifdef ENABLE_TIME_CHART
+ g_message ("TASK-BEGIN: %s", name);
+#endif
}
/**
@@ -2132,7 +2151,7 @@ async_result_init_iface (GAsyncResultIface *iface)
}
void
-ide_dump_tasks (void)
+_ide_dump_tasks (void)
{
guint i = 0;
diff --git a/src/libide/threading/ide-task.h b/src/libide/threading/ide-task.h
index fe6d939b4..b424edad7 100644
--- a/src/libide/threading/ide-task.h
+++ b/src/libide/threading/ide-task.h
@@ -19,9 +19,11 @@
#pragma once
-#include <gio/gio.h>
+#if !defined (IDE_THREADING_INSIDE) && !defined (IDE_THREADING_COMPILATION)
+# error "Only <libide-threading.h> can be included directly."
+#endif
-#include "ide-version-macros.h"
+#include <gio/gio.h>
G_BEGIN_DECLS
@@ -167,8 +169,6 @@ void ide_task_report_new_error (gpointer source_o
gint code,
const gchar *format,
...) G_GNUC_PRINTF (7, 8);
-IDE_AVAILABLE_IN_3_32
-void ide_dump_tasks (void);
#ifdef __GNUC__
# define ide_task_new(self, cancellable, callback, user_data) \
diff --git a/src/libide/threading/ide-thread-pool.c b/src/libide/threading/ide-thread-pool.c
index 934d18f26..d21579b9d 100644
--- a/src/libide/threading/ide-thread-pool.c
+++ b/src/libide/threading/ide-thread-pool.c
@@ -22,12 +22,10 @@
#include "config.h"
-#include <dazzle.h>
+#include <libide-core.h>
-#include "ide-debug.h"
-
-#include "threading/ide-thread-pool.h"
-#include "threading/ide-thread-private.h"
+#include "ide-thread-pool.h"
+#include "ide-thread-private.h"
typedef struct
{
@@ -54,9 +52,6 @@ struct _IdeThreadPool
gboolean exclusive;
};
-DZL_DEFINE_COUNTER (TotalTasks, "ThreadPool", "Total Tasks", "Total number of tasks processed.")
-DZL_DEFINE_COUNTER (QueuedTasks, "ThreadPool", "Queued Tasks", "Current number of pending tasks.")
-
static IdeThreadPool thread_pools[] = {
{ NULL, IDE_THREAD_POOL_DEFAULT, 10, 1, FALSE },
{ NULL, IDE_THREAD_POOL_COMPILER, 2, 2, FALSE },
@@ -105,8 +100,6 @@ ide_thread_pool_push_task (IdeThreadPoolKind kind,
g_return_if_fail (G_IS_TASK (task));
g_return_if_fail (func != NULL);
- DZL_COUNTER_INC (TotalTasks);
-
pool = ide_thread_pool_get_pool (kind);
if (pool != NULL)
@@ -119,8 +112,6 @@ ide_thread_pool_push_task (IdeThreadPoolKind kind,
work_item->task.task = g_object_ref (task);
work_item->task.func = func;
- DZL_COUNTER_INC (QueuedTasks);
-
g_thread_pool_push (pool, work_item, NULL);
}
else
@@ -174,8 +165,6 @@ ide_thread_pool_push_with_priority (IdeThreadPoolKind kind,
g_return_if_fail (kind < IDE_THREAD_POOL_LAST);
g_return_if_fail (func != NULL);
- DZL_COUNTER_INC (TotalTasks);
-
pool = ide_thread_pool_get_pool (kind);
if (pool != NULL)
@@ -188,8 +177,6 @@ ide_thread_pool_push_with_priority (IdeThreadPoolKind kind,
work_item->func.callback = func;
work_item->func.data = func_data;
- DZL_COUNTER_INC (QueuedTasks);
-
g_thread_pool_push (pool, work_item, NULL);
}
else
@@ -208,8 +195,6 @@ ide_thread_pool_worker (gpointer data,
g_assert (work_item != NULL);
- DZL_COUNTER_DEC (QueuedTasks);
-
if (work_item->type == TYPE_TASK)
{
gpointer source_object = g_task_get_source_object (work_item->task.task);
diff --git a/src/libide/threading/ide-thread-pool.h b/src/libide/threading/ide-thread-pool.h
index 0b2fa6016..2bc9bb99e 100644
--- a/src/libide/threading/ide-thread-pool.h
+++ b/src/libide/threading/ide-thread-pool.h
@@ -20,9 +20,12 @@
#pragma once
-#include <gio/gio.h>
+#if !defined (IDE_THREADING_INSIDE) && !defined (IDE_THREADING_COMPILATION)
+# error "Only <libide-threading.h> can be included directly."
+#endif
-#include "ide-version-macros.h"
+#include <gio/gio.h>
+#include <libide-core.h>
G_BEGIN_DECLS
@@ -41,6 +44,8 @@ typedef enum
* IdeThreadFunc:
* @user_data: (closure) (transfer full): The closure for the callback.
*
+ *
+ * Since: 3.32
*/
typedef void (*IdeThreadFunc) (gpointer user_data);
diff --git a/src/libide/threading/ide-thread-private.h b/src/libide/threading/ide-thread-private.h
index ca416a5a9..defe1fc7d 100644
--- a/src/libide/threading/ide-thread-private.h
+++ b/src/libide/threading/ide-thread-private.h
@@ -25,5 +25,6 @@
G_BEGIN_DECLS
void _ide_thread_pool_init (gboolean is_worker);
+void _ide_dump_tasks (void);
G_END_DECLS
diff --git a/src/libide/threading/libide-threading.h b/src/libide/threading/libide-threading.h
new file mode 100644
index 000000000..b321f06ab
--- /dev/null
+++ b/src/libide/threading/libide-threading.h
@@ -0,0 +1,35 @@
+/* ide-threading.h
+ *
+ * Copyright 2018-2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libide-core.h>
+
+#define IDE_THREADING_INSIDE
+
+#include "ide-environment.h"
+#include "ide-environment-variable.h"
+#include "ide-subprocess-launcher.h"
+#include "ide-subprocess-supervisor.h"
+#include "ide-subprocess.h"
+#include "ide-task.h"
+#include "ide-thread-pool.h"
+
+#undef IDE_THREADING_INSIDE
diff --git a/src/libide/threading/meson.build b/src/libide/threading/meson.build
index 201e188e0..d38ddfb64 100644
--- a/src/libide/threading/meson.build
+++ b/src/libide/threading/meson.build
@@ -1,20 +1,78 @@
-threading_headers = [
- 'ide-thread-pool.h',
+libide_threading_header_subdir = join_paths(libide_header_subdir, 'threading')
+libide_include_directories += include_directories('.')
+
+#
+# Public API Headers
+#
+
+libide_threading_public_headers = [
+ 'ide-environment.h',
+ 'ide-environment-variable.h',
+ 'ide-subprocess.h',
+ 'ide-subprocess-launcher.h',
+ 'ide-subprocess-supervisor.h',
'ide-task.h',
+ 'ide-thread-pool.h',
+ 'libide-threading.h',
]
-threading_sources = [
- 'ide-thread-pool.c',
+install_headers(libide_threading_public_headers, subdir: libide_threading_header_subdir)
+
+#
+# Sources
+#
+
+libide_threading_private_headers = [
+ 'ide-thread-private.h',
+ 'ide-flatpak-subprocess-private.h',
+ 'ide-gtask-private.h',
+ 'ide-simple-subprocess-private.h',
+]
+
+libide_threading_private_sources = [
+ 'ide-flatpak-subprocess.c',
+ 'ide-simple-subprocess.c',
+]
+
+libide_threading_public_sources = [
+ 'ide-environment-variable.c',
+ 'ide-environment.c',
+ 'ide-gtask.c',
+ 'ide-subprocess-launcher.c',
+ 'ide-subprocess-supervisor.c',
+ 'ide-subprocess.c',
'ide-task.c',
+ 'ide-thread-pool.c',
]
-threading_enums = [
- 'ide-thread-pool.h',
- 'ide-task.h',
+libide_threading_sources = libide_threading_public_sources + libide_threading_private_sources
+
+#
+# Library Definitions
+#
+
+libide_threading_deps = [
+ libgio_dep,
+ libgiounix_dep,
+
+ libide_core_dep,
]
-libide_public_headers += files(threading_headers)
-libide_public_sources += files(threading_sources)
-libide_enum_headers += files(threading_enums)
+libide_threading = static_library('ide-threading-' + libide_api_version, libide_threading_sources,
+ dependencies: libide_threading_deps,
+ c_args: libide_args + release_args + ['-DIDE_THREADING_COMPILATION'],
+)
+
+libide_threading_dep = declare_dependency(
+ sources: libide_threading_private_headers,
+ dependencies: libide_threading_deps,
+ link_whole: libide_threading,
+ include_directories: include_directories('.'),
+)
-install_headers(threading_headers, subdir: join_paths(libide_header_subdir, 'threading'))
+gnome_builder_public_sources += files(libide_threading_public_sources)
+gnome_builder_public_headers += files(libide_threading_public_headers)
+gnome_builder_private_sources += files(libide_threading_private_sources)
+gnome_builder_private_headers += files(libide_threading_private_headers)
+gnome_builder_include_subdirs += libide_threading_header_subdir
+gnome_builder_gir_extra_args += ['--c-include=libide-threading.h', '-DIDE_THREADING_COMPILATION']
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]