This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository libx2goclient. commit 36158f4a194419f117d04708433d1f54663b9476 Author: Mihai Moldovan <ionic@ionic.de> Date: Sat Oct 31 02:43:55 2020 +0100 src/x2goclient-network-ssh.{c,h}: add x2goclient_network_ssh_disconnect (), which is more or less a copy of the old code in x2goclient_network_ssh_finalize (). Naturally, we're also using it in x2goclient_network_ssh_finalize (). --- src/x2goclient-network-ssh.c | 132 ++++++++++++++++++++++++++++--------------- src/x2goclient-network-ssh.h | 1 + 2 files changed, 89 insertions(+), 44 deletions(-) diff --git a/src/x2goclient-network-ssh.c b/src/x2goclient-network-ssh.c index d130cac..e22c027 100644 --- a/src/x2goclient-network-ssh.c +++ b/src/x2goclient-network-ssh.c @@ -72,6 +72,7 @@ G_DEFINE_TYPE (X2GoClientNetworkOptionsSSH, x2goclient_network_options_ssh, X2GO * improve maintainability. */ typedef gboolean (*parent_connect_type) (void * const self, void * const gerr); +typedef gboolean (*parent_disconnect_type) (void * const self, void * const gerr); static void x2goclient_network_options_ssh_class_init (X2GoClientNetworkOptionsSSHClass * const klass) { @@ -153,6 +154,7 @@ static GSocketAddress* x2goclient_network_ssh_parse_sockspec_alias (const GStrin static GSocketAddress* x2goclient_network_ssh_parse_sockspec (X2GoClientNetwork * const parent, const GString * const sockspec); static gboolean x2goclient_network_ssh_kill_subprocesses (X2GoClientNetworkSSH * const self); static gboolean x2goclient_network_ssh_parent_connect (X2GoClientNetwork * const parent, GError ** const gerr); +static gboolean x2goclient_network_ssh_parent_disconnect (X2GoClientNetwork * const parent, GError ** const gerr); static gboolean x2goclient_network_ssh_fetch_openssh_version (X2GoClientNetworkSSH * const self, GError ** const gerr); static void x2goclient_network_ssh_log_std_str (const gchar * const str, const gsize str_size, const _Bool select_stderr); static gboolean x2goclient_network_ssh_gptrarray_to_string (GPtrArray * const arr, const gchar * const prelude, gchar ** const ret_str); @@ -194,6 +196,7 @@ static void x2goclient_network_ssh_class_init (X2GoClientNetworkSSHClass * const X2GoClientNetworkClass *parent_class = X2GOCLIENT_NETWORK_CLASS (klass); parent_class->connect = &x2goclient_network_ssh_parent_connect; + parent_class->disconnect = &x2goclient_network_ssh_parent_disconnect; parent_class->parse_sockspec = &x2goclient_network_ssh_parse_sockspec; } @@ -253,50 +256,8 @@ static void x2goclient_network_ssh_finalize (GObject * const object) { * connection, so make sure that the dependencies are set up correctly here. */ - /* Remove timeout source. */ - g_mutex_lock (&(self->check_thread_mutex)); - if (self->check_thread_loop) { - g_main_context_invoke_full (self->check_thread_context, G_PRIORITY_DEFAULT_IDLE, G_SOURCE_FUNC (&g_main_loop_quit), self->check_thread_loop, NULL); - } - - if (self->check_timeout_source) { - g_source_destroy (self->check_timeout_source); - g_source_unref (self->check_timeout_source); - self->check_timeout_source = NULL; - } - - /* Let last event run out and thread terminate. */ - if (self->check_thread) { - /* - * Keep the mutex clear while joining the thread. - * - * Otherwise, the thread's main function won't continue to execute (and - * finish) after its main loop (correctly) terminated. - */ - g_mutex_unlock (&(self->check_thread_mutex)); - - (void) g_thread_join (self->check_thread); - - g_mutex_lock (&(self->check_thread_mutex)); - self->check_thread = NULL; - } - - /* - * Context should be gone by now, implicitly through the thread's main - * method, so let's just get rid of the pointer. - */ - self->check_thread_context = NULL; - g_mutex_unlock (&(self->check_thread_mutex)); - - g_mutex_clear (&(self->check_thread_mutex)); - - if (!(x2goclient_network_ssh_kill_subprocesses (self))) { - g_log (NULL, G_LOG_LEVEL_CRITICAL, "Some subprocesses were not terminated correctly!"); - } - - g_free (self->control_path); - self->control_path = NULL; - + /* Disconnect from held connections and terminate the master connection. */ + x2goclient_network_ssh_disconnect (self, NULL); /* Properties. */ if (self->openssh_version) { @@ -984,6 +945,89 @@ static gboolean x2goclient_network_ssh_parent_connect (X2GoClientNetwork * const return (ret); } +gboolean x2goclient_network_ssh_disconnect (X2GoClientNetworkSSH * const self, GError ** const gerr) { + gboolean ret = FALSE; + + g_return_val_if_fail (X2GOCLIENT_IS_NETWORK_SSH (self), ret); + g_return_val_if_fail (((NULL == gerr) || (NULL == *gerr)), ret); + + X2GoClientNetwork *parent = X2GOCLIENT_NETWORK (self); + X2GoClientNetworkClass *parent_class = X2GOCLIENT_NETWORK_GET_CLASS (parent); + + /* Fetch parent's disconnect function. */ + parent_disconnect_type parent_disconnect = NULL; + g_object_get (G_OBJECT (self), "disconnect-function", &parent_disconnect, NULL); + g_assert (parent_disconnect); + + if (parent_disconnect) { + ret = parent_disconnect (parent, gerr); + } + + return (ret); +} + +static gboolean x2goclient_network_ssh_parent_disconnect (X2GoClientNetwork * const parent, GError ** const gerr) { + gboolean ret = FALSE; + + g_return_val_if_fail (X2GOCLIENT_IS_NETWORK_SSH (parent), ret); + g_return_val_if_fail (((NULL == gerr) || (NULL == *gerr)), ret); + + X2GoClientNetworkSSH *self = X2GOCLIENT_NETWORK_SSH (parent); + + /* Actual implementation here. */ + + /* Most things can't really fail, so prepare for success. */ + ret = TRUE; + + /* Remove timeout source. */ + g_mutex_lock (&(self->check_thread_mutex)); + if (self->check_thread_loop) { + g_main_context_invoke_full (self->check_thread_context, G_PRIORITY_DEFAULT_IDLE, G_SOURCE_FUNC (&g_main_loop_quit), self->check_thread_loop, NULL); + } + + if (self->check_timeout_source) { + g_source_destroy (self->check_timeout_source); + g_source_unref (self->check_timeout_source); + self->check_timeout_source = NULL; + } + + /* Let last event run out and thread terminate. */ + if (self->check_thread) { + /* + * Keep the mutex clear while joining the thread. + * + * Otherwise, the thread's main function won't continue to execute (and + * finish) after its main loop (correctly) terminated. + */ + g_mutex_unlock (&(self->check_thread_mutex)); + + (void) g_thread_join (self->check_thread); + + g_mutex_lock (&(self->check_thread_mutex)); + self->check_thread = NULL; + } + + /* + * Context should be gone by now, implicitly through the thread's main + * method, so let's just get rid of the pointer. + */ + self->check_thread_context = NULL; + g_mutex_unlock (&(self->check_thread_mutex)); + + g_mutex_clear (&(self->check_thread_mutex)); + + ret &= x2goclient_network_ssh_kill_subprocesses (self); + + if (!(ret)) { + g_log (NULL, G_LOG_LEVEL_CRITICAL, "Some subprocesses were not terminated correctly!"); + } + + g_free (self->control_path); + self->control_path = NULL; + + return (ret); +} + static gboolean x2goclient_network_ssh_fetch_openssh_version (X2GoClientNetworkSSH * const self, GError ** const gerr) { gboolean ret = FALSE; diff --git a/src/x2goclient-network-ssh.h b/src/x2goclient-network-ssh.h index 690d550..f3108cb 100644 --- a/src/x2goclient-network-ssh.h +++ b/src/x2goclient-network-ssh.h @@ -73,6 +73,7 @@ enum { gboolean x2goclient_network_ssh_connect (X2GoClientNetworkSSH * const self, GError ** const gerr); +gboolean x2goclient_network_ssh_disconnect (X2GoClientNetworkSSH * const self, GError ** const gerr); G_END_DECLS -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/libx2goclient.git