Commit 3df260c0 authored by Havoc Pennington's avatar Havoc Pennington

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.
parent 88cd5da3
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
......
......@@ -706,8 +706,18 @@ babysitter_watch_callback (DBusWatch *watch,
_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;
......
......@@ -122,9 +122,12 @@ server_watch_callback (DBusWatch *watch,
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
......
......@@ -195,15 +195,15 @@ connection_watch_callback (DBusWatch *watch,
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
......@@ -231,7 +231,7 @@ static void
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);
......@@ -815,7 +815,7 @@ bus_connection_get_name (DBusConnection *connection)
return d->name;
}
/**
/*
* Transactions
*
* Note that this is fairly fragile; in particular, don't try to use
......
......@@ -40,16 +40,12 @@ client_watch_callback (DBusWatch *watch,
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
......
......@@ -38,6 +38,7 @@ typedef enum
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);
......@@ -56,6 +57,9 @@ void _dbus_connection_remove_watch (DBusConnection
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,
......@@ -78,9 +82,6 @@ DBusHandlerResult _dbus_message_handler_handle_message (DBusMessageHandl
DBusConnection *connection,
DBusMessage *message);
DBUS_END_DECLS;
#endif /* DBUS_CONNECTION_INTERNAL_H */
......@@ -115,7 +115,7 @@ struct DBusConnection
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
......@@ -2171,10 +2171,10 @@ dbus_connection_dispatch (DBusConnection *connection)
* 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.
*
......@@ -2366,29 +2366,28 @@ dbus_connection_set_dispatch_status_function (DBusConnection *connec
}
/**
* 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);
......
......@@ -50,7 +50,7 @@ typedef enum
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). */
......@@ -130,9 +130,6 @@ void dbus_connection_set_dispatch_status_function (DBusConnection
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,
......@@ -147,6 +144,8 @@ 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_handle (DBusWatch *watch,
unsigned int flags);
dbus_bool_t dbus_watch_get_enabled (DBusWatch *watch);
int dbus_timeout_get_interval (DBusTimeout *timeout);
......
......@@ -104,7 +104,7 @@ struct DBusMessage
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. */
};
......@@ -115,6 +115,7 @@ enum {
DBUS_MESSAGE_ITER_TYPE_DICT
};
/** typedef for internals of message iterator */
typedef struct DBusMessageRealIter DBusMessageRealIter;
/**
......@@ -1689,7 +1690,7 @@ dbus_message_iter_get_args_valist (DBusMessageIter *iter,
* 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,
......@@ -1825,7 +1826,7 @@ dbus_message_iter_has_next (DBusMessageIter *iter)
/**
* 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
......@@ -2486,7 +2487,7 @@ dbus_message_iter_get_dict_key (DBusMessageIter *iter)
* 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,
......@@ -2789,11 +2790,15 @@ dbus_message_iter_append_string (DBusMessageIter *iter,
}
/**
* 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
......@@ -3003,8 +3008,7 @@ dbus_message_iter_append_array (DBusMessageIter *iter,
* 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
......
......@@ -108,15 +108,6 @@ debug_finalize (DBusServer *server)
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)
{
......@@ -125,7 +116,6 @@ debug_disconnect (DBusServer *server)
static DBusServerVTable debug_vtable = {
debug_finalize,
debug_handle_watch,
debug_disconnect
};
......
......@@ -71,14 +71,6 @@ debug_finalize (DBusServer *server)
{
}
static dbus_bool_t
debug_handle_watch (DBusServer *server,
DBusWatch *watch,
unsigned int flags)
{
return TRUE;
}
static void
debug_disconnect (DBusServer *server)
{
......@@ -86,7 +78,6 @@ debug_disconnect (DBusServer *server)
static DBusServerVTable debug_vtable = {
debug_finalize,
debug_handle_watch,
debug_disconnect
};
......
......@@ -38,13 +38,6 @@ struct DBusServerVTable
{
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
*
......@@ -129,11 +129,12 @@ handle_new_client_fd (DBusServer *server,
}
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);
......@@ -202,7 +203,6 @@ unix_disconnect (DBusServer *server)
static DBusServerVTable unix_vtable = {
unix_finalize,
unix_handle_watch,
unix_disconnect
};
......@@ -225,17 +225,19 @@ _dbus_server_new_for_fd (int fd,
{
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;
}
......
......@@ -609,34 +609,6 @@ dbus_server_set_timeout_functions (DBusServer *server,
data, free_data_function);
}
/**
* 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
......
/* -*- 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
*
......@@ -62,9 +62,6 @@ dbus_bool_t dbus_server_set_timeout_functions (DBusServer *
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);
......
......@@ -678,20 +678,12 @@ _dbus_babysitter_set_watch_functions (DBusBabysitter *sitter,
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;
......@@ -1051,7 +1043,7 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
*/
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);
......@@ -1066,7 +1058,7 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
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);
......
......@@ -52,11 +52,6 @@ dbus_bool_t _dbus_babysitter_set_watch_functions (DBusBabysitter *si
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;
......
......@@ -1520,7 +1520,7 @@ _dbus_user_info_fill (DBusUserInfo *info,
* 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
*/
......@@ -1642,6 +1642,15 @@ fill_group_info (DBusGroupInfo *info,
#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,
......@@ -1652,6 +1661,15 @@ _dbus_group_info_fill (DBusGroupInfo *info,
}
/**
* 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,
......
......@@ -786,6 +786,14 @@ static dbus_bool_t
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))
......@@ -1018,13 +1026,15 @@ _dbus_transport_new_for_fd (int fd,
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;
......
......@@ -784,6 +784,8 @@ _dbus_user_database_get_groupname (DBusUserDatabase *db,
/** @} */
#ifdef DBUS_BUILD_TESTS
#include <stdio.h>
/**
* Unit test for dbus-userdb.c.
*
......
......@@ -38,23 +38,35 @@ struct DBusWatch
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;
......@@ -71,6 +83,10 @@ _dbus_watch_new (int fd,
watch->flags = flags;
watch->enabled = enabled;
watch->handler = handler;
watch->handler_data = data;
watch->free_handler_data_function = free_data_function;
return watch;
}
......@@ -101,6 +117,10 @@ _dbus_watch_unref (DBusWatch *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);
}
}
......@@ -363,6 +383,32 @@ _dbus_watch_list_toggle_watch (DBusWatchList *watch_list,
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;
}
/** @} */
/**
......@@ -467,4 +513,45 @@ dbus_watch_get_enabled (DBusWatch *watch)
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 wa