summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-server-unix.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2005-02-13 17:16:25 +0000
committerHavoc Pennington <hp@redhat.com>2005-02-13 17:16:25 +0000
commitf349e6b8c50ea6faa48c8261198cf1b07bf59a79 (patch)
tree80661925d7864c5772e3c5999c131a068ea549e4 /dbus/dbus-server-unix.c
parent970be5fda36ea575973a9e7f25389e2ef173b940 (diff)
2005-02-13 Havoc Pennington <hp@redhat.com>
* dbus/dbus-object-tree.c (handle_default_introspect_and_unlock): fix a double-unlock * dbus/dbus-connection.c (_dbus_connection_detach_pending_call_unlocked): add this Initial semi-correct pass through to fix thread locking; there are still some issues with the condition variable paths I'm pretty sure * dbus/dbus-server.c: add a mutex on DBusServer and appropriate lock/unlock calls * dbus/dbus-connection.c (_dbus_connection_do_iteration_unlocked): rename to add _unlocked (struct DBusConnection): move "dispatch_acquired" and "io_path_acquired" to use only one bit each. (CONNECTION_LOCK, CONNECTION_UNLOCK): add checks with !DBUS_DISABLE_CHECKS (dbus_connection_set_watch_functions): hacky fix to reentrancy (_dbus_connection_add_watch, _dbus_connection_remove_watch) (_dbus_connection_toggle_watch, _dbus_connection_add_timeout) (_dbus_connection_remove_timeout) (_dbus_connection_toggle_timeout): drop lock when calling out to user functions; done in a hacky/bad way. (_dbus_connection_send_and_unlock): add a missing unlock (_dbus_connection_block_for_reply): add a missing unlock * dbus/dbus-transport.c (_dbus_transport_get_is_authenticated): drop lock in a hacky probably unsafe way to call out to user function
Diffstat (limited to 'dbus/dbus-server-unix.c')
-rw-r--r--dbus/dbus-server-unix.c55
1 files changed, 42 insertions, 13 deletions
diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c
index f576b427..4a07f149 100644
--- a/dbus/dbus-server-unix.c
+++ b/dbus/dbus-server-unix.c
@@ -72,21 +72,29 @@ unix_finalize (DBusServer *server)
*/
/* Return value is just for memory, not other failures. */
static dbus_bool_t
-handle_new_client_fd (DBusServer *server,
- int client_fd)
+handle_new_client_fd_and_unlock (DBusServer *server,
+ int client_fd)
{
DBusConnection *connection;
DBusTransport *transport;
+ DBusNewConnectionFunction new_connection_function;
+ void *new_connection_data;
_dbus_verbose ("Creating new client connection with fd %d\n", client_fd);
-
+
+ HAVE_LOCK_CHECK (server);
+
if (!_dbus_set_fd_nonblocking (client_fd, NULL))
- return TRUE;
+ {
+ SERVER_UNLOCK (server);
+ return TRUE;
+ }
transport = _dbus_transport_new_for_fd (client_fd, TRUE, NULL);
if (transport == NULL)
{
close (client_fd);
+ SERVER_UNLOCK (server);
return FALSE;
}
@@ -94,6 +102,7 @@ handle_new_client_fd (DBusServer *server,
(const char **) server->auth_mechanisms))
{
_dbus_transport_unref (transport);
+ SERVER_UNLOCK (server);
return FALSE;
}
@@ -103,19 +112,27 @@ handle_new_client_fd (DBusServer *server,
connection = _dbus_connection_new_for_transport (transport);
_dbus_transport_unref (transport);
+ transport = NULL; /* now under the connection lock */
if (connection == NULL)
- return FALSE;
+ {
+ SERVER_UNLOCK (server);
+ return FALSE;
+ }
- /* See if someone wants to handle this new connection,
- * self-referencing for paranoia
+ /* See if someone wants to handle this new connection, self-referencing
+ * for paranoia.
*/
- if (server->new_connection_function)
+ new_connection_function = server->new_connection_function;
+ new_connection_data = server->new_connection_data;
+
+ _dbus_server_ref_unlocked (server);
+ SERVER_UNLOCK (server);
+
+ if (new_connection_function)
{
- dbus_server_ref (server);
-
- (* server->new_connection_function) (server, connection,
- server->new_connection_data);
+ (* new_connection_function) (server, connection,
+ new_connection_data);
dbus_server_unref (server);
}
@@ -133,6 +150,8 @@ unix_handle_watch (DBusWatch *watch,
DBusServer *server = data;
DBusServerUnix *unix_server = data;
+ SERVER_LOCK (server);
+
_dbus_assert (watch == unix_server->watch);
_dbus_verbose ("Handling client connection, flags 0x%x\n", flags);
@@ -155,12 +174,14 @@ unix_handle_watch (DBusWatch *watch,
else
_dbus_verbose ("Failed to accept a client connection: %s\n",
_dbus_strerror (errno));
+
+ SERVER_UNLOCK (server);
}
else
{
_dbus_fd_set_close_on_exec (client_fd);
- if (!handle_new_client_fd (server, client_fd))
+ if (!handle_new_client_fd_and_unlock (server, client_fd))
_dbus_verbose ("Rejected client connection due to lack of memory\n");
}
}
@@ -246,6 +267,10 @@ _dbus_server_new_for_fd (int fd,
return NULL;
}
+#ifndef DBUS_DISABLE_CHECKS
+ unix_server->base.have_server_lock = TRUE;
+#endif
+
if (!_dbus_server_add_watch (&unix_server->base,
watch))
{
@@ -254,6 +279,10 @@ _dbus_server_new_for_fd (int fd,
dbus_free (unix_server);
return NULL;
}
+
+#ifndef DBUS_DISABLE_CHECKS
+ unix_server->base.have_server_lock = FALSE;
+#endif
unix_server->fd = fd;
unix_server->watch = watch;