mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-01-07 15:50:21 +01:00
2003-03-15 Havoc Pennington <hp@pobox.com>
Make it pass the Hello handling test including all OOM codepaths. Now to do other messages... * bus/services.c (bus_service_remove_owner): fix crash when removing owner from an empty list of owners (bus_registry_ensure): don't leave service in the list of a connection's owned services if we fail to put the service in the hash table. * bus/connection.c (bus_connection_preallocate_oom_error): set error flag on the OOM error. * dbus/dbus-connection.c (_dbus_connection_new_for_transport): handle _dbus_transport_set_connection failure * dbus/dbus-transport-unix.c (_dbus_transport_new_for_fd): modify to create watches up front and simply enable/disable them as needed. (unix_connection_set): this can now fail on OOM * dbus/dbus-timeout.c, dbus/dbus-watch.c: add concept of enabling/disabling a watch or timeout. * bus/loop.c (bus_loop_iterate): don't touch disabled watches/timeouts * glib/dbus-gmain.c: adapt to enable/disable watches and timeouts
This commit is contained in:
parent
f05f87a825
commit
f587ce7845
25 changed files with 547 additions and 228 deletions
30
ChangeLog
30
ChangeLog
|
|
@ -1,3 +1,33 @@
|
|||
2003-03-15 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
Make it pass the Hello handling test including all OOM codepaths.
|
||||
Now to do other messages...
|
||||
|
||||
* bus/services.c (bus_service_remove_owner): fix crash when
|
||||
removing owner from an empty list of owners
|
||||
(bus_registry_ensure): don't leave service in the list of
|
||||
a connection's owned services if we fail to put the service
|
||||
in the hash table.
|
||||
|
||||
* bus/connection.c (bus_connection_preallocate_oom_error): set
|
||||
error flag on the OOM error.
|
||||
|
||||
* dbus/dbus-connection.c (_dbus_connection_new_for_transport):
|
||||
handle _dbus_transport_set_connection failure
|
||||
|
||||
* dbus/dbus-transport-unix.c (_dbus_transport_new_for_fd): modify
|
||||
to create watches up front and simply enable/disable them as
|
||||
needed.
|
||||
(unix_connection_set): this can now fail on OOM
|
||||
|
||||
* dbus/dbus-timeout.c, dbus/dbus-watch.c: add concept
|
||||
of enabling/disabling a watch or timeout.
|
||||
|
||||
* bus/loop.c (bus_loop_iterate): don't touch disabled
|
||||
watches/timeouts
|
||||
|
||||
* glib/dbus-gmain.c: adapt to enable/disable watches and timeouts
|
||||
|
||||
2003-03-15 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* bus/dispatch.c (bus_dispatch_test): OK, now finally actually
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ bus_context_new (const char *address,
|
|||
if (!dbus_server_set_watch_functions (context->server,
|
||||
(DBusAddWatchFunction) add_server_watch,
|
||||
(DBusRemoveWatchFunction) remove_server_watch,
|
||||
NULL,
|
||||
context,
|
||||
NULL))
|
||||
{
|
||||
|
|
@ -171,6 +172,7 @@ bus_context_new (const char *address,
|
|||
if (!dbus_server_set_timeout_functions (context->server,
|
||||
(DBusAddTimeoutFunction) add_server_timeout,
|
||||
(DBusRemoveTimeoutFunction) remove_server_timeout,
|
||||
NULL,
|
||||
context, NULL))
|
||||
{
|
||||
BUS_SET_OOM (error);
|
||||
|
|
@ -192,13 +194,13 @@ bus_context_shutdown (BusContext *context)
|
|||
return;
|
||||
|
||||
if (!dbus_server_set_watch_functions (context->server,
|
||||
NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
context,
|
||||
NULL))
|
||||
_dbus_assert_not_reached ("setting watch functions to NULL failed");
|
||||
|
||||
if (!dbus_server_set_timeout_functions (context->server,
|
||||
NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
context,
|
||||
NULL))
|
||||
_dbus_assert_not_reached ("setting timeout functions to NULL failed");
|
||||
|
|
|
|||
|
|
@ -107,13 +107,13 @@ bus_connection_disconnected (DBusConnection *connection)
|
|||
|
||||
/* no more watching */
|
||||
if (!dbus_connection_set_watch_functions (connection,
|
||||
NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
connection,
|
||||
NULL))
|
||||
_dbus_assert_not_reached ("setting watch functions to NULL failed");
|
||||
|
||||
if (!dbus_connection_set_timeout_functions (connection,
|
||||
NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
connection,
|
||||
NULL))
|
||||
_dbus_assert_not_reached ("setting timeout functions to NULL failed");
|
||||
|
|
@ -288,6 +288,7 @@ bus_connections_setup_connection (BusConnections *connections,
|
|||
if (!dbus_connection_set_watch_functions (connection,
|
||||
(DBusAddWatchFunction) add_connection_watch,
|
||||
(DBusRemoveWatchFunction) remove_connection_watch,
|
||||
NULL,
|
||||
connection,
|
||||
NULL))
|
||||
{
|
||||
|
|
@ -298,6 +299,7 @@ bus_connections_setup_connection (BusConnections *connections,
|
|||
if (!dbus_connection_set_timeout_functions (connection,
|
||||
(DBusAddTimeoutFunction) add_connection_timeout,
|
||||
(DBusRemoveTimeoutFunction) remove_connection_timeout,
|
||||
NULL,
|
||||
connection, NULL))
|
||||
{
|
||||
dbus_connection_disconnect (connection);
|
||||
|
|
@ -442,6 +444,8 @@ bus_connection_preallocate_oom_error (DBusConnection *connection)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
dbus_message_set_is_error (message, TRUE);
|
||||
|
||||
/* set reply serial to placeholder value just so space is already allocated
|
||||
* for it.
|
||||
*/
|
||||
|
|
@ -603,6 +607,9 @@ bus_transaction_send_message (BusTransaction *transaction,
|
|||
BusConnectionData *d;
|
||||
DBusList *link;
|
||||
|
||||
_dbus_verbose (" trying to add message %s to transaction\n",
|
||||
dbus_message_get_name (message));
|
||||
|
||||
if (!dbus_connection_get_is_connected (connection))
|
||||
return TRUE; /* silently ignore disconnected connections */
|
||||
|
||||
|
|
@ -789,6 +796,9 @@ bus_transaction_send_error_reply (BusTransaction *transaction,
|
|||
|
||||
_dbus_assert (error != NULL);
|
||||
_DBUS_ASSERT_ERROR_IS_SET (error);
|
||||
|
||||
_dbus_verbose (" trying to add error %s to transaction\n",
|
||||
error->name);
|
||||
|
||||
reply = dbus_message_new_error_reply (in_reply_to,
|
||||
error->name,
|
||||
|
|
|
|||
|
|
@ -514,6 +514,7 @@ check_hello_connection (BusContext *context)
|
|||
|
||||
if (!bus_setup_debug_client (connection))
|
||||
{
|
||||
dbus_connection_disconnect (connection);
|
||||
dbus_connection_unref (connection);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -582,9 +583,6 @@ bus_dispatch_test (const DBusString *test_data_dir)
|
|||
&error);
|
||||
if (context == NULL)
|
||||
_dbus_assert_not_reached ("could not alloc context");
|
||||
|
||||
check1_try_iterations (context, "create_and_hello",
|
||||
check_hello_connection);
|
||||
|
||||
foo = dbus_connection_open ("debug-pipe:name=test-server", &result);
|
||||
if (foo == NULL)
|
||||
|
|
@ -610,8 +608,14 @@ bus_dispatch_test (const DBusString *test_data_dir)
|
|||
if (!check_hello_message (context, baz))
|
||||
_dbus_assert_not_reached ("hello message failed");
|
||||
|
||||
check1_try_iterations (context, "create_and_hello",
|
||||
check_hello_connection);
|
||||
|
||||
dbus_connection_disconnect (foo);
|
||||
dbus_connection_unref (foo);
|
||||
dbus_connection_disconnect (bar);
|
||||
dbus_connection_unref (bar);
|
||||
dbus_connection_disconnect (baz);
|
||||
dbus_connection_unref (baz);
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
55
bus/loop.c
55
bus/loop.c
|
|
@ -294,9 +294,26 @@ bus_loop_iterate (dbus_bool_t block)
|
|||
bus_loop_quit ();
|
||||
goto next_iteration;
|
||||
}
|
||||
|
||||
n_fds = watch_count;
|
||||
|
||||
/* count enabled watches */
|
||||
n_fds = 0;
|
||||
link = _dbus_list_get_first_link (&callbacks);
|
||||
while (link != NULL)
|
||||
{
|
||||
DBusList *next = _dbus_list_get_next_link (&callbacks, link);
|
||||
Callback *cb = link->data;
|
||||
if (cb->type == CALLBACK_WATCH)
|
||||
{
|
||||
WatchCallback *wcb = WATCH_CALLBACK (cb);
|
||||
|
||||
if (dbus_watch_get_enabled (wcb->watch))
|
||||
++n_fds;
|
||||
}
|
||||
|
||||
link = next;
|
||||
}
|
||||
|
||||
/* fill our array of fds and watches */
|
||||
if (n_fds > 0)
|
||||
{
|
||||
fds = dbus_new0 (DBusPollFD, n_fds);
|
||||
|
|
@ -323,18 +340,21 @@ bus_loop_iterate (dbus_bool_t block)
|
|||
{
|
||||
unsigned int flags;
|
||||
WatchCallback *wcb = WATCH_CALLBACK (cb);
|
||||
|
||||
watches_for_fds[i] = wcb;
|
||||
|
||||
flags = dbus_watch_get_flags (wcb->watch);
|
||||
|
||||
fds[i].fd = dbus_watch_get_fd (wcb->watch);
|
||||
if (flags & DBUS_WATCH_READABLE)
|
||||
fds[i].events |= _DBUS_POLLIN;
|
||||
if (flags & DBUS_WATCH_WRITABLE)
|
||||
fds[i].events |= _DBUS_POLLOUT;
|
||||
|
||||
++i;
|
||||
if (dbus_watch_get_enabled (wcb->watch))
|
||||
{
|
||||
watches_for_fds[i] = wcb;
|
||||
|
||||
flags = dbus_watch_get_flags (wcb->watch);
|
||||
|
||||
fds[i].fd = dbus_watch_get_fd (wcb->watch);
|
||||
if (flags & DBUS_WATCH_READABLE)
|
||||
fds[i].events |= _DBUS_POLLIN;
|
||||
if (flags & DBUS_WATCH_WRITABLE)
|
||||
fds[i].events |= _DBUS_POLLOUT;
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
link = next;
|
||||
|
|
@ -359,7 +379,8 @@ bus_loop_iterate (dbus_bool_t block)
|
|||
DBusList *next = _dbus_list_get_next_link (&callbacks, link);
|
||||
Callback *cb = link->data;
|
||||
|
||||
if (cb->type == CALLBACK_TIMEOUT)
|
||||
if (cb->type == CALLBACK_TIMEOUT &&
|
||||
dbus_timeout_get_enabled (TIMEOUT_CALLBACK (cb)->timeout))
|
||||
{
|
||||
TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb);
|
||||
unsigned long interval;
|
||||
|
|
@ -427,7 +448,8 @@ bus_loop_iterate (dbus_bool_t block)
|
|||
if (exited)
|
||||
goto next_iteration;
|
||||
|
||||
if (cb->type == CALLBACK_TIMEOUT)
|
||||
if (cb->type == CALLBACK_TIMEOUT &&
|
||||
dbus_timeout_get_enabled (TIMEOUT_CALLBACK (cb)->timeout))
|
||||
{
|
||||
TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb);
|
||||
unsigned long interval;
|
||||
|
|
@ -513,7 +535,8 @@ bus_loop_iterate (dbus_bool_t block)
|
|||
* weird POLLFOO thing like POLLWRBAND
|
||||
*/
|
||||
|
||||
if (condition != 0)
|
||||
if (condition != 0 &&
|
||||
dbus_watch_get_enabled (wcb->watch))
|
||||
{
|
||||
(* wcb->function) (wcb->watch,
|
||||
condition,
|
||||
|
|
|
|||
|
|
@ -170,6 +170,8 @@ bus_registry_ensure (BusRegistry *registry,
|
|||
service->name,
|
||||
service))
|
||||
{
|
||||
bus_connection_remove_owned_service (owner_if_created,
|
||||
service);
|
||||
_dbus_list_clear (&service->owners);
|
||||
dbus_free (service->name);
|
||||
_dbus_mem_pool_dealloc (registry->service_pool, service);
|
||||
|
|
@ -290,7 +292,11 @@ bus_service_remove_owner (BusService *service,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (_dbus_list_length_is_one (&service->owners))
|
||||
if (service->owners == NULL)
|
||||
{
|
||||
_dbus_assert_not_reached ("Tried to remove owner of a service that has no owners");
|
||||
}
|
||||
else if (_dbus_list_length_is_one (&service->owners))
|
||||
{
|
||||
/* We are the only owner - send service deleted */
|
||||
if (!bus_driver_send_service_deleted (service->name,
|
||||
|
|
@ -301,6 +307,7 @@ bus_service_remove_owner (BusService *service,
|
|||
{
|
||||
DBusList *link;
|
||||
link = _dbus_list_get_first (&service->owners);
|
||||
_dbus_assert (link != NULL);
|
||||
link = _dbus_list_get_next_link (&service->owners, link);
|
||||
|
||||
if (link != NULL)
|
||||
|
|
@ -320,7 +327,8 @@ bus_service_remove_owner (BusService *service,
|
|||
if (service->owners == NULL)
|
||||
{
|
||||
/* Delete service (already sent message that it was deleted above) */
|
||||
_dbus_hash_table_remove_string (service->registry->service_hash, service->name);
|
||||
_dbus_hash_table_remove_string (service->registry->service_hash,
|
||||
service->name);
|
||||
|
||||
dbus_free (service->name);
|
||||
_dbus_mem_pool_dealloc (service->registry->service_pool, service);
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ bus_setup_debug_client (DBusConnection *connection)
|
|||
if (!dbus_connection_set_watch_functions (connection,
|
||||
(DBusAddWatchFunction) add_client_watch,
|
||||
(DBusRemoveWatchFunction) remove_client_watch,
|
||||
NULL,
|
||||
connection,
|
||||
NULL))
|
||||
goto out;
|
||||
|
|
@ -134,6 +135,7 @@ bus_setup_debug_client (DBusConnection *connection)
|
|||
if (!dbus_connection_set_timeout_functions (connection,
|
||||
(DBusAddTimeoutFunction) add_client_timeout,
|
||||
(DBusRemoveTimeoutFunction) remove_client_timeout,
|
||||
NULL,
|
||||
connection, NULL))
|
||||
goto out;
|
||||
|
||||
|
|
@ -148,9 +150,9 @@ bus_setup_debug_client (DBusConnection *connection)
|
|||
_DBUS_N_ELEMENTS (to_handle));
|
||||
|
||||
dbus_connection_set_watch_functions (connection,
|
||||
NULL, NULL, NULL, NULL);
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
dbus_connection_set_timeout_functions (connection,
|
||||
NULL, NULL, NULL, NULL);
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
dbus_message_handler_unref (disconnect_handler);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -330,6 +330,25 @@ _dbus_connection_remove_watch (DBusConnection *connection,
|
|||
watch);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -145,6 +145,25 @@ _dbus_server_remove_watch (DBusServer *server,
|
|||
_dbus_watch_list_remove_watch (server->watches, watch);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
_dbus_connection_toggle_watch (transport->connection,
|
||||
unix_transport->write_watch,
|
||||
need_write_watch);
|
||||
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -238,6 +238,9 @@ add_watch (DBusWatch *watch,
|
|||
GPollFD *poll_fd;
|
||||
DBusGSource *dbus_source;
|
||||
guint flags;
|
||||
|
||||
if (!dbus_watch_get_enabled (watch))
|
||||
return TRUE;
|
||||
|
||||
dbus_source = data;
|
||||
|
||||
|
|
@ -269,6 +272,8 @@ remove_watch (DBusWatch *watch,
|
|||
GPollFD *poll_fd;
|
||||
|
||||
poll_fd = dbus_watch_get_data (watch);
|
||||
if (poll_fd == NULL)
|
||||
return; /* probably a not-enabled watch that was added */
|
||||
|
||||
dbus_source->poll_fds = g_list_remove (dbus_source->poll_fds, poll_fd);
|
||||
g_hash_table_remove (dbus_source->watches, poll_fd);
|
||||
|
|
@ -277,6 +282,19 @@ remove_watch (DBusWatch *watch,
|
|||
g_free (poll_fd);
|
||||
}
|
||||
|
||||
static void
|
||||
watch_toggled (DBusWatch *watch,
|
||||
void *data)
|
||||
{
|
||||
/* Because we just exit on OOM, enable/disable is
|
||||
* no different from add/remove
|
||||
*/
|
||||
if (dbus_watch_get_enabled (watch))
|
||||
add_watch (watch, data);
|
||||
else
|
||||
remove_watch (watch, data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
timeout_handler (gpointer data)
|
||||
{
|
||||
|
|
@ -293,6 +311,9 @@ add_timeout (DBusTimeout *timeout,
|
|||
{
|
||||
guint timeout_tag;
|
||||
|
||||
if (!dbus_timeout_get_enabled (timeout))
|
||||
return TRUE;
|
||||
|
||||
timeout_tag = g_timeout_add (dbus_timeout_get_interval (timeout),
|
||||
timeout_handler, timeout);
|
||||
|
||||
|
|
@ -308,10 +329,25 @@ remove_timeout (DBusTimeout *timeout,
|
|||
guint timeout_tag;
|
||||
|
||||
timeout_tag = GPOINTER_TO_UINT (dbus_timeout_get_data (timeout));
|
||||
|
||||
g_source_remove (timeout_tag);
|
||||
|
||||
if (timeout_tag != 0) /* if 0, probably timeout was disabled */
|
||||
g_source_remove (timeout_tag);
|
||||
}
|
||||
|
||||
static void
|
||||
timeout_toggled (DBusTimeout *timeout,
|
||||
void *data)
|
||||
{
|
||||
/* Because we just exit on OOM, enable/disable is
|
||||
* no different from add/remove
|
||||
*/
|
||||
if (dbus_timeout_get_enabled (timeout))
|
||||
add_timeout (timeout, data);
|
||||
else
|
||||
remove_timeout (timeout, data);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
free_source (GSource *source)
|
||||
{
|
||||
|
|
@ -363,12 +399,14 @@ dbus_connection_setup_with_g_main (DBusConnection *connection)
|
|||
if (!dbus_connection_set_watch_functions (connection,
|
||||
add_watch,
|
||||
remove_watch,
|
||||
watch_toggled,
|
||||
source, NULL))
|
||||
goto nomem;
|
||||
|
||||
if (!dbus_connection_set_timeout_functions (connection,
|
||||
add_timeout,
|
||||
remove_timeout,
|
||||
timeout_toggled,
|
||||
NULL, NULL))
|
||||
goto nomem;
|
||||
|
||||
|
|
@ -412,11 +450,13 @@ dbus_server_setup_with_g_main (DBusServer *server)
|
|||
dbus_server_set_watch_functions (server,
|
||||
add_watch,
|
||||
remove_watch,
|
||||
watch_toggled,
|
||||
source, NULL);
|
||||
|
||||
dbus_server_set_timeout_functions (server,
|
||||
add_timeout,
|
||||
remove_timeout,
|
||||
timeout_toggled,
|
||||
NULL, NULL);
|
||||
|
||||
g_source_attach (source, NULL);
|
||||
|
|
|
|||
103
test/watch.c
103
test/watch.c
|
|
@ -237,24 +237,28 @@ do_mainloop (void)
|
|||
while (link != NULL)
|
||||
{
|
||||
DBusList *next = _dbus_list_get_next_link (&watches, link);
|
||||
int fd;
|
||||
DBusWatch *watch;
|
||||
unsigned int flags;
|
||||
|
||||
watch = link->data;
|
||||
|
||||
fd = dbus_watch_get_fd (watch);
|
||||
flags = dbus_watch_get_flags (watch);
|
||||
|
||||
max_fd = MAX (max_fd, fd);
|
||||
|
||||
if (flags & DBUS_WATCH_READABLE)
|
||||
FD_SET (fd, &read_set);
|
||||
|
||||
if (flags & DBUS_WATCH_WRITABLE)
|
||||
FD_SET (fd, &write_set);
|
||||
if (dbus_watch_get_enabled (watch))
|
||||
{
|
||||
int fd;
|
||||
unsigned int flags;
|
||||
|
||||
FD_SET (fd, &err_set);
|
||||
fd = dbus_watch_get_fd (watch);
|
||||
flags = dbus_watch_get_flags (watch);
|
||||
|
||||
max_fd = MAX (max_fd, fd);
|
||||
|
||||
if (flags & DBUS_WATCH_READABLE)
|
||||
FD_SET (fd, &read_set);
|
||||
|
||||
if (flags & DBUS_WATCH_WRITABLE)
|
||||
FD_SET (fd, &write_set);
|
||||
|
||||
FD_SET (fd, &err_set);
|
||||
}
|
||||
|
||||
link = next;
|
||||
}
|
||||
|
|
@ -266,10 +270,7 @@ do_mainloop (void)
|
|||
while (link != NULL)
|
||||
{
|
||||
DBusList *next = _dbus_list_get_next_link (&watches, link);
|
||||
int fd;
|
||||
DBusWatch *watch;
|
||||
unsigned int flags;
|
||||
unsigned int condition;
|
||||
|
||||
if (initial_watch_serial != watch_list_serial)
|
||||
{
|
||||
|
|
@ -286,44 +287,52 @@ do_mainloop (void)
|
|||
}
|
||||
|
||||
watch = link->data;
|
||||
|
||||
fd = dbus_watch_get_fd (watch);
|
||||
flags = dbus_watch_get_flags (watch);
|
||||
|
||||
condition = 0;
|
||||
|
||||
if ((flags & DBUS_WATCH_READABLE) &&
|
||||
FD_ISSET (fd, &read_set))
|
||||
condition |= DBUS_WATCH_READABLE;
|
||||
|
||||
if ((flags & DBUS_WATCH_WRITABLE) &&
|
||||
FD_ISSET (fd, &write_set))
|
||||
condition |= DBUS_WATCH_WRITABLE;
|
||||
|
||||
if (FD_ISSET (fd, &err_set))
|
||||
condition |= DBUS_WATCH_ERROR;
|
||||
|
||||
if (condition != 0)
|
||||
if (dbus_watch_get_enabled (watch))
|
||||
{
|
||||
WatchData *wd;
|
||||
int fd;
|
||||
unsigned int flags;
|
||||
unsigned int condition;
|
||||
|
||||
wd = dbus_watch_get_data (watch);
|
||||
|
||||
fd = dbus_watch_get_fd (watch);
|
||||
flags = dbus_watch_get_flags (watch);
|
||||
|
||||
if (wd->type == WATCH_CONNECTION)
|
||||
condition = 0;
|
||||
|
||||
if ((flags & DBUS_WATCH_READABLE) &&
|
||||
FD_ISSET (fd, &read_set))
|
||||
condition |= DBUS_WATCH_READABLE;
|
||||
|
||||
if ((flags & DBUS_WATCH_WRITABLE) &&
|
||||
FD_ISSET (fd, &write_set))
|
||||
condition |= DBUS_WATCH_WRITABLE;
|
||||
|
||||
if (FD_ISSET (fd, &err_set))
|
||||
condition |= DBUS_WATCH_ERROR;
|
||||
|
||||
if (condition != 0)
|
||||
{
|
||||
DBusConnection *connection = wd->data;
|
||||
WatchData *wd;
|
||||
|
||||
dbus_connection_handle_watch (connection,
|
||||
wd = dbus_watch_get_data (watch);
|
||||
|
||||
if (wd->type == WATCH_CONNECTION)
|
||||
{
|
||||
DBusConnection *connection = wd->data;
|
||||
|
||||
dbus_connection_handle_watch (connection,
|
||||
watch,
|
||||
condition);
|
||||
}
|
||||
else if (wd->type == WATCH_SERVER)
|
||||
{
|
||||
DBusServer *server = wd->data;
|
||||
|
||||
dbus_server_handle_watch (server,
|
||||
watch,
|
||||
condition);
|
||||
}
|
||||
else if (wd->type == WATCH_SERVER)
|
||||
{
|
||||
DBusServer *server = wd->data;
|
||||
|
||||
dbus_server_handle_watch (server,
|
||||
watch,
|
||||
condition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -345,6 +354,7 @@ setup_connection (DBusConnection *connection)
|
|||
if (!dbus_connection_set_watch_functions (connection,
|
||||
(DBusAddWatchFunction) add_connection_watch,
|
||||
(DBusRemoveWatchFunction) remove_connection_watch,
|
||||
NULL,
|
||||
connection,
|
||||
NULL))
|
||||
_dbus_assert_not_reached ("not enough memory");
|
||||
|
|
@ -359,6 +369,7 @@ setup_server (DBusServer *server)
|
|||
if (!dbus_server_set_watch_functions (server,
|
||||
(DBusAddWatchFunction) add_server_watch,
|
||||
(DBusRemoveWatchFunction) remove_server_watch,
|
||||
NULL,
|
||||
server,
|
||||
NULL))
|
||||
_dbus_assert_not_reached ("not enough memory");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue