summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbus-connection-internal.h6
-rw-r--r--dbus/dbus-connection.c73
-rw-r--r--dbus/dbus-connection.h51
-rw-r--r--dbus/dbus-server-protected.h16
-rw-r--r--dbus/dbus-server-unix.c3
-rw-r--r--dbus/dbus-server.c45
-rw-r--r--dbus/dbus-server.h2
-rw-r--r--dbus/dbus-timeout.c50
-rw-r--r--dbus/dbus-timeout.h4
-rw-r--r--dbus/dbus-transport-debug.c9
-rw-r--r--dbus/dbus-transport-protected.h2
-rw-r--r--dbus/dbus-transport-unix.c166
-rw-r--r--dbus/dbus-transport.c8
-rw-r--r--dbus/dbus-transport.h2
-rw-r--r--dbus/dbus-watch.c52
-rw-r--r--dbus/dbus-watch.h8
16 files changed, 343 insertions, 154 deletions
diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h
index 64c4cf39..4d3ed130 100644
--- a/dbus/dbus-connection-internal.h
+++ b/dbus/dbus-connection-internal.h
@@ -55,10 +55,16 @@ dbus_bool_t _dbus_connection_add_watch (DBusConnection *connect
DBusWatch *watch);
void _dbus_connection_remove_watch (DBusConnection *connection,
DBusWatch *watch);
+void _dbus_connection_toggle_watch (DBusConnection *connection,
+ DBusWatch *watch,
+ dbus_bool_t enabled);
dbus_bool_t _dbus_connection_add_timeout (DBusConnection *connection,
DBusTimeout *timeout);
void _dbus_connection_remove_timeout (DBusConnection *connection,
DBusTimeout *timeout);
+void _dbus_connection_toggle_timeout (DBusConnection *connection,
+ DBusTimeout *timeout,
+ dbus_bool_t enabled);
DBusConnection* _dbus_connection_new_for_transport (DBusTransport *transport);
void _dbus_connection_do_iteration (DBusConnection *connection,
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index c5df5611..780c410f 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -331,6 +331,25 @@ _dbus_connection_remove_watch (DBusConnection *connection,
}
/**
+ * Toggles a watch and notifies app via connection's
+ * DBusWatchToggledFunction if available. It's an error to call this
+ * function on a watch that was not previously added.
+ *
+ * @param connection the connection.
+ * @param timeout the timeout to toggle.
+ * @param enabled whether to enable or disable
+ */
+void
+_dbus_connection_toggle_watch (DBusConnection *connection,
+ DBusWatch *watch,
+ dbus_bool_t enabled)
+{
+ if (connection->watches) /* null during finalize */
+ _dbus_watch_list_toggle_watch (connection->watches,
+ watch, enabled);
+}
+
+/**
* Adds a timeout using the connection's DBusAddTimeoutFunction if
* available. Otherwise records the timeout to be added when said
* function is available. Also re-adds the timeout if the
@@ -378,6 +397,24 @@ _dbus_connection_remove_timeout_locked (DBusConnection *connection,
dbus_mutex_unlock (connection->mutex);
}
+/**
+ * Toggles a timeout and notifies app via connection's
+ * DBusTimeoutToggledFunction if available. It's an error to call this
+ * function on a timeout that was not previously added.
+ *
+ * @param connection the connection.
+ * @param timeout the timeout to toggle.
+ * @param enabled whether to enable or disable
+ */
+void
+_dbus_connection_toggle_timeout (DBusConnection *connection,
+ DBusTimeout *timeout,
+ dbus_bool_t enabled)
+{
+ if (connection->timeouts) /* null during finalize */
+ _dbus_timeout_list_toggle_timeout (connection->timeouts,
+ timeout, enabled);
+}
/**
* Tells the connection that the transport has been disconnected.
@@ -598,8 +635,10 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
connection->disconnect_message_link = disconnect_link;
- _dbus_transport_ref (transport);
- _dbus_transport_set_connection (transport, connection);
+ if (!_dbus_transport_set_connection (transport, connection))
+ goto error;
+
+ _dbus_transport_ref (transport);
return connection;
@@ -1793,8 +1832,18 @@ dbus_connection_dispatch_message (DBusConnection *connection)
* poll(). When using Qt, typically the DBusAddWatchFunction would
* create a QSocketNotifier. When using GLib, the DBusAddWatchFunction
* could call g_io_add_watch(), or could be used as part of a more
- * elaborate GSource.
- *
+ * elaborate GSource. Note that when a watch is added, it may
+ * not be enabled.
+ *
+ * The DBusWatchToggledFunction notifies the application that the
+ * watch has been enabled or disabled. Call dbus_watch_get_enabled()
+ * to check this. A disabled watch should have no effect, and enabled
+ * watch should be added to the main loop. This feature is used
+ * instead of simply adding/removing the watch because
+ * enabling/disabling can be done without memory allocation. The
+ * toggled function may be NULL if a main loop re-queries
+ * dbus_watch_get_enabled() every time anyway.
+ *
* The DBusWatch can be queried for the file descriptor to watch using
* dbus_watch_get_fd(), and for the events to watch for using
* dbus_watch_get_flags(). The flags returned by
@@ -1825,6 +1874,7 @@ dbus_connection_dispatch_message (DBusConnection *connection)
* @param connection the connection.
* @param add_function function to begin monitoring a new descriptor.
* @param remove_function function to stop monitoring a descriptor.
+ * @param toggled_function function to notify of enable/disable
* @param data data to pass to add_function and remove_function.
* @param free_data_function function to be called to free the data.
* @returns #FALSE on failure (no memory)
@@ -1833,6 +1883,7 @@ dbus_bool_t
dbus_connection_set_watch_functions (DBusConnection *connection,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
+ DBusWatchToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function)
{
@@ -1844,6 +1895,7 @@ dbus_connection_set_watch_functions (DBusConnection *connection,
retval = _dbus_watch_list_set_functions (connection->watches,
add_function, remove_function,
+ toggled_function,
data, free_data_function);
dbus_mutex_unlock (connection->mutex);
@@ -1859,6 +1911,16 @@ dbus_connection_set_watch_functions (DBusConnection *connection,
* When using Qt, typically the DBusAddTimeoutFunction would create a
* QTimer. When using GLib, the DBusAddTimeoutFunction would call
* g_timeout_add.
+ *
+ * The DBusTimeoutToggledFunction notifies the application that the
+ * timeout has been enabled or disabled. Call
+ * dbus_timeout_get_enabled() to check this. A disabled timeout should
+ * have no effect, and enabled timeout should be added to the main
+ * loop. This feature is used instead of simply adding/removing the
+ * timeout because enabling/disabling can be done without memory
+ * allocation. With Qt, QTimer::start() and QTimer::stop() can be used
+ * to enable and disable. The toggled function may be NULL if a main
+ * loop re-queries dbus_timeout_get_enabled() every time anyway.
*
* The DBusTimeout can be queried for the timer interval using
* dbus_timeout_get_interval(). dbus_timeout_handle() should
@@ -1869,6 +1931,7 @@ dbus_connection_set_watch_functions (DBusConnection *connection,
* @param connection the connection.
* @param add_function function to add a timeout.
* @param remove_function function to remove a timeout.
+ * @param toggled_function function to notify of enable/disable
* @param data data to pass to add_function and remove_function.
* @param free_data_function function to be called to free the data.
* @returns #FALSE on failure (no memory)
@@ -1877,6 +1940,7 @@ dbus_bool_t
dbus_connection_set_timeout_functions (DBusConnection *connection,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
+ DBusTimeoutToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function)
{
@@ -1888,6 +1952,7 @@ dbus_connection_set_timeout_functions (DBusConnection *connection,
retval = _dbus_timeout_list_set_functions (connection->timeouts,
add_function, remove_function,
+ toggled_function,
data, free_data_function);
dbus_mutex_unlock (connection->mutex);
diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h
index bf0983e6..78a8d58c 100644
--- a/dbus/dbus-connection.h
+++ b/dbus/dbus-connection.h
@@ -56,15 +56,19 @@ typedef enum
* can be present in current state). */
} DBusWatchFlags;
-typedef dbus_bool_t (* DBusAddWatchFunction) (DBusWatch *watch,
- void *data);
-typedef void (* DBusRemoveWatchFunction) (DBusWatch *watch,
- void *data);
-typedef void (* DBusWakeupMainFunction) (void *data);
-typedef dbus_bool_t (* DBusAddTimeoutFunction) (DBusTimeout *timeout,
- void *data);
-typedef void (* DBusRemoveTimeoutFunction) (DBusTimeout *timeout,
- void *data);
+typedef dbus_bool_t (* DBusAddWatchFunction) (DBusWatch *watch,
+ void *data);
+typedef void (* DBusWatchToggledFunction) (DBusWatch *watch,
+ void *data);
+typedef void (* DBusRemoveWatchFunction) (DBusWatch *watch,
+ void *data);
+typedef void (* DBusWakeupMainFunction) (void *data);
+typedef dbus_bool_t (* DBusAddTimeoutFunction) (DBusTimeout *timeout,
+ void *data);
+typedef void (* DBusTimeoutToggledFunction) (DBusTimeout *timeout,
+ void *data);
+typedef void (* DBusRemoveTimeoutFunction) (DBusTimeout *timeout,
+ void *data);
DBusConnection* dbus_connection_open (const char *address,
DBusResultCode *result);
@@ -100,11 +104,13 @@ DBusMessage *dbus_connection_send_with_reply_and_block (DBusConnection *conn
dbus_bool_t dbus_connection_set_watch_functions (DBusConnection *connection,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
+ DBusWatchToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function);
dbus_bool_t dbus_connection_set_timeout_functions (DBusConnection *connection,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
+ DBusTimeoutToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function);
void dbus_connection_set_wakeup_main_function (DBusConnection *connection,
@@ -118,20 +124,21 @@ void dbus_connection_handle_watch (DBusConnection
-int dbus_watch_get_fd (DBusWatch *watch);
-unsigned int dbus_watch_get_flags (DBusWatch *watch);
-void* dbus_watch_get_data (DBusWatch *watch);
-void dbus_watch_set_data (DBusWatch *watch,
- void *data,
- DBusFreeFunction free_data_function);
-
-int dbus_timeout_get_interval (DBusTimeout *timeout);
-void* dbus_timeout_get_data (DBusTimeout *timeout);
-void dbus_timeout_set_data (DBusTimeout *timeout,
- void *data,
- DBusFreeFunction free_data_function);
-void dbus_timeout_handle (DBusTimeout *timeout);
+int dbus_watch_get_fd (DBusWatch *watch);
+unsigned int dbus_watch_get_flags (DBusWatch *watch);
+void* dbus_watch_get_data (DBusWatch *watch);
+void dbus_watch_set_data (DBusWatch *watch,
+ void *data,
+ DBusFreeFunction free_data_function);
+dbus_bool_t dbus_watch_get_enabled (DBusWatch *watch);
+int dbus_timeout_get_interval (DBusTimeout *timeout);
+void* dbus_timeout_get_data (DBusTimeout *timeout);
+void dbus_timeout_set_data (DBusTimeout *timeout,
+ void *data,
+ DBusFreeFunction free_data_function);
+void dbus_timeout_handle (DBusTimeout *timeout);
+dbus_bool_t dbus_timeout_get_enabled (DBusTimeout *timeout);
/* Handlers */
dbus_bool_t dbus_connection_add_filter (DBusConnection *connection,
diff --git a/dbus/dbus-server-protected.h b/dbus/dbus-server-protected.h
index 24b805c4..bbedeea3 100644
--- a/dbus/dbus-server-protected.h
+++ b/dbus/dbus-server-protected.h
@@ -78,16 +78,22 @@ struct DBusServer
};
dbus_bool_t _dbus_server_init_base (DBusServer *server,
- const DBusServerVTable *vtable);
+ const DBusServerVTable *vtable);
void _dbus_server_finalize_base (DBusServer *server);
dbus_bool_t _dbus_server_add_watch (DBusServer *server,
- DBusWatch *watch);
+ DBusWatch *watch);
void _dbus_server_remove_watch (DBusServer *server,
- DBusWatch *watch);
+ DBusWatch *watch);
+void _dbus_server_toggle_watch (DBusServer *server,
+ DBusWatch *watch,
+ dbus_bool_t enabled);
dbus_bool_t _dbus_server_add_timeout (DBusServer *server,
- DBusTimeout *timeout);
+ DBusTimeout *timeout);
void _dbus_server_remove_timeout (DBusServer *server,
- DBusTimeout *timeout);
+ DBusTimeout *timeout);
+void _dbus_server_toggle_timeout (DBusServer *server,
+ DBusTimeout *timeout,
+ dbus_bool_t enabled);
diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c
index 0a98c53c..a181a925 100644
--- a/dbus/dbus-server-unix.c
+++ b/dbus/dbus-server-unix.c
@@ -204,7 +204,8 @@ _dbus_server_new_for_fd (int fd)
DBusWatch *watch;
watch = _dbus_watch_new (fd,
- DBUS_WATCH_READABLE);
+ DBUS_WATCH_READABLE,
+ TRUE);
if (watch == NULL)
return NULL;
diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c
index 80ee6fc2..48703e17 100644
--- a/dbus/dbus-server.c
+++ b/dbus/dbus-server.c
@@ -146,6 +146,25 @@ _dbus_server_remove_watch (DBusServer *server,
}
/**
+ * Toggles a watch and notifies app via server's
+ * DBusWatchToggledFunction if available. It's an error to call this
+ * function on a watch that was not previously added.
+ *
+ * @param server the server.
+ * @param timeout the timeout to toggle.
+ * @param enabled whether to enable or disable
+ */
+void
+_dbus_server_toggle_watch (DBusServer *server,
+ DBusWatch *watch,
+ dbus_bool_t enabled)
+{
+ if (server->watches) /* null during finalize */
+ _dbus_watch_list_toggle_watch (server->watches,
+ watch, enabled);
+}
+
+/**
* Adds a timeout for this server, chaining out to
* application-provided timeout handlers. The timeout should be
* repeatedly handled with dbus_timeout_handle() at its given interval
@@ -174,6 +193,26 @@ _dbus_server_remove_timeout (DBusServer *server,
_dbus_timeout_list_remove_timeout (server->timeouts, timeout);
}
+/**
+ * Toggles a timeout and notifies app via server's
+ * DBusTimeoutToggledFunction if available. It's an error to call this
+ * function on a timeout that was not previously added.
+ *
+ * @param server the server.
+ * @param timeout the timeout to toggle.
+ * @param enabled whether to enable or disable
+ */
+void
+_dbus_server_toggle_timeout (DBusServer *server,
+ DBusTimeout *timeout,
+ dbus_bool_t enabled)
+{
+ if (server->timeouts) /* null during finalize */
+ _dbus_timeout_list_toggle_timeout (server->timeouts,
+ timeout, enabled);
+}
+
+
/** @} */
/**
@@ -405,6 +444,7 @@ dbus_server_set_new_connection_function (DBusServer *server,
* @param server the server.
* @param add_function function to begin monitoring a new descriptor.
* @param remove_function function to stop monitoring a descriptor.
+ * @param toggled_function function to notify when the watch is enabled/disabled
* @param data data to pass to add_function and remove_function.
* @param free_data_function function to be called to free the data.
* @returns #FALSE on failure (no memory)
@@ -413,12 +453,14 @@ dbus_bool_t
dbus_server_set_watch_functions (DBusServer *server,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
+ DBusWatchToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function)
{
return _dbus_watch_list_set_functions (server->watches,
add_function,
remove_function,
+ toggled_function,
data,
free_data_function);
}
@@ -433,6 +475,7 @@ dbus_server_set_watch_functions (DBusServer *server,
* @param server the server.
* @param add_function function to add a timeout.
* @param remove_function function to remove a timeout.
+ * @param toggled_function function to notify when the timeout is enabled/disabled
* @param data data to pass to add_function and remove_function.
* @param free_data_function function to be called to free the data.
* @returns #FALSE on failure (no memory)
@@ -441,11 +484,13 @@ dbus_bool_t
dbus_server_set_timeout_functions (DBusServer *server,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
+ DBusTimeoutToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function)
{
return _dbus_timeout_list_set_functions (server->timeouts,
add_function, remove_function,
+ toggled_function,
data, free_data_function);
}
diff --git a/dbus/dbus-server.h b/dbus/dbus-server.h
index 6665335b..589237f1 100644
--- a/dbus/dbus-server.h
+++ b/dbus/dbus-server.h
@@ -52,11 +52,13 @@ void dbus_server_set_new_connection_function (DBusServer *
dbus_bool_t dbus_server_set_watch_functions (DBusServer *server,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
+ DBusWatchToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function);
dbus_bool_t dbus_server_set_timeout_functions (DBusServer *server,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
+ DBusTimeoutToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function);
void dbus_server_handle_watch (DBusServer *server,
diff --git a/dbus/dbus-timeout.c b/dbus/dbus-timeout.c
index 09e54b31..9825872e 100644
--- a/dbus/dbus-timeout.c
+++ b/dbus/dbus-timeout.c
@@ -44,6 +44,7 @@ struct DBusTimeout
void *data; /**< Application data. */
DBusFreeFunction free_data_function; /**< Free the application data. */
+ unsigned int enabled : 1; /**< True if timeout is active. */
};
/**
@@ -69,6 +70,8 @@ _dbus_timeout_new (int interval,
timeout->handler = handler;
timeout->handler_data = data;
timeout->free_handler_data_function = free_data_function;
+
+ timeout->enabled = TRUE;
return timeout;
}
@@ -130,6 +133,7 @@ struct DBusTimeoutList
DBusAddTimeoutFunction add_timeout_function; /**< Callback for adding a timeout. */
DBusRemoveTimeoutFunction remove_timeout_function; /**< Callback for removing a timeout. */
+ DBusTimeoutToggledFunction timeout_toggled_function; /**< Callback when timeout is enabled/disabled */
void *timeout_data; /**< Data for timeout callbacks */
DBusFreeFunction timeout_free_data_function; /**< Free function for timeout callback data */
};
@@ -162,7 +166,7 @@ _dbus_timeout_list_free (DBusTimeoutList *timeout_list)
{
/* free timeout_data and remove timeouts as a side effect */
_dbus_timeout_list_set_functions (timeout_list,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
_dbus_list_foreach (&timeout_list->timeouts,
(DBusForeachFunction) _dbus_timeout_unref,
@@ -179,6 +183,7 @@ _dbus_timeout_list_free (DBusTimeoutList *timeout_list)
* @param timeout_list the timeout list
* @param add_function the add timeout function.
* @param remove_function the remove timeout function.
+ * @param toggled_function toggle notify function, or #NULL
* @param data the data for those functions.
* @param free_data_function the function to free the data.
* @returns #FALSE if no memory
@@ -188,6 +193,7 @@ dbus_bool_t
_dbus_timeout_list_set_functions (DBusTimeoutList *timeout_list,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
+ DBusTimeoutToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function)
{
@@ -239,6 +245,7 @@ _dbus_timeout_list_set_functions (DBusTimeoutList *timeout_list,
timeout_list->add_timeout_function = add_function;
timeout_list->remove_timeout_function = remove_function;
+ timeout_list->timeout_toggled_function = toggled_function;
timeout_list->timeout_data = data;
timeout_list->timeout_free_data_function = free_data_function;
@@ -297,6 +304,31 @@ _dbus_timeout_list_remove_timeout (DBusTimeoutList *timeout_list,
_dbus_timeout_unref (timeout);
}
+/**
+ * Sets a timeout to the given enabled state, invoking the
+ * application's DBusTimeoutToggledFunction if appropriate.
+ *
+ * @param timeout_list the timeout list.
+ * @param timeout the timeout to toggle.
+ * @param enabled #TRUE to enable
+ */
+void
+_dbus_timeout_list_toggle_timeout (DBusTimeoutList *timeout_list,
+ DBusTimeout *timeout,
+ dbus_bool_t enabled)
+{
+ enabled = !!enabled;
+
+ if (enabled == timeout->enabled)
+ return;
+
+ timeout->enabled = enabled;
+
+ if (timeout_list->timeout_toggled_function != NULL)
+ (* timeout_list->timeout_toggled_function) (timeout,
+ timeout_list->timeout_data);
+}
+
/** @} */
/**
@@ -380,3 +412,19 @@ dbus_timeout_handle (DBusTimeout *timeout)
{
(* timeout->handler) (timeout->handler_data);
}
+
+
+/**
+ * Returns whether a timeout is enabled or not. If not
+ * enabled, it should not be polled by the main loop.
+ *
+ * @param timeout the DBusTimeout object
+ * @returns #TRUE if the timeout is enabled
+ */
+dbus_bool_t
+dbus_timeout_get_enabled (DBusTimeout *timeout)
+{
+ return timeout->enabled;
+}
+
+/** @} end public API docs */
diff --git a/dbus/dbus-timeout.h b/dbus/dbus-timeout.h
index 2d7112a7..0ff5dc56 100644
--- a/dbus/dbus-timeout.h
+++ b/dbus/dbus-timeout.h
@@ -46,12 +46,16 @@ void _dbus_timeout_list_free (DBusTimeoutList *t
dbus_bool_t _dbus_timeout_list_set_functions (DBusTimeoutList *timeout_list,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
+ DBusTimeoutToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function);
dbus_bool_t _dbus_timeout_list_add_timeout (DBusTimeoutList *timeout_list,
DBusTimeout *timeout);
void _dbus_timeout_list_remove_timeout (DBusTimeoutList *timeout_list,
DBusTimeout *timeout);
+void _dbus_timeout_list_toggle_timeout (DBusTimeoutList *timeout_list,
+ DBusTimeout *timeout,
+ dbus_bool_t enabled);
DBUS_END_DECLS;
diff --git a/dbus/dbus-transport-debug.c b/dbus/dbus-transport-debug.c
index 42d1efdc..a7db3a6e 100644
--- a/dbus/dbus-transport-debug.c
+++ b/dbus/dbus-transport-debug.c
@@ -147,10 +147,8 @@ check_timeout (DBusTransport *transport)
{
if (!debug_transport->timeout_added)
{
- /* FIXME; messages_pending is going to have to
- * handle OOM somehow (probably being part of
- * PreallocatedSend). See also dbus-transport-unix.c
- * check_write_watch()
+ /* FIXME this can be fixed now, by enabling/disabling
+ * the timeout instead of adding it here
*/
while (!_dbus_connection_add_timeout (transport->connection,
debug_transport->timeout))
@@ -203,10 +201,11 @@ debug_disconnect (DBusTransport *transport)
{
}
-static void
+static dbus_bool_t
debug_connection_set (DBusTransport *transport)
{
check_timeout (transport);
+ return TRUE;
}
static void
diff --git a/dbus/dbus-transport-protected.h b/dbus/dbus-transport-protected.h
index 46dfe141..0f6c45ed 100644
--- a/dbus/dbus-transport-protected.h
+++ b/dbus/dbus-transport-protected.h
@@ -49,7 +49,7 @@ struct DBusTransportVTable
void (* disconnect) (DBusTransport *transport);
/**< Disconnect this transport. */
- void (* connection_set) (DBusTransport *transport);
+ dbus_bool_t (* connection_set) (DBusTransport *transport);
/**< Called when transport->connection has been filled in */
void (* messages_pending) (DBusTransport *transport,
diff --git a/dbus/dbus-transport-unix.c b/dbus/dbus-transport-unix.c
index 3c5fe848..23ab7c54 100644
--- a/dbus/dbus-transport-unix.c
+++ b/dbus/dbus-transport-unix.c
@@ -117,6 +117,12 @@ check_write_watch (DBusTransport *transport)
if (transport->connection == NULL)
return;
+
+ if (transport->disconnected)
+ {
+ _dbus_assert (unix_transport->write_watch == NULL);
+ return;
+ }
_dbus_transport_ref (transport);
@@ -126,51 +132,10 @@ check_write_watch (DBusTransport *transport)
need_write_watch = transport->send_credentials_pending ||
_dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND;
- if (transport->disconnected)
- need_write_watch = FALSE;
-
- if (need_write_watch &&
- unix_transport->write_watch == NULL)
- {
- unix_transport->write_watch =
- _dbus_watch_new (unix_transport->fd,
- DBUS_WATCH_WRITABLE);
-
- /* FIXME this is total crack. The proper fix is probably to
- * allocate the write watch on transport creation, keep it
- * allocated. But that doesn't solve needing memory to add the
- * watch. messages_pending is going to have to handle OOM
- * somehow (probably being part of PreallocatedSend)
- */
- if (unix_transport->write_watch == NULL)
- goto out;
+ _dbus_connection_toggle_watch (transport->connection,
+ unix_transport->write_watch,
+ need_write_watch);
- if (!_dbus_connection_add_watch (transport->connection,
- unix_transport->write_watch))
- {
- _dbus_watch_invalidate (unix_transport->write_watch);
- _dbus_watch_unref (unix_transport->write_watch);
- unix_transport->write_watch = NULL;
- }
- }
- else if (!need_write_watch &&
- unix_transport->write_watch != NULL)
- {
- _dbus_connection_remove_watch (transport->connection,
- unix_transport->write_watch);
- _dbus_watch_invalidate (unix_transport->write_watch);
- _dbus_watch_unref (unix_transport->write_watch);
- unix_transport->write_watch = NULL;
- }
- else
- {
-#if 0
- _dbus_verbose ("Write watch is unchanged from %p on fd %d\n",
- unix_transport->write_watch, unix_transport->fd);
-#endif
- }
-
- out:
_dbus_transport_unref (transport);
}
@@ -182,6 +147,12 @@ check_read_watch (DBusTransport *transport)
if (transport->connection == NULL)
return;
+
+ if (transport->disconnected)
+ {
+ _dbus_assert (unix_transport->read_watch == NULL);
+ return;
+ }
_dbus_transport_ref (transport);
@@ -192,57 +163,10 @@ check_read_watch (DBusTransport *transport)
need_read_watch = transport->receive_credentials_pending ||
_dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_WAITING_FOR_INPUT;
-#if 0
- _dbus_verbose ("need_read_watch = %d authenticated = %d\n",
- need_read_watch, _dbus_transport_get_is_authenticated (transport));
-#endif
-
- if (transport->disconnected)
- need_read_watch = FALSE;
-
- if (need_read_watch &&
- unix_transport->read_watch == NULL)
- {
- _dbus_verbose ("Adding read watch to unix fd %d\n",
- unix_transport->fd);
-
- unix_transport->read_watch =
- _dbus_watch_new (unix_transport->fd,
- DBUS_WATCH_READABLE);
+ _dbus_connection_toggle_watch (transport->connection,
+ unix_transport->read_watch,
+ need_read_watch);
- /* we can maybe add it some other time, just silently bomb */
- if (unix_transport->read_watch == NULL)
- goto out;
-
- if (!_dbus_connection_add_watch (transport->connection,
- unix_transport->read_watch))
- {
- _dbus_watch_invalidate (unix_transport->read_watch);
- _dbus_watch_unref (unix_transport->read_watch);
- unix_transport->read_watch = NULL;
- }
- }
- else if (!need_read_watch &&
- unix_transport->read_watch != NULL)
- {
- _dbus_verbose ("Removing read watch from unix fd %d\n",
- unix_transport->fd);
-
- _dbus_connection_remove_watch (transport->connection,
- unix_transport->read_watch);
- _dbus_watch_invalidate (unix_transport->read_watch);
- _dbus_watch_unref (unix_transport->read_watch);
- unix_transport->read_watch = NULL;
- }
- else
- {
-#if 0
- _dbus_verbose ("Read watch is unchanged from %p on fd %d\n",
- unix_transport->read_watch, unix_transport->fd);
-#endif
- }
-
- out:
_dbus_transport_unref (transport);
}
@@ -908,11 +832,27 @@ unix_disconnect (DBusTransport *transport)
unix_transport->fd = -1;
}
-static void
+static dbus_bool_t
unix_connection_set (DBusTransport *transport)
{
+ DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
+
+ if (!_dbus_connection_add_watch (transport->connection,
+ unix_transport->write_watch))
+ return FALSE;
+
+ if (!_dbus_connection_add_watch (transport->connection,
+ unix_transport->read_watch))
+ {
+ _dbus_connection_remove_watch (transport->connection,
+ unix_transport->write_watch);
+ return FALSE;
+ }
+
check_read_watch (transport);
check_write_watch (transport);
+
+ return TRUE;
}
static void
@@ -1120,19 +1060,24 @@ _dbus_transport_new_for_fd (int fd,
if (!_dbus_string_init (&unix_transport->encoded_message,
_DBUS_INT_MAX))
- {
- dbus_free (unix_transport);
- return NULL;
- }
+ goto failed_0;
+
+ unix_transport->write_watch = _dbus_watch_new (fd,
+ DBUS_WATCH_WRITABLE,
+ FALSE);
+ if (unix_transport->write_watch == NULL)
+ goto failed_1;
+
+ unix_transport->read_watch = _dbus_watch_new (fd,
+ DBUS_WATCH_READABLE,
+ FALSE);
+ if (unix_transport->read_watch == NULL)
+ goto failed_2;
if (!_dbus_transport_init_base (&unix_transport->base,
&unix_vtable,
server))
- {
- _dbus_string_free (&unix_transport->encoded_message);
- dbus_free (unix_transport);
- return NULL;
- }
+ goto failed_3;
unix_transport->fd = fd;
unix_transport->message_bytes_written = 0;
@@ -1140,11 +1085,18 @@ _dbus_transport_new_for_fd (int fd,
/* These values should probably be tunable or something. */
unix_transport->max_bytes_read_per_iteration = 2048;
unix_transport->max_bytes_written_per_iteration = 2048;
-
- check_read_watch ((DBusTransport*) unix_transport);
- check_write_watch ((DBusTransport*) unix_transport);
return (DBusTransport*) unix_transport;
+
+ failed_3:
+ _dbus_watch_unref (unix_transport->read_watch);
+ failed_2:
+ _dbus_watch_unref (unix_transport->write_watch);
+ failed_1:
+ _dbus_string_free (&unix_transport->encoded_message);
+ failed_0:
+ dbus_free (unix_transport);
+ return NULL;
}
/**
diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c
index 03fea75b..8c6c7f1c 100644
--- a/dbus/dbus-transport.c
+++ b/dbus/dbus-transport.c
@@ -427,8 +427,9 @@ _dbus_transport_handle_watch (DBusTransport *transport,
*
* @param transport the transport.
* @param connection the connection.
+ * @returns #FALSE if not enough memory
*/
-void
+dbus_bool_t
_dbus_transport_set_connection (DBusTransport *transport,
DBusConnection *connection)
{
@@ -438,8 +439,11 @@ _dbus_transport_set_connection (DBusTransport *transport,
transport->connection = connection;
_dbus_transport_ref (transport);
- (* transport->vtable->connection_set) (transport);
+ if (!(* transport->vtable->connection_set) (transport))
+ transport->connection = NULL;
_dbus_transport_unref (transport);
+
+ return transport->connection != NULL;
}
/**
diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h
index 5e7de3e5..1f01788f 100644
--- a/dbus/dbus-transport.h
+++ b/dbus/dbus-transport.h
@@ -40,7 +40,7 @@ dbus_bool_t _dbus_transport_get_is_authenticated (DBusTransport *trans
void _dbus_transport_handle_watch (DBusTransport *transport,
DBusWatch *watch,
unsigned int condition);
-void _dbus_transport_set_connection (DBusTransport *transport,
+dbus_bool_t _dbus_transport_set_connection (DBusTransport *transport,
DBusConnection *connection);
void _dbus_transport_messages_pending (DBusTransport *transport,
int queue_length);
diff --git a/dbus/dbus-watch.c b/dbus/dbus-watch.c
index ef2a0ed9..1fdbc7ac 100644
--- a/dbus/dbus-watch.c
+++ b/dbus/dbus-watch.c
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-watch.c DBusWatch implementation
*
- * Copyright (C) 2002 Red Hat Inc.
+ * Copyright (C) 2002, 2003 Red Hat Inc.
*
* Licensed under the Academic Free License version 1.2
*
@@ -40,6 +40,7 @@ struct DBusWatch
unsigned int flags; /**< Conditions to watch. */
void *data; /**< Application data. */
DBusFreeFunction free_data_function; /**< Free the application data. */
+ unsigned int enabled : 1; /**< Whether it's enabled. */
};
/**
@@ -47,11 +48,13 @@ struct DBusWatch
* implementation.
* @param fd the file descriptor to be watched.
* @param flags the conditions to watch for on the descriptor.
+ * @param enabled the initial enabled state
* @returns the new DBusWatch object.
*/
DBusWatch*
_dbus_watch_new (int fd,
- unsigned int flags)
+ unsigned int flags,
+ dbus_bool_t enabled)
{
DBusWatch *watch;
@@ -63,6 +66,7 @@ _dbus_watch_new (int fd,
watch->refcount = 1;
watch->fd = fd;
watch->flags = flags;
+ watch->enabled = enabled;
return watch;
}
@@ -160,6 +164,7 @@ struct DBusWatchList
DBusAddWatchFunction add_watch_function; /**< Callback for adding a watch. */
DBusRemoveWatchFunction remove_watch_function; /**< Callback for removing a watch. */
+ DBusWatchToggledFunction watch_toggled_function; /**< Callback on toggling enablement */
void *watch_data; /**< Data for watch callbacks */
DBusFreeFunction watch_free_data_function; /**< Free function for watch callback data */
};
@@ -192,7 +197,7 @@ _dbus_watch_list_free (DBusWatchList *watch_list)
{
/* free watch_data and removes watches as a side effect */
_dbus_watch_list_set_functions (watch_list,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
_dbus_list_foreach (&watch_list->watches,
(DBusForeachFunction) _dbus_watch_unref,
@@ -210,6 +215,7 @@ _dbus_watch_list_free (DBusWatchList *watch_list)
* @param watch_list the watch list.
* @param add_function the add watch function.
* @param remove_function the remove watch function.
+ * @param toggled_function function on toggling enabled flag, or #NULL
* @param data the data for those functions.
* @param free_data_function the function to free the data.
* @returns #FALSE if not enough memory
@@ -219,6 +225,7 @@ dbus_bool_t
_dbus_watch_list_set_functions (DBusWatchList *watch_list,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
+ DBusWatchToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function)
{
@@ -270,6 +277,7 @@ _dbus_watch_list_set_functions (DBusWatchList *watch_list,
watch_list->add_watch_function = add_function;
watch_list->remove_watch_function = remove_function;
+ watch_list->watch_toggled_function = toggled_function;
watch_list->watch_data = data;
watch_list->watch_free_data_function = free_data_function;
@@ -328,6 +336,31 @@ _dbus_watch_list_remove_watch (DBusWatchList *watch_list,
_dbus_watch_unref (watch);
}
+/**
+ * Sets a watch to the given enabled state, invoking the
+ * application's DBusWatchToggledFunction if appropriate.
+ *
+ * @param watch_list the watch list.
+ * @param watch the watch to toggle.
+ * @param enabled #TRUE to enable
+ */
+void
+_dbus_watch_list_toggle_watch (DBusWatchList *watch_list,
+ DBusWatch *watch,
+ dbus_bool_t enabled)
+{
+ enabled = !!enabled;
+
+ if (enabled == watch->enabled)
+ return;
+
+ watch->enabled = enabled;
+
+ if (watch_list->watch_toggled_function != NULL)
+ (* watch_list->watch_toggled_function) (watch,
+ watch_list->watch_data);
+}
+
/** @} */
/**
@@ -419,4 +452,17 @@ dbus_watch_set_data (DBusWatch *watch,
watch->free_data_function = free_data_function;
}
+/**
+ * Returns whether a watch is enabled or not. If not
+ * enabled, it should not be polled by the main loop.
+ *
+ * @param watch the DBusWatch object
+ * @returns #TRUE if the watch is enabled
+ */
+dbus_bool_t
+dbus_watch_get_enabled (DBusWatch *watch)
+{
+ return watch->enabled;
+}
+
/** @} */
diff --git a/dbus/dbus-watch.h b/dbus/dbus-watch.h
index 9d85737e..7a9ec57c 100644
--- a/dbus/dbus-watch.h
+++ b/dbus/dbus-watch.h
@@ -33,7 +33,8 @@ DBUS_BEGIN_DECLS;
typedef struct DBusWatchList DBusWatchList;
DBusWatch* _dbus_watch_new (int fd,
- unsigned int flags);
+ unsigned int flags,
+ dbus_bool_t enabled);
void _dbus_watch_ref (DBusWatch *watch);
void _dbus_watch_unref (DBusWatch *watch);
void _dbus_watch_invalidate (DBusWatch *watch);
@@ -46,13 +47,16 @@ void _dbus_watch_list_free (DBusWatchList *watch_li
dbus_bool_t _dbus_watch_list_set_functions (DBusWatchList *watch_list,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
+ DBusWatchToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function);
dbus_bool_t _dbus_watch_list_add_watch (DBusWatchList *watch_list,
DBusWatch *watch);
void _dbus_watch_list_remove_watch (DBusWatchList *watch_list,
DBusWatch *watch);
-
+void _dbus_watch_list_toggle_watch (DBusWatchList *watch_list,
+ DBusWatch *watch,
+ dbus_bool_t enabled);
DBUS_END_DECLS;