+2003-04-18 Havoc Pennington <hp@pobox.com>
+
+ * glib/dbus-gmain.c: adapt to watch changes
+
+ * bus/bus.c, bus/activation.c, etc.: adjust to watch changes
+
+ * dbus/dbus-server.h: remove dbus_server_handle_watch
+
+ * dbus/dbus-connection.h: remove dbus_connection_handle_watch
+
+ * dbus/dbus-watch.c (dbus_watch_handle): change DBusWatch to work
+ like DBusTimeout, so we don't need dbus_connection_handle_watch
+ etc.
+
2003-04-17 Havoc Pennington <hp@redhat.com>
* dbus/dbus-userdb.c, dbus/dbus-sysdeps.c: redo all the passwd
_dbus_babysitter_ref (babysitter);
- retval = _dbus_babysitter_handle_watch (babysitter, watch, condition);
-
+ retval = dbus_watch_handle (watch, condition);
+
+ /* FIXME this is broken in the same way that
+ * connection watches used to be; there should be
+ * a separate callback for status change, instead
+ * of doing "if we handled a watch status might
+ * have changed"
+ *
+ * Fixing this lets us move dbus_watch_handle
+ * calls into dbus-mainloop.c
+ */
+
if (_dbus_babysitter_get_child_exited (babysitter))
{
DBusError error;
unsigned int condition,
void *data)
{
- DBusServer *server = data;
-
- return dbus_server_handle_watch (server, watch, condition);
+ /* FIXME this can be done in dbus-mainloop.c
+ * if the code in activation.c for the babysitter
+ * watch handler is fixed.
+ */
+
+ return dbus_watch_handle (watch, condition);
}
static dbus_bool_t
unsigned int condition,
void *data)
{
- DBusConnection *connection = data;
- dbus_bool_t retval;
-
+ /* FIXME this can be done in dbus-mainloop.c
+ * if the code in activation.c for the babysitter
+ * watch handler is fixed.
+ */
+
#if 0
_dbus_verbose ("Calling handle_watch\n");
#endif
- retval = dbus_connection_handle_watch (connection, watch, condition);
-
- return retval;
+ return dbus_watch_handle (watch, condition);
}
static dbus_bool_t
connection_timeout_callback (DBusTimeout *timeout,
void *data)
{
- DBusConnection *connection = data;
+ /* DBusConnection *connection = data; */
/* can return FALSE on OOM but we just let it fire again later */
dbus_timeout_handle (timeout);
return d->name;
}
-/**
+/*
* Transactions
*
* Note that this is fairly fragile; in particular, don't try to use
unsigned int condition,
void *data)
{
- DBusConnection *connection = data;
- dbus_bool_t retval;
-
- dbus_connection_ref (connection);
-
- retval = dbus_connection_handle_watch (connection, watch, condition);
-
- dbus_connection_unref (connection);
-
- return retval;
+ /* FIXME this can be done in dbus-mainloop.c
+ * if the code in activation.c for the babysitter
+ * watch handler is fixed.
+ */
+
+ return dbus_watch_handle (watch, condition);
}
static dbus_bool_t
DBUS_ITERATION_DO_READING = 1 << 1, /**< Read messages in. */
DBUS_ITERATION_BLOCK = 1 << 2 /**< Block if nothing to do. */
} DBusIterationFlags;
+
void _dbus_connection_lock (DBusConnection *connection);
void _dbus_connection_unlock (DBusConnection *connection);
void _dbus_connection_ref_unlocked (DBusConnection *connection);
void _dbus_connection_toggle_watch (DBusConnection *connection,
DBusWatch *watch,
dbus_bool_t enabled);
+dbus_bool_t _dbus_connection_handle_watch (DBusWatch *watch,
+ unsigned int condition,
+ void *data);
dbus_bool_t _dbus_connection_add_timeout (DBusConnection *connection,
DBusTimeout *timeout);
void _dbus_connection_remove_timeout (DBusConnection *connection,
DBusConnection *connection,
DBusMessage *message);
-
-
-
DBUS_END_DECLS;
#endif /* DBUS_CONNECTION_INTERNAL_H */
void *dispatch_status_data; /**< Application data for dispatch_status_function */
DBusFreeFunction free_dispatch_status_data; /**< free dispatch_status_data */
- DBusDispatchStatus last_dispatch_status;
+ DBusDispatchStatus last_dispatch_status; /**< The last dispatch status we reported to the application. */
};
typedef struct
* other exceptional conditions.
*
* Once a file descriptor becomes readable or writable, or an exception
- * occurs, dbus_connection_handle_watch() should be called to
+ * occurs, dbus_watch_handle() should be called to
* notify the connection of the file descriptor's condition.
*
- * dbus_connection_handle_watch() cannot be called during the
+ * dbus_watch_handle() cannot be called during the
* DBusAddWatchFunction, as the connection will not be ready to handle
* that watch yet.
*
}
/**
- * Called to notify the connection when a previously-added watch
- * is ready for reading or writing, or has an exception such
- * as a hangup.
- *
- * If this function returns #FALSE, then the file descriptor may still
- * be ready for reading or writing, but more memory is needed in order
- * to do the reading or writing. If you ignore the #FALSE return, your
- * application may spin in a busy loop on the file descriptor until
- * memory becomes available, but nothing more catastrophic should
- * happen.
+ * A callback for use with dbus_watch_new() to create a DBusWatch.
+ *
+ * @todo This is basically a hack - we could delete _dbus_transport_handle_watch()
+ * and the virtual handle_watch in DBusTransport if we got rid of it.
+ * The reason this is some work is threading, see the _dbus_connection_handle_watch()
+ * implementation.
*
- * @param connection the connection.
* @param watch the watch.
* @param condition the current condition of the file descriptors being watched.
+ * @param data must be a pointer to a #DBusConnection
* @returns #FALSE if the IO condition may not have been fully handled due to lack of memory
*/
dbus_bool_t
-dbus_connection_handle_watch (DBusConnection *connection,
- DBusWatch *watch,
- unsigned int condition)
+_dbus_connection_handle_watch (DBusWatch *watch,
+ unsigned int condition,
+ void *data)
{
+ DBusConnection *connection;
dbus_bool_t retval;
DBusDispatchStatus status;
+
+ connection = data;
dbus_mutex_lock (connection->mutex);
_dbus_connection_acquire_io_path (connection, -1);
DBUS_WATCH_READABLE = 1 << 0, /**< As in POLLIN */
DBUS_WATCH_WRITABLE = 1 << 1, /**< As in POLLOUT */
DBUS_WATCH_ERROR = 1 << 2, /**< As in POLLERR (can't watch for this, but
- * the flag can be passed to dbus_connection_handle_watch()).
+ * the flag can be passed to dbus_watch_handle()).
*/
DBUS_WATCH_HANGUP = 1 << 3 /**< As in POLLHUP (can't watch for it, but
* can be present in current state). */
DBusDispatchStatusFunction function,
void *data,
DBusFreeFunction free_data_function);
-dbus_bool_t dbus_connection_handle_watch (DBusConnection *connection,
- DBusWatch *watch,
- unsigned int condition);
dbus_bool_t dbus_connection_get_unix_user (DBusConnection *connection,
unsigned long *uid);
void dbus_connection_set_unix_user_function (DBusConnection *connection,
void dbus_watch_set_data (DBusWatch *watch,
void *data,
DBusFreeFunction free_data_function);
+dbus_bool_t dbus_watch_handle (DBusWatch *watch,
+ unsigned int flags);
dbus_bool_t dbus_watch_get_enabled (DBusWatch *watch);
int dbus_timeout_get_interval (DBusTimeout *timeout);
DBusList *size_counters; /**< 0-N DBusCounter used to track message size. */
long size_counter_delta; /**< Size we incremented the size counters by. */
- dbus_uint32_t changed_stamp;
+ dbus_uint32_t changed_stamp; /**< Incremented when iterators are invalidated. */
unsigned int locked : 1; /**< Message being sent, no modifications allowed. */
};
DBUS_MESSAGE_ITER_TYPE_DICT
};
+/** typedef for internals of message iterator */
typedef struct DBusMessageRealIter DBusMessageRealIter;
/**
* message passed in.
*
* @param message the message
- * @param _iter pointer to an iterator to initialize
+ * @param iter pointer to an iterator to initialize
*/
void
dbus_message_iter_init (DBusMessage *message,
/**
* Moves the iterator to the next field.
*
- * @param _iter The message iter
+ * @param iter The message iter
* @returns #TRUE if the iterator was moved to the next field
*/
dbus_bool_t
* message.
*
* @param message the message
- * @param _iter pointer to an iterator to initialize
+ * @param iter pointer to an iterator to initialize
*/
void
dbus_message_append_iter_init (DBusMessage *message,
}
/**
- * Appends a named type data chunk to the message.
+ * Appends a named type data chunk to the message. A named
+ * type is simply an arbitrary UTF-8 string used as a type
+ * tag, plus an array of arbitrary bytes to be interpreted
+ * according to the type tag.
*
* @param iter an iterator pointing to the end of the message
* @param name the name of the type
- * @parame
+ * @param data the binary data used to store the value
+ * @param len the length of the binary data in bytes
* @returns #TRUE on success
*/
dbus_bool_t
* can be used to append to the dict.
*
* @param iter an iterator pointing to the end of the message
- * @param array_iter pointer to an iter that will be initialized
- * @param element_type the type of the array elements
+ * @param dict_iter pointer to an iter that will be initialized
* @returns #TRUE on success
*/
dbus_bool_t
dbus_free (server);
}
-static dbus_bool_t
-debug_handle_watch (DBusServer *server,
- DBusWatch *watch,
- unsigned int flags)
-{
-
- return TRUE;
-}
-
static void
debug_disconnect (DBusServer *server)
{
static DBusServerVTable debug_vtable = {
debug_finalize,
- debug_handle_watch,
debug_disconnect
};
{
}
-static dbus_bool_t
-debug_handle_watch (DBusServer *server,
- DBusWatch *watch,
- unsigned int flags)
-{
- return TRUE;
-}
-
static void
debug_disconnect (DBusServer *server)
{
static DBusServerVTable debug_vtable = {
debug_finalize,
- debug_handle_watch,
debug_disconnect
};
{
void (* finalize) (DBusServer *server);
/**< The finalize method must free the server. */
-
- dbus_bool_t (* handle_watch) (DBusServer *server,
- DBusWatch *watch,
- unsigned int flags);
- /**< The handle_watch method handles reading/writing
- * data as indicated by the flags.
- */
void (* disconnect) (DBusServer *server);
/**< Disconnect this server. */
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-server-unix.c Server implementation for Unix network protocols.
*
- * Copyright (C) 2002 Red Hat Inc.
+ * Copyright (C) 2002, 2003 Red Hat Inc.
*
* Licensed under the Academic Free License version 1.2
*
}
static dbus_bool_t
-unix_handle_watch (DBusServer *server,
- DBusWatch *watch,
- unsigned int flags)
+unix_handle_watch (DBusWatch *watch,
+ unsigned int flags,
+ void *data)
{
- DBusServerUnix *unix_server = (DBusServerUnix*) server;
+ DBusServer *server = data;
+ DBusServerUnix *unix_server = data;
_dbus_assert (watch == unix_server->watch);
static DBusServerVTable unix_vtable = {
unix_finalize,
- unix_handle_watch,
unix_disconnect
};
{
DBusServerUnix *unix_server;
DBusWatch *watch;
+
+ unix_server = dbus_new0 (DBusServerUnix, 1);
+ if (unix_server == NULL)
+ return NULL;
watch = _dbus_watch_new (fd,
DBUS_WATCH_READABLE,
- TRUE);
+ TRUE,
+ unix_handle_watch, unix_server,
+ NULL);
if (watch == NULL)
- return NULL;
-
- unix_server = dbus_new0 (DBusServerUnix, 1);
- if (unix_server == NULL)
{
- _dbus_watch_unref (watch);
+ dbus_free (unix_server);
return NULL;
}
}
/**
- * Called to notify the server when a previously-added watch
- * is ready for reading or writing, or has an exception such
- * as a hangup.
- *
- * If this function returns #FALSE, then the file descriptor may still
- * be ready for reading or writing, but more memory is needed in order
- * to do the reading or writing. If you ignore the #FALSE return, your
- * application may spin in a busy loop on the file descriptor until
- * memory becomes available, but nothing more catastrophic should
- * happen.
- *
- * @param server the server.
- * @param watch the watch.
- * @param condition the current condition of the file descriptors being watched.
- */
-dbus_bool_t
-dbus_server_handle_watch (DBusServer *server,
- DBusWatch *watch,
- unsigned int condition)
-{
- _dbus_assert (server->vtable->handle_watch != NULL);
-
- _dbus_watch_sanitize_condition (watch, &condition);
-
- return (* server->vtable->handle_watch) (server, watch, condition);
-}
-
-/**
* Sets the authentication mechanisms that this server offers
* to clients, as a list of SASL mechanisms. This function
* only affects connections created *after* it is called.
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-server.h DBusServer object
*
- * Copyright (C) 2002 Red Hat Inc.
+ * Copyright (C) 2002, 2003 Red Hat Inc.
*
* Licensed under the Academic Free License version 1.2
*
DBusTimeoutToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function);
-dbus_bool_t dbus_server_handle_watch (DBusServer *server,
- DBusWatch *watch,
- unsigned int condition);
dbus_bool_t dbus_server_set_auth_mechanisms (DBusServer *server,
const char **mechanisms);
free_data_function);
}
-/**
- * Handles watch when descriptors are ready.
- *
- * @param sitter the babysitter.
- * @param watch the watch object
- * @param condition the descriptor conditions
- * @returns #FALSE if there wasn't enough memory.
- *
- */
-dbus_bool_t
-_dbus_babysitter_handle_watch (DBusBabysitter *sitter,
- DBusWatch *watch,
- unsigned int condition)
+static dbus_bool_t
+handle_watch (DBusWatch *watch,
+ unsigned int condition,
+ void *data)
{
+ DBusBabysitter *sitter = data;
int revents;
int fd;
*/
sitter->error_watch = _dbus_watch_new (child_err_report_pipe[READ_END],
DBUS_WATCH_READABLE,
- TRUE);
+ TRUE, handle_watch, sitter, NULL);
if (sitter->error_watch == NULL)
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
sitter->sitter_watch = _dbus_watch_new (babysitter_pipe[0],
DBUS_WATCH_READABLE,
- TRUE);
+ TRUE, handle_watch, sitter, NULL);
if (sitter->sitter_watch == NULL)
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
DBusWatchToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function);
-dbus_bool_t _dbus_babysitter_handle_watch (DBusBabysitter *sitter,
- DBusWatch *watch,
- unsigned int condition);
-
-
DBUS_END_DECLS;
* Gets user info for the given user ID.
*
* @param info user info object to initialize
- * @param username the username
+ * @param uid the user ID
* @param error error return
* @returns #TRUE on success
*/
#endif /* ! HAVE_GETPWNAM_R */
}
+/**
+ * Initializes the given DBusGroupInfo struct
+ * with information about the given group name.
+ *
+ * @param info the group info struct
+ * @param groupname name of group
+ * @param error the error return
+ * @returns #FALSE if error is set
+ */
dbus_bool_t
_dbus_group_info_fill (DBusGroupInfo *info,
const DBusString *groupname,
}
+/**
+ * Initializes the given DBusGroupInfo struct
+ * with information about the given group ID.
+ *
+ * @param info the group info struct
+ * @param gid group ID
+ * @param error the error return
+ * @returns #FALSE if error is set
+ */
dbus_bool_t
_dbus_group_info_fill_gid (DBusGroupInfo *info,
dbus_gid_t gid,
unix_connection_set (DBusTransport *transport)
{
DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
+
+ _dbus_watch_set_handler (unix_transport->write_watch,
+ _dbus_connection_handle_watch,
+ transport->connection, NULL);
+
+ _dbus_watch_set_handler (unix_transport->read_watch,
+ _dbus_connection_handle_watch,
+ transport->connection, NULL);
if (!_dbus_connection_add_watch (transport->connection,
unix_transport->write_watch))
unix_transport->write_watch = _dbus_watch_new (fd,
DBUS_WATCH_WRITABLE,
- FALSE);
+ FALSE,
+ NULL, NULL, NULL);
if (unix_transport->write_watch == NULL)
goto failed_2;
unix_transport->read_watch = _dbus_watch_new (fd,
DBUS_WATCH_READABLE,
- FALSE);
+ FALSE,
+ NULL, NULL, NULL);
if (unix_transport->read_watch == NULL)
goto failed_3;
/** @} */
#ifdef DBUS_BUILD_TESTS
+#include <stdio.h>
+
/**
* Unit test for dbus-userdb.c.
*
int refcount; /**< Reference count */
int fd; /**< File descriptor. */
unsigned int flags; /**< Conditions to watch. */
+
+ DBusWatchHandler handler; /**< Watch handler. */
+ void *handler_data; /**< Watch handler data. */
+ DBusFreeFunction free_handler_data_function; /**< Free the watch handler data. */
+
void *data; /**< Application data. */
DBusFreeFunction free_data_function; /**< Free the application data. */
unsigned int enabled : 1; /**< Whether it's enabled. */
};
/**
- * Creates a new DBusWatch. Normally used by a DBusTransport
- * implementation.
+ * Creates a new DBusWatch. Used to add a file descriptor to be polled
+ * by a main loop.
+ *
* @param fd the file descriptor to be watched.
* @param flags the conditions to watch for on the descriptor.
* @param enabled the initial enabled state
+ * @param handler the handler function
+ * @param data data for handler function
+ * @param free_data_function function to free the data
* @returns the new DBusWatch object.
*/
DBusWatch*
-_dbus_watch_new (int fd,
- unsigned int flags,
- dbus_bool_t enabled)
+_dbus_watch_new (int fd,
+ unsigned int flags,
+ dbus_bool_t enabled,
+ DBusWatchHandler handler,
+ void *data,
+ DBusFreeFunction free_data_function)
{
DBusWatch *watch;
watch->flags = flags;
watch->enabled = enabled;
+ watch->handler = handler;
+ watch->handler_data = data;
+ watch->free_handler_data_function = free_data_function;
+
return watch;
}
if (watch->refcount == 0)
{
dbus_watch_set_data (watch, NULL, NULL); /* call free_data_function */
+
+ if (watch->free_handler_data_function)
+ (* watch->free_handler_data_function) (watch->handler_data);
+
dbus_free (watch);
}
}
watch_list->watch_data);
}
+/**
+ * Sets the handler for the watch.
+ *
+ * @todo this function only exists because of the weird
+ * way connection watches are done, see the note
+ * in docs for _dbus_connection_handle_watch().
+ *
+ * @param watch the watch
+ * @param handler the new handler
+ * @param data the data
+ * @param free_data_function free data with this
+ */
+void
+_dbus_watch_set_handler (DBusWatch *watch,
+ DBusWatchHandler handler,
+ void *data,
+ DBusFreeFunction free_data_function)
+{
+ if (watch->free_handler_data_function)
+ (* watch->free_handler_data_function) (watch->handler_data);
+
+ watch->handler = handler;
+ watch->handler_data = data;
+ watch->free_handler_data_function = free_data_function;
+}
+
/** @} */
/**
return watch->enabled;
}
+
+/**
+ * Called to notify the D-BUS library when a previously-added watch is
+ * ready for reading or writing, or has an exception such as a hangup.
+ *
+ * If this function returns #FALSE, then the file descriptor may still
+ * be ready for reading or writing, but more memory is needed in order
+ * to do the reading or writing. If you ignore the #FALSE return, your
+ * application may spin in a busy loop on the file descriptor until
+ * memory becomes available, but nothing more catastrophic should
+ * happen.
+ *
+ * dbus_watch_handle() cannot be called during the
+ * DBusAddWatchFunction, as the connection will not be ready to handle
+ * that watch yet.
+ *
+ * It is not allowed to reference a DBusWatch after it has been passed
+ * to remove_function.
+ *
+ * @param watch the DBusWatch object.
+ * @param flags the poll condition using #DBusWatchFlags values
+ * @returns #FALSE if there wasn't enough memory
+ */
+dbus_bool_t
+dbus_watch_handle (DBusWatch *watch,
+ unsigned int flags)
+{
+ _dbus_watch_sanitize_condition (watch, &flags);
+
+ if (flags == 0)
+ {
+ _dbus_verbose ("After sanitization, watch flags on fd %d were 0\n",
+ watch->fd);
+ return TRUE;
+ }
+ else
+ return (* watch->handler) (watch, flags,
+ watch->handler_data);
+}
+
+
/** @} */
typedef struct DBusWatchList DBusWatchList;
-DBusWatch* _dbus_watch_new (int fd,
- 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);
+typedef dbus_bool_t (* DBusWatchHandler) (DBusWatch *watch,
+ unsigned int flags,
+ void *data);
+
+DBusWatch* _dbus_watch_new (int fd,
+ unsigned int flags,
+ dbus_bool_t enabled,
+ DBusWatchHandler handler,
+ void *data,
+ DBusFreeFunction free_data_function);
+void _dbus_watch_ref (DBusWatch *watch);
+void _dbus_watch_unref (DBusWatch *watch);
+void _dbus_watch_invalidate (DBusWatch *watch);
+void _dbus_watch_sanitize_condition (DBusWatch *watch,
+ unsigned int *condition);
+void _dbus_watch_set_handler (DBusWatch *watch,
+ DBusWatchHandler handler,
+ void *data,
+ DBusFreeFunction free_data_function);
-void _dbus_watch_sanitize_condition (DBusWatch *watch,
- unsigned int *condition);
DBusWatchList* _dbus_watch_list_new (void);
void _dbus_watch_list_free (DBusWatchList *watch_list);
GList *copy, *list;
/* We need to traverse a copy of the list, since it can change in
- dbus_connect_handle_watch. */
+ dbus_watch_handle(). */
copy = g_list_copy (dbus_source->poll_fds);
list = copy;
if (poll_fd->revents & G_IO_HUP)
condition |= DBUS_WATCH_HANGUP;
- if (is_server)
- dbus_server_handle_watch (dbus_source->connection_or_server,
- watch, condition);
- else
- dbus_connection_handle_watch (dbus_source->connection_or_server,
- watch, condition);
+ dbus_watch_handle (watch, condition);
}
list = list->next;
unsigned int condition,
void *data)
{
- CData *cd = data;
- dbus_bool_t retval;
-
- retval = dbus_connection_handle_watch (cd->connection, watch, condition);
-
- return retval;
+ return dbus_watch_handle (watch, condition);
}
static dbus_bool_t