[X2Go-Commits] [libx2goclient] 88/132: src/x2goclient-network{, -ssh}.{c, h}: rework (dis-)connect hierarchy architecture.
git-admin at x2go.org
git-admin at x2go.org
Fri Dec 3 15:26:32 CET 2021
This is an automated email from the git hooks/post-receive script.
x2go pushed a commit to branch master
in repository libx2goclient.
commit a498517f64b3bd3adcf894d033e55ef093c6fafa
Author: Mihai Moldovan <ionic at ionic.de>
Date: Sat Jul 31 11:19:53 2021 +0200
src/x2goclient-network{,-ssh}.{c,h}: rework (dis-)connect hierarchy architecture.
The previous approach used a virtual function in the parent class
structure, which was supposed to be set to the correct function in
derived classes, which was then used to call the derived class's
function in the parent's (dis-)connect function and properties on the
parent class exposing its (dis-)connect functions via indirection
(function pointer to object pointer), which could be used in derived
classes to effectively chain up.
This had multiple shortcomings:
- chaining wasn't really possible or implemented due to a single
property for each parent function.
- the code needed ugly typedefs for these function pointers and
reference types to these function pointers as part of the
indirection, which wasn't even compatible with
gobject-introspection.
- a slightly more complex class hierarchy such as A -> B -> C would
have worked by accident/chance, if the properties would have been
available and set on A, and derived implementations would have
chained down, since in that case, chaining up would only be
necessary to go to the top class, but this wouldn't have been
elegant.
Instead, we'll switch to using multiple virtual functions in the class
structures and get rid of the properties.
Implemented carefully, this allows us to fully chain up to the top level
and then chain down via derived class virtual functions that each chain
to the next one.
The upside of that is that no matter which function you call, the whole
chain will always be executed in a predictable manner.
Example (connect-side only, disconnect is symmetrical) for a hierarchy
such as A -> B -> C -> D:
- D_class_init () sets CClass::derived_connect () to
D_parent_connect () (the actual implementation)
- D_connect () chains up to CClass::connect () (and does nothing
else)
- D_parent_connect () implements D's connect functionality and does
not chain down (since it's at the bottom of the hierarchy)
- C_class_init () sets BClass::derived_connect () to
C_parent_connect () and CClass::connect () to C_connect ()
- C_connect () chains up to BClass::connect () (and does nothing
else)
- C_parent_connect () implements C's connect functionality and chains
down by calling CClass::derived_connect ()
- B_class_init () sets AClass::derived_connect () to
B_parent_connect () and BClass::connect () to B_connect ()
- B_connect () chains up to AClass::connect () (and does nothing
else)
- B_parent_connect () implements B's connect functionality and chains
down by calling BClass::derived_connect ()
- A_class_init () sets AClass::connect () to A_connect ()
- A_connect () checks the A:connected property and, if false,
implements A's connect functionality (if any) and chains down by
calling AClass::derived_connect ()
---
src/x2goclient-network-ssh.c | 69 +++++++----------
src/x2goclient-network.c | 178 +++++++++++++------------------------------
src/x2goclient-network.h | 113 ++++++++++++++++++++-------
3 files changed, 162 insertions(+), 198 deletions(-)
diff --git a/src/x2goclient-network-ssh.c b/src/x2goclient-network-ssh.c
index 89378b6..cb246a6 100644
--- a/src/x2goclient-network-ssh.c
+++ b/src/x2goclient-network-ssh.c
@@ -181,8 +181,8 @@ static GSocketAddress* x2goclient_network_ssh_parse_sockspec_ip (const GString *
static GSocketAddress* x2goclient_network_ssh_parse_sockspec_alias (const GString * const sockspec, GError ** const gerr);
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_parent_connect (const gpointer ptr, GError ** const gerr);
+static gboolean x2goclient_network_ssh_parent_disconnect (const gpointer ptr, 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);
@@ -245,8 +245,8 @@ 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->derived_connect = &x2goclient_network_ssh_parent_connect;
+ parent_class->derived_disconnect = &x2goclient_network_ssh_parent_disconnect;
parent_class->parse_sockspec = &x2goclient_network_ssh_parse_sockspec;
}
@@ -1064,8 +1064,9 @@ static gboolean x2goclient_network_ssh_kill_subprocesses (X2GoClientNetworkSSH *
*
* Wraps the SSH connect function.
*
- * This function can be called on #X2GoClientNetworkSSH objects and redirects
- * to the actual connection function, x2goclient_network_ssh_parent_connect().
+ * This function can be called on #X2GoClientNetworkSSH objects and chains up
+ * through the inheritance chain, eventually calling the actual connection
+ * function, x2goclient_network_ssh_parent_connect().
*
* x2goclient_network_ssh_parent_connect() opens an SSH connection to the
* remote location and registers the corresponding master connection
@@ -1125,20 +1126,12 @@ gboolean x2goclient_network_ssh_connect (X2GoClientNetworkSSH * const self, GErr
X2GoClientNetwork *parent = X2GOCLIENT_NETWORK (self);
X2GoClientNetworkClass *parent_class = X2GOCLIENT_NETWORK_GET_CLASS (parent);
- (void) parent_class;
- /* Fetch parent's connect function. */
- x2goclient_network_connect_type parent_connect = NULL;
- X2GoClientNetwork_connect_ref_type parent_connect_ref = NULL;
- g_object_get (G_OBJECT (self), "connect-function", &parent_connect_ref, NULL);
- g_assert (parent_connect_ref);
+ /* Just chain up here. */
+ g_assert (parent_class->connect);
- if (parent_connect_ref) {
- parent_connect = *(parent_connect_ref);
-
- if (parent_connect) {
- ret = parent_connect (parent, gerr);
- }
+ if (parent_class->connect) {
+ ret = parent_class->connect (parent, gerr);
}
return (ret);
@@ -1146,8 +1139,7 @@ gboolean x2goclient_network_ssh_connect (X2GoClientNetworkSSH * const self, GErr
/*
* x2goclient_network_ssh_parent_connect:
- * @parent: (in) (not optional): pointer to the #X2GoClientNetwork parent
- * instance.
+ * @ptr: (in) (not optional): pointer to the #X2GoClientNetworkSSH instance.
* @gerr: (out) (nullable): a return location for a #GError, pass %NULL if not
* interested.
*
@@ -1175,13 +1167,13 @@ gboolean x2goclient_network_ssh_connect (X2GoClientNetworkSSH * const self, GErr
*
* Since: 0.0.0
*/
-static gboolean x2goclient_network_ssh_parent_connect (X2GoClientNetwork * const parent, GError ** const gerr) {
+static gboolean x2goclient_network_ssh_parent_connect (const gpointer ptr, GError ** const gerr) {
gboolean ret = FALSE;
- g_return_val_if_fail (X2GOCLIENT_IS_NETWORK_SSH (parent), ret);
+ g_return_val_if_fail (X2GOCLIENT_IS_NETWORK_SSH (ptr), ret);
g_return_val_if_fail (((NULL == gerr) || (NULL == *gerr)), ret);
- X2GoClientNetworkSSH *self = X2GOCLIENT_NETWORK_SSH (parent);
+ X2GoClientNetworkSSH *self = X2GOCLIENT_NETWORK_SSH (ptr);
/* Actual implementation here. */
@@ -1335,9 +1327,9 @@ static gboolean x2goclient_network_ssh_parent_connect (X2GoClientNetwork * const
*
* Wraps the SSH disconnect function.
*
- * This function can be called on #X2GoClientNetworkSSH objects and redirects
- * to the actual disconnection function,
- * x2goclient_network_ssh_parent_disconnect().
+ * This function can be called on #X2GoClientNetworkSSH objects and chains up
+ * through the inheritance chain, eventually calling the actual disconnection
+ * function, x2goclient_network_ssh_parent_disconnect().
*
* x2goclient_network_ssh_parent_disconnect() terminates the registered master
* connection to the remote location (if it exists), clears the connected
@@ -1364,20 +1356,12 @@ gboolean x2goclient_network_ssh_disconnect (X2GoClientNetworkSSH * const self, G
X2GoClientNetwork *parent = X2GOCLIENT_NETWORK (self);
X2GoClientNetworkClass *parent_class = X2GOCLIENT_NETWORK_GET_CLASS (parent);
- (void) parent_class;
- /* Fetch parent's disconnect function. */
- x2goclient_network_disconnect_type parent_disconnect = NULL;
- X2GoClientNetwork_disconnect_ref_type parent_disconnect_ref = NULL;
- g_object_get (G_OBJECT (self), "disconnect-function", &parent_disconnect_ref, NULL);
- g_assert (parent_disconnect_ref);
+ /* Just chain up here. */
+ g_assert (parent_class->disconnect);
- if (parent_disconnect_ref) {
- parent_disconnect = *(parent_disconnect_ref);
-
- if (parent_disconnect) {
- ret = parent_disconnect (parent, gerr);
- }
+ if (parent_class->disconnect) {
+ ret = parent_class->disconnect (parent, gerr);
}
return (ret);
@@ -1385,8 +1369,7 @@ gboolean x2goclient_network_ssh_disconnect (X2GoClientNetworkSSH * const self, G
/*
* x2goclient_network_ssh_parent_disconnect:
- * @parent: (in) (not optional): pointer to the #X2GoClientNetwork parent
- * instance.
+ * @ptr: (in) (not optional): pointer to the #X2GoClientNetworkSSH instance.
* @gerr: (out) (nullable): a return location for a #GError, pass %NULL if not
* interested.
*
@@ -1415,13 +1398,13 @@ gboolean x2goclient_network_ssh_disconnect (X2GoClientNetworkSSH * const self, G
*
* Since: 0.0.0
*/
-static gboolean x2goclient_network_ssh_parent_disconnect (X2GoClientNetwork * const parent, GError ** const gerr) {
+static gboolean x2goclient_network_ssh_parent_disconnect (const gpointer ptr, GError ** const gerr) {
gboolean ret = FALSE;
- g_return_val_if_fail (X2GOCLIENT_IS_NETWORK_SSH (parent), ret);
+ g_return_val_if_fail (X2GOCLIENT_IS_NETWORK_SSH (ptr), ret);
g_return_val_if_fail (((NULL == gerr) || (NULL == *gerr)), ret);
- X2GoClientNetworkSSH *self = X2GOCLIENT_NETWORK_SSH (parent);
+ X2GoClientNetworkSSH *self = X2GOCLIENT_NETWORK_SSH (ptr);
/* Actual implementation here. */
diff --git a/src/x2goclient-network.c b/src/x2goclient-network.c
index 27cc6b2..64849b5 100644
--- a/src/x2goclient-network.c
+++ b/src/x2goclient-network.c
@@ -60,14 +60,36 @@
* Since: 0.0.0
*/
+/**
+ * X2GoClientNetworkClass:
+ * @connect: pointer to the current class's connect function, useful for
+ * derived classes. Check the in-line documentation within the class
+ * structure for further information.
+ * @derived_connect: pointer to the derived class's connect function, must be
+ * set manually by the derived class in its
+ * <code>class_init</code> function. Check the in-line
+ * documentation within the class structure for further
+ * information.
+ * @disconnect: pointer to the current class's disconnect function, useful for
+ * derived classes. Check the in-line documentation within the
+ * class structure for further information.
+ * @derived_disconnect: pointer to the derived class's disconnect function,
+ * must be set manually by the derived class in its
+ * <code>class_init</code> function. Check the in-line
+ * documentation within the class structure for further
+ * information.
+ *
+ * Virtual function table for #X2GoClientNetwork.
+ *
+ * Since: 0.0.0
+ */
+
typedef struct X2GoClientNetworkPrivate_ {
GString *socket_spec;
GSocketAddress *socket;
X2GoClientNetworkOptions *options;
gchar *session_path; /* Will eventually be replaced with a session object, probably. */
gboolean connected;
- x2goclient_network_connect_type connect_func;
- x2goclient_network_disconnect_type disconnect_func;
} X2GoClientNetworkPrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (X2GoClientNetwork, x2goclient_network, G_TYPE_OBJECT)
@@ -86,8 +108,6 @@ enum {
X2GO_NET_PROP_OPTIONS,
X2GO_NET_PROP_SESSION_PATH,
X2GO_NET_PROP_CONNECTED,
- X2GO_NET_PROP_CONN_FUNC,
- X2GO_NET_PROP_DISCONN_FUNC,
X2GO_NET_N_PROPERTIES
};
@@ -105,8 +125,10 @@ static void x2goclient_network_class_init (X2GoClientNetworkClass * const klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
/* Initialize class members. */
- klass->connect = NULL;
- klass->disconnect = NULL;
+ klass->connect = &x2goclient_network_connect;
+ klass->derived_connect = NULL;
+ klass->disconnect = &x2goclient_network_disconnect;
+ klass->derived_disconnect = NULL;
klass->parse_sockspec = NULL;
/*
@@ -218,54 +240,6 @@ static void x2goclient_network_class_init (X2GoClientNetworkClass * const klass)
FALSE,
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
- /**
- * X2GoClientNetwork:connect-function:
- *
- * This property holds a pointer to a pointer to the instance's connect
- * function.
- *
- * It is read-only.
- *
- * Use it to fetch the parent's connect function in derived classes.
- *
- * This property transfers ownership of the wrapping pointer - i.e., the
- * data returned by it - to the caller, who is responsible for freeing it.
- *
- * Since: 0.0.0
- */
- net_obj_properties[X2GO_NET_PROP_CONN_FUNC] = g_param_spec_pointer ("connect-function",
- _("Pointer to a pointer to this instance's connect function; "
- "the ownership of the wrapping pointer is transferred to the caller"),
- _("A pointer to a pointer to the instance's connect function. "
- "This is supposed to be immutable. "
- "The caller is responsible for freeing the wrapping pointer - i.e., "
- "the data returned by this property."),
- G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
-
- /**
- * X2GoClientNetwork:disconnect-function:
- *
- * This property holds a pointer to a pointer to the instance's disconnect
- * function.
- *
- * It is read-only.
- *
- * Use it to fetch the parent's disconnect function in derived classes.
- *
- * This property transfers ownership of the wrapping pointer - i.e., the
- * data returned by it - to the caller, who is responsible for freeing it.
- *
- * Since: 0.0.0
- */
- net_obj_properties[X2GO_NET_PROP_DISCONN_FUNC] = g_param_spec_pointer ("disconnect-function",
- _("Pointer to a pointer to this instance's disconnect function; "
- "the ownership of the wrapping pointer is transferred to the caller"),
- _("A pointer to the instance's disconnect function. "
- "This is supposed to be immutable. "
- "The caller is responsible for freeing the wrapping pointer - i.e., "
- "the data returned by this property."),
- G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
-
g_object_class_install_properties (object_class, X2GO_NET_N_PROPERTIES, net_obj_properties);
}
@@ -276,8 +250,6 @@ static void x2goclient_network_init (X2GoClientNetwork * const self) {
priv->options = NULL;
priv->session_path = NULL;
priv->connected = FALSE;
- priv->connect_func = &x2goclient_network_connect;
- priv->disconnect_func = &x2goclient_network_disconnect;
}
static void x2goclient_network_dispose (GObject * const object) {
@@ -299,9 +271,6 @@ static void x2goclient_network_finalize (GObject * const object) {
g_free (priv->session_path);
priv->session_path = NULL;
- priv->connect_func = NULL;
- priv->disconnect_func = NULL;
-
(G_OBJECT_CLASS (x2goclient_network_parent_class))->finalize (object);
}
@@ -336,19 +305,22 @@ static GSocketAddress* x2goclient_network_parse_sockspec (X2GoClientNetwork * co
/**
* x2goclient_network_connect:
- * @self: (in) (not optional): an #X2GoClientNetwork.
+ * @self: (in) (not optional): pointer to an #X2GoClientNetwork instance.
* @gerr: (out) (nullable): a return location for a #GError, pass %NULL if not
* interested.
*
* Connects to a remote location.
*
- * This function uses the #X2GoClientNetworkClass::connect virtual method to
- * actually connect. By default, this virtual method is unset (or rather, set
- * to %NULL). Make sure to probably initialize it in your derived class.
+ * This function uses the #X2GoClientNetworkClass::derived_connect virtual
+ * method to call down the inheritance chain. By default, this virtual method
+ * is unset (or rather, set to %NULL). Make sure to properly initialize it in
+ * your derived class.
+ * Derived classes are also supposed to move down the inheritance chain after
+ * running their implementation.
*
* This function is idempotent.
*
- * Returns: %TRUE if the connection was established successful or it is
+ * Returns: %TRUE if the connection was established successfully or it is
* already running, %FALSE on error.
*
* Since: 0.0.0
@@ -361,14 +333,15 @@ gboolean x2goclient_network_connect (X2GoClientNetwork * const self, GError ** c
g_return_val_if_fail (X2GOCLIENT_IS_NETWORK (self), ret);
g_return_val_if_fail (((NULL == gerr) || (NULL == *gerr)), ret);
- g_return_val_if_fail (class->connect, ret);
ret = priv->connected;
if (!(ret)) {
- ret = class->connect (self, gerr);
+ if (class->derived_connect) {
+ ret = class->derived_connect (self, gerr);
- priv->connected = ret;
+ priv->connected = ret;
+ }
}
return (ret);
@@ -376,16 +349,18 @@ gboolean x2goclient_network_connect (X2GoClientNetwork * const self, GError ** c
/**
* x2goclient_network_disconnect:
- * @self: (in) (not optional): an #X2GoClientNetwork.
+ * @self: (in) (not optional): pointer to an #X2GoClientNetwork instance.
* @gerr: (out) (nullable): a return location for a #GError, pass %NULL if not
* interested.
*
* Disconnects from a remote location.
*
- * This function uses the #X2GoClientNetworkClass::disconnect virtual method
- * to actually disconnect. By default, this virtual method is unset (or
- * rather, set to %NULL). Make sure to probably initialize it in your derived
- * class.
+ * This function uses the #X2GoClientNetworkClass::derived_disconnect virtual
+ * method to call down the inheritance chain. By default, this virtual method
+ * is unset (or rather, set to %NULL). Make sure to properly initialize it in
+ * your derived class.
+ * Derived classes are also supposed to move down the inheritance chain after
+ * running their implementation.
*
* This function is idempotent.
*
@@ -402,14 +377,15 @@ gboolean x2goclient_network_disconnect (X2GoClientNetwork * const self, GError *
g_return_val_if_fail (X2GOCLIENT_IS_NETWORK (self), ret);
g_return_val_if_fail (((NULL == gerr) || (NULL == *gerr)), ret);
- g_return_val_if_fail (class->disconnect, ret);
ret = (!(priv->connected));
if (!(ret)) {
- ret = class->disconnect (self, gerr);
+ if (class->derived_disconnect) {
+ ret = class->derived_disconnect (self, gerr);
- priv->connected = (!(ret));
+ priv->connected = (!(ret));
+ }
}
return (ret);
@@ -419,8 +395,6 @@ static void x2goclient_network_set_property (GObject * const object, guint prop_
X2GoClientNetwork *self = X2GOCLIENT_NETWORK (object);
X2GoClientNetworkPrivate *priv = x2goclient_network_get_instance_private (self);
- X2GoClientNetwork_connect_ref_type conn_ref = NULL;
- X2GoClientNetwork_disconnect_ref_type disconn_ref = NULL;
switch (prop_id) {
case (X2GO_NET_PROP_SOCKET_SPEC):
if (priv->socket_spec) {
@@ -445,32 +419,6 @@ static void x2goclient_network_set_property (GObject * const object, guint prop_
case (X2GO_NET_PROP_CONNECTED):
priv->connected = g_value_get_boolean (value);
break;
- case (X2GO_NET_PROP_CONN_FUNC):
- /* Fetch data pointer. */
- conn_ref = g_value_get_pointer (value);
-
- /* Set function pointer based on this data. */
- priv->connect_func = *(conn_ref);
-
- /*
- * And, importantly, get rid of the data.
- *
- * Note that this is strictly speaking a
- * violation of g_value_get_pointer ()'s
- * contract (being transfer_none), but we
- * explicitly transfer ownership, so it
- * should be fine in this case.
- */
- g_free (conn_ref);
- conn_ref = NULL;
- break;
- case (X2GO_NET_PROP_DISCONN_FUNC):
- /* Same as for CONN_FUNC. */
- disconn_ref = g_value_get_pointer (value);
- priv->disconnect_func = *(disconn_ref);
- g_free (disconn_ref);
- disconn_ref = NULL;
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, param_spec);
break;
@@ -481,8 +429,6 @@ static void x2goclient_network_get_property (GObject * const object, const guint
X2GoClientNetwork *self = X2GOCLIENT_NETWORK (object);
X2GoClientNetworkPrivate *priv = x2goclient_network_get_instance_private (self);
- X2GoClientNetwork_connect_ref_type conn_ref = NULL;
- X2GoClientNetwork_disconnect_ref_type disconn_ref = NULL;
switch (prop_id) {
case (X2GO_NET_PROP_SOCKET_SPEC):
g_value_set_boxed (value, priv->socket_spec);
@@ -499,28 +445,6 @@ static void x2goclient_network_get_property (GObject * const object, const guint
case (X2GO_NET_PROP_CONNECTED):
g_value_set_boolean (value, priv->connected);
break;
- case (X2GO_NET_PROP_CONN_FUNC):
- /*
- * Create and pass function pointer as
- * data.
- */
- conn_ref = g_new0 (x2goclient_network_connect_type, 1);
- *(conn_ref) = priv->connect_func;
- g_value_set_pointer (value, conn_ref);
-
- /*
- * Never free conn_ref here! It's the
- * caller's responsibility.
- */
- conn_ref = NULL;
- break;
- case (X2GO_NET_PROP_DISCONN_FUNC):
- /* Same as for CONN_FUNC. */
- disconn_ref = g_new0 (x2goclient_network_disconnect_type, 1);
- *(disconn_ref) = priv->disconnect_func;
- g_value_set_pointer (value, disconn_ref);
- disconn_ref = NULL;
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, param_spec);
break;
diff --git a/src/x2goclient-network.h b/src/x2goclient-network.h
index ea854cf..2660879 100644
--- a/src/x2goclient-network.h
+++ b/src/x2goclient-network.h
@@ -44,37 +44,94 @@ G_BEGIN_DECLS
#define X2GOCLIENT_TYPE_NETWORK (x2goclient_network_get_type ())
G_DECLARE_DERIVABLE_TYPE (X2GoClientNetwork, x2goclient_network, X2GOCLIENT, NETWORK, GObject)
-/*
- * Function (pointer) prototypes.
- *
- * We need the reference type because casting function pointers to object
- * pointers is illegal in ISO C. This isn't just an oversight in the standard,
- * but actually intended to keep developers from shooting themselves in the
- * foot.
- *
- * Function pointers and object pointers are not interchangeable. There are
- * platforms on which both have different sizes.
- *
- * Due to this, the only way to pass them around is through indirection -
- * i.e., the address of an object pointer.
- */
-typedef gboolean (*x2goclient_network_connect_type) (X2GoClientNetwork * const self, GError ** const gerr);
-typedef gboolean (*x2goclient_network_disconnect_type) (X2GoClientNetwork * const self, GError ** const gerr);
-#ifndef __GI_SCANNER__
-/*
- * We have to hide this until
- * https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/385 is
- * resolved.
- */
-typedef x2goclient_network_connect_type *X2GoClientNetwork_connect_ref_type;
-typedef x2goclient_network_disconnect_type *X2GoClientNetwork_disconnect_ref_type;
-#endif
-
struct _X2GoClientNetworkClass {
GObjectClass parent_class;
- x2goclient_network_connect_type connect;
- x2goclient_network_disconnect_type disconnect;
+ /**
+ * X2GoClientNetworkClass::connect:
+ * @self: (not optional): pointer to an #X2GoClientNetwork instance.
+ * @gerr: (out) (nullable): a return location for a #GError, pass %NULL if
+ * not interested.
+ *
+ * This is a pointer to the current class's connect function.
+ *
+ * Derived classes can use it to fetch their parent class's connect function
+ * for chaining up.
+ *
+ * In the top-level class, this function must implement its specifics and
+ * then chain down, while in lower-level classes, it must only chain up,
+ * without implementing any specifics or chaining down.
+ *
+ * Returns: %TRUE if the connection was established successfully or it is
+ * already running, %FALSE on error.
+ *
+ * Since: 0.0.0
+ */
+ gboolean (*connect) (X2GoClientNetwork * const self, GError ** const gerr);
+
+ /**
+ * X2GoClientNetworkClass::derived_connect:
+ * @ptr: (not optional): pointer to a derived instance.
+ * @gerr: (out) (nullable): a return location for a #GError, pass %NULL if
+ * not interested.
+ *
+ * This is a pointer to the derived class's connect function.
+ *
+ * Derived classes should set it to their actual public connect
+ * implementation in their <code>class_init</code> function.
+ *
+ * This function must implement its specifics and then chain down, unless it
+ * is at the bottom of its hierarchy.
+ *
+ * Returns: %TRUE if the connection was established successfully or it is
+ * already running, %FALSE on error.
+ *
+ * Since: 0.0.0
+ */
+ gboolean (*derived_connect) (const gpointer ptr, GError ** const gerr);
+
+ /**
+ * X2GoClientNetworkClass::disconnect:
+ * @self: (not optional): pointer to an #X2GoClientNetwork instance.
+ * @gerr: (out) (nullable): a return location for a #GError, pass %NULL if
+ * not interested.
+ *
+ * This is a pointer to the current class's disconnect function.
+ *
+ * Derived classes can use it to fetch their parent class's disconnect
+ * function for chaining up.
+ *
+ * In the top-level class, this function must implement its specifics and
+ * then chain down, while in lower-level classes, it must only chain up,
+ * without implementing any specifics or chaining down.
+ *
+ * Returns: %TRUE if the connection was successfully destroyed or there was
+ * none to begin with, %FALSE on error.
+ *
+ * Since: 0.0.0
+ */
+ gboolean (*disconnect) (X2GoClientNetwork * const self, GError ** const gerr);
+
+ /**
+ * X2GoClientNetworkClass::derived_disconnect:
+ * @ptr: (not optional): pointer to a derived instance.
+ * @gerr: (out) (nullable): a return location for a #GError, pass %NULL if
+ * not interested.
+ *
+ * This is a pointer to the derived class's disconnect function.
+ *
+ * Derived classes should set it to their actual public disconnect
+ * implementation in their <code>class_init</code> function.
+ *
+ * This function must implement its specifics and then chain down, unless it
+ * is at the bottom of its hierarchy.
+ *
+ * Returns: %TRUE if the connection was successfully destroyed or there was
+ * none to begin with, %FALSE on error.
+ *
+ * Since: 0.0.0
+ */
+ gboolean (*derived_disconnect) (const gpointer ptr, GError ** const gerr);
/*< private >*/
GSocketAddress* (*parse_sockspec) (X2GoClientNetwork * const self, const GString * const sockspec);
--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/libx2goclient.git
More information about the x2go-commits
mailing list