qulogic/pidgin

Parents c5bcc44520c3
Children 6dcf672547fe
Add a cancellable property to PurpleConnection and port IRCv3 to it

As more and more of our protocols start using Gio, it just makes sense to have
a cancellable ready for them.

Testing Done:
Connected, disconnected, and reconnected and IRCv3 account without issue.

Reviewed at https://reviews.imfreedom.org/r/2864/
--- a/libpurple/connection.c Mon Dec 04 01:59:11 2023 -0600
+++ b/libpurple/connection.c Mon Dec 04 02:13:29 2023 -0600
@@ -46,6 +46,8 @@
gchar *id;
+ GCancellable *cancellable;
+
PurpleProtocol *protocol; /* The protocol. */
PurpleConnectionFlags flags; /* Connection flags. */
@@ -81,6 +83,7 @@
enum {
PROP_0,
PROP_ID,
+ PROP_CANCELLABLE,
PROP_PROTOCOL,
PROP_FLAGS,
PROP_STATE,
@@ -715,6 +718,12 @@
priv = purple_connection_get_instance_private(connection);
+ /* Tell everyone we're shutting down. */
+ if(G_IS_CANCELLABLE(priv->cancellable)) {
+ g_cancellable_cancel(priv->cancellable);
+ g_clear_object(&priv->cancellable);
+ }
+
purple_protocol_close(priv->protocol, connection);
return TRUE;
@@ -773,6 +782,10 @@
case PROP_ID:
g_value_set_string(value, purple_connection_get_id(connection));
break;
+ case PROP_CANCELLABLE:
+ g_value_set_object(value,
+ purple_connection_get_cancellable(connection));
+ break;
case PROP_PROTOCOL:
g_value_set_object(value,
purple_connection_get_protocol(connection));
@@ -803,6 +816,12 @@
static void
purple_connection_init(PurpleConnection *connection) {
+ PurpleConnectionPrivate *priv = NULL;
+
+ priv = purple_connection_get_instance_private(connection);
+
+ priv->cancellable = g_cancellable_new();
+
purple_connection_set_state(connection, PURPLE_CONNECTION_STATE_CONNECTING);
connections = g_list_append(connections, connection);
}
@@ -855,6 +874,8 @@
g_free(priv->display_name);
g_free(priv->id);
+ g_clear_object(&priv->cancellable);
+
G_OBJECT_CLASS(purple_connection_parent_class)->finalize(object);
}
@@ -877,6 +898,22 @@
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ /**
+ * PurpleConnection:cancellable:
+ *
+ * A [class@Gio.Cancellable] to be used with the connection.
+ *
+ * This can be passed function that require a cancellable for the
+ * connection.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_CANCELLABLE] = g_param_spec_object(
+ "cancellable", "cancellable",
+ "A cancellable for the connection.",
+ G_TYPE_CANCELLABLE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
properties[PROP_PROTOCOL] = g_param_spec_object(
"protocol", "Protocol",
"The protocol that the connection is using.",
@@ -1035,6 +1072,17 @@
return ret;
}
+GCancellable *
+purple_connection_get_cancellable(PurpleConnection *connection) {
+ PurpleConnectionPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_CONNECTION(connection), NULL);
+
+ priv = purple_connection_get_instance_private(connection);
+
+ return priv->cancellable;
+}
+
/**************************************************************************
* Connections API
**************************************************************************/
--- a/libpurple/connection.h Mon Dec 04 01:59:11 2023 -0600
+++ b/libpurple/connection.h Mon Dec 04 02:13:29 2023 -0600
@@ -390,6 +390,19 @@
void purple_connection_set_password(PurpleConnection *connection, const char *password);
/**
+ * purple_connection_get_cancellable:
+ * @connection: The instance.
+ *
+ * Gets the cancellable that should be used with @connection.
+ *
+ * Returns: (transfer none): The cancellable.
+ *
+ * Since: 3.0.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+GCancellable *purple_connection_get_cancellable(PurpleConnection *connection);
+
+/**
* purple_connection_get_active_chats:
* @gc: The connection.
*
--- a/libpurple/protocols/ircv3/purpleircv3connection.c Mon Dec 04 01:59:11 2023 -0600
+++ b/libpurple/protocols/ircv3/purpleircv3connection.c Mon Dec 04 02:13:29 2023 -0600
@@ -27,7 +27,6 @@
enum {
PROP_0,
- PROP_CANCELLABLE,
PROP_CAPABILITIES,
PROP_REGISTERED,
N_PROPERTIES,
@@ -44,7 +43,6 @@
typedef struct {
GSocketConnection *connection;
- GCancellable *cancellable;
gchar *server_name;
gboolean registered;
@@ -155,6 +153,7 @@
{
PurpleIRCv3Connection *connection = data;
PurpleIRCv3ConnectionPrivate *priv = NULL;
+ GCancellable *cancellable = NULL;
GDataInputStream *istream = G_DATA_INPUT_STREAM(source);
GError *error = NULL;
gchar *line = NULL;
@@ -195,9 +194,10 @@
g_free(line);
/* Call read_line_async again to continue reading lines. */
+ cancellable = purple_connection_get_cancellable(PURPLE_CONNECTION(connection));
g_data_input_stream_read_line_async(priv->input,
G_PRIORITY_DEFAULT,
- priv->cancellable,
+ cancellable,
purple_ircv3_connection_read_cb,
connection);
}
@@ -231,6 +231,7 @@
{
PurpleIRCv3Connection *connection = data;
PurpleIRCv3ConnectionPrivate *priv = NULL;
+ GCancellable *cancellable = NULL;
GError *error = NULL;
GInputStream *istream = NULL;
GOutputStream *ostream = NULL;
@@ -266,10 +267,12 @@
g_data_input_stream_set_newline_type(G_DATA_INPUT_STREAM(priv->input),
G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
+ cancellable = purple_connection_get_cancellable(PURPLE_CONNECTION(connection));
+
/* Add our read callback. */
g_data_input_stream_read_line_async(priv->input,
G_PRIORITY_DEFAULT,
- priv->cancellable,
+ cancellable,
purple_ircv3_connection_read_cb,
connection);
@@ -309,6 +312,7 @@
PurpleIRCv3Connection *connection = NULL;
PurpleIRCv3ConnectionPrivate *priv = NULL;
PurpleAccount *account = NULL;
+ GCancellable *cancellable = NULL;
GSocketClient *client = NULL;
gint default_port = PURPLE_IRCV3_DEFAULT_TLS_PORT;
gint port = 0;
@@ -339,9 +343,11 @@
}
port = purple_account_get_int(account, "port", default_port);
+ cancellable = purple_connection_get_cancellable(purple_connection);
+
/* Finally start the async connection. */
g_socket_client_connect_to_host_async(client, priv->server_name,
- port, priv->cancellable,
+ port, cancellable,
purple_ircv3_connection_connected_cb,
connection);
@@ -352,25 +358,23 @@
static gboolean
purple_ircv3_connection_disconnect(PurpleConnection *purple_connection,
- G_GNUC_UNUSED GError **error)
+ GError **error)
{
PurpleIRCv3Connection *connection = NULL;
PurpleIRCv3ConnectionPrivate *priv = NULL;
+ PurpleConnectionClass *parent_class = NULL;
g_return_val_if_fail(PURPLE_IRCV3_IS_CONNECTION(purple_connection), FALSE);
+ /* Chain up to our parent's disconnect to do initial clean up. */
+ parent_class = PURPLE_CONNECTION_CLASS(purple_ircv3_connection_parent_class);
+ parent_class->disconnect(purple_connection, error);
+
connection = PURPLE_IRCV3_CONNECTION(purple_connection);
priv = purple_ircv3_connection_get_instance_private(connection);
/* TODO: send QUIT command. */
- /* Cancel the cancellable to tell everyone we're shutting down. */
- if(G_IS_CANCELLABLE(priv->cancellable)) {
- g_cancellable_cancel(priv->cancellable);
-
- g_clear_object(&priv->cancellable);
- }
-
if(G_IS_SOCKET_CONNECTION(priv->connection)) {
GInputStream *istream = G_INPUT_STREAM(priv->input);
GOutputStream *ostream = G_OUTPUT_STREAM(priv->output);
@@ -406,10 +410,6 @@
PurpleIRCv3Connection *connection = PURPLE_IRCV3_CONNECTION(obj);
switch(param_id) {
- case PROP_CANCELLABLE:
- g_value_set_object(value,
- purple_ircv3_connection_get_cancellable(connection));
- break;
case PROP_CAPABILITIES:
g_value_set_object(value,
purple_ircv3_connection_get_capabilities(connection));
@@ -431,8 +431,6 @@
priv = purple_ircv3_connection_get_instance_private(connection);
- g_clear_object(&priv->cancellable);
-
g_clear_object(&priv->input);
g_clear_object(&priv->output);
g_clear_object(&priv->connection);
@@ -512,8 +510,6 @@
g_clear_pointer(&title, g_free);
/* Finally create our objects. */
- priv->cancellable = g_cancellable_new();
-
priv->capabilities = purple_ircv3_capabilities_new(connection);
g_signal_connect_object(priv->capabilities, "done",
G_CALLBACK(purple_ircv3_connection_caps_done_cb),
@@ -542,19 +538,6 @@
connection_class->disconnect = purple_ircv3_connection_disconnect;
/**
- * PurpleIRCv3Connection:cancellable:
- *
- * The [class@Gio.Cancellable] for this connection.
- *
- * Since: 3.0.0
- */
- properties[PROP_CANCELLABLE] = g_param_spec_object(
- "cancellable", "cancellable",
- "The cancellable for this connection",
- G_TYPE_CANCELLABLE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
- /**
* PurpleIRCv3Connection:capabilities:
*
* The capabilities that the server supports.
@@ -676,17 +659,6 @@
g_type_class_unref(hack);
}
-GCancellable *
-purple_ircv3_connection_get_cancellable(PurpleIRCv3Connection *connection) {
- PurpleIRCv3ConnectionPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection), NULL);
-
- priv = purple_ircv3_connection_get_instance_private(connection);
-
- return priv->cancellable;
-}
-
void
purple_ircv3_connection_emit_ctcp_request(PurpleIRCv3Connection *connection,
const char *command,
@@ -720,6 +692,7 @@
{
PurpleIRCv3ConnectionPrivate *priv = NULL;
GBytes *bytes = NULL;
+ GCancellable *cancellable = NULL;
GString *msg = NULL;
va_list vargs;
@@ -740,9 +713,11 @@
/* Finally turn the string into bytes and send it! */
bytes = g_string_free_to_bytes(msg);
+
+ cancellable = purple_connection_get_cancellable(PURPLE_CONNECTION(connection));
purple_queued_output_stream_push_bytes_async(priv->output, bytes,
G_PRIORITY_DEFAULT,
- priv->cancellable,
+ cancellable,
purple_ircv3_connection_write_cb,
connection);
--- a/libpurple/protocols/ircv3/purpleircv3connection.h Mon Dec 04 01:59:11 2023 -0600
+++ b/libpurple/protocols/ircv3/purpleircv3connection.h Mon Dec 04 02:13:29 2023 -0600
@@ -63,18 +63,6 @@
G_GNUC_INTERNAL void purple_ircv3_connection_register(GPluginNativePlugin *plugin);
/**
- * purple_ircv3_connection_get_cancellable: (skip)
- * @connection: The instance.
- *
- * This is a private method that is not exposed externally.
- *
- * Gets the cancellable for @connection.
- *
- * Since: 3.0.0
- */
-G_GNUC_INTERNAL GCancellable *purple_ircv3_connection_get_cancellable(PurpleIRCv3Connection *connection);
-
-/**
* purple_ircv3_connection_emit_ctcp_request:
* @connection: The instance.
* @command: The CTCP command.