dbus_bool_t disconnected; /**< TRUE if disconnect has been called */
};
+/* FIXME not threadsafe (right now the test suite doesn't use threads anyhow ) */
static DBusHashTable *server_pipe_hash;
+static int server_pipe_hash_refcount = 0;
+static dbus_bool_t
+pipe_hash_ref (void)
+{
+ if (!server_pipe_hash)
+ {
+ _dbus_assert (server_pipe_hash_refcount == 0);
+
+ server_pipe_hash = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, NULL);
+
+ if (!server_pipe_hash)
+ return FALSE;
+ }
+
+ server_pipe_hash_refcount = 1;
+
+ return TRUE;
+}
+
+static void
+pipe_hash_unref (void)
+{
+ _dbus_assert (server_pipe_hash != NULL);
+ _dbus_assert (server_pipe_hash_refcount > 0);
+
+ server_pipe_hash_refcount -= 1;
+ if (server_pipe_hash_refcount == 0)
+ {
+ _dbus_hash_table_unref (server_pipe_hash);
+ server_pipe_hash = NULL;
+ }
+}
static void
debug_finalize (DBusServer *server)
{
+ DBusServerDebugPipe *debug_server = (DBusServerDebugPipe*) server;
+
+ pipe_hash_unref ();
+
_dbus_server_finalize_base (server);
+ dbus_free (debug_server->name);
dbus_free (server);
}
-static void
+static dbus_bool_t
debug_handle_watch (DBusServer *server,
DBusWatch *watch,
unsigned int flags)
{
-
+
+ return TRUE;
}
static void
* Creates a new debug server using an in-process pipe
*
* @param server_name the name of the server.
- * @param result address where a result code can be returned.
+ * @param error address where an error can be returned.
* @returns a new server, or #NULL on failure.
*/
DBusServer*
_dbus_server_debug_pipe_new (const char *server_name,
- DBusResultCode *result)
+ DBusError *error)
{
DBusServerDebugPipe *debug_server;
-
- if (!server_pipe_hash)
- {
- server_pipe_hash = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, NULL);
-
- if (!server_pipe_hash)
- {
- dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
- return NULL;
- }
- }
-
+ DBusString address;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ if (!pipe_hash_ref ())
+ return NULL;
+
if (_dbus_hash_table_lookup_string (server_pipe_hash, server_name) != NULL)
{
- dbus_set_result (result, DBUS_RESULT_ADDRESS_IN_USE);
+ dbus_set_error (error, DBUS_ERROR_ADDRESS_IN_USE, NULL);
+ pipe_hash_unref ();
return NULL;
}
debug_server = dbus_new0 (DBusServerDebugPipe, 1);
-
if (debug_server == NULL)
- return NULL;
+ goto nomem_0;
+ if (!_dbus_string_init (&address))
+ goto nomem_1;
+
+ if (!_dbus_string_append (&address, "debug-pipe:name=") ||
+ !_dbus_string_append (&address, server_name))
+ goto nomem_2;
+
debug_server->name = _dbus_strdup (server_name);
if (debug_server->name == NULL)
- {
- dbus_free (debug_server->name);
- dbus_free (debug_server);
-
- dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
- }
+ goto nomem_2;
if (!_dbus_server_init_base (&debug_server->base,
- &debug_vtable))
- {
- dbus_free (debug_server->name);
- dbus_free (debug_server);
-
- dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
-
- return NULL;
- }
+ &debug_vtable, &address))
+ goto nomem_3;
if (!_dbus_hash_table_insert_string (server_pipe_hash,
debug_server->name,
debug_server))
- {
- _dbus_server_finalize_base (&debug_server->base);
- dbus_free (debug_server->name);
- dbus_free (debug_server);
+ goto nomem_4;
- dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
+ _dbus_string_free (&address);
- return NULL;
- }
-
- dbus_set_result (result, DBUS_RESULT_SUCCESS);
+ /* server keeps the pipe hash ref */
return (DBusServer *)debug_server;
+
+ nomem_4:
+ _dbus_server_finalize_base (&debug_server->base);
+ nomem_3:
+ dbus_free (debug_server->name);
+ nomem_2:
+ _dbus_string_free (&address);
+ nomem_1:
+ dbus_free (debug_server);
+ nomem_0:
+ pipe_hash_unref ();
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return NULL;
}
/**
* given debug-pipe server name.
*
* @param server_name name of server to connect to
- * @param result return location for result
+ * @param error address where an error can be returned.
* @returns #NULL on no memory or transport
*/
DBusTransport*
_dbus_transport_debug_pipe_new (const char *server_name,
- DBusResultCode *result)
+ DBusError *error)
{
DBusTransport *client_transport;
DBusTransport *server_transport;
DBusConnection *connection;
int client_fd, server_fd;
DBusServer *server;
-
+ DBusString address;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
server = _dbus_hash_table_lookup_string (server_pipe_hash,
server_name);
if (server == NULL ||
((DBusServerDebugPipe*)server)->disconnected)
{
- dbus_set_result (result, DBUS_RESULT_BAD_ADDRESS);
+ dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, NULL);
+ return NULL;
+ }
+
+ if (!_dbus_string_init (&address))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return NULL;
+ }
+
+ if (!_dbus_string_append (&address, "debug-pipe:name=") ||
+ !_dbus_string_append (&address, server_name))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ _dbus_string_free (&address);
return NULL;
}
NULL))
{
_dbus_verbose ("failed to create full duplex pipe\n");
- dbus_set_result (result, DBUS_RESULT_FAILED);
+ dbus_set_error (error, DBUS_ERROR_FAILED, "Could not create full-duplex pipe");
+ _dbus_string_free (&address);
return NULL;
}
_dbus_fd_set_close_on_exec (server_fd);
client_transport = _dbus_transport_new_for_fd (client_fd,
- FALSE);
+ FALSE, &address);
if (client_transport == NULL)
{
_dbus_close (client_fd, NULL);
_dbus_close (server_fd, NULL);
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ _dbus_string_free (&address);
return NULL;
}
+ _dbus_string_free (&address);
+
client_fd = -1;
server_transport = _dbus_transport_new_for_fd (server_fd,
- TRUE);
+ TRUE, NULL);
if (server_transport == NULL)
{
_dbus_transport_unref (client_transport);
_dbus_close (server_fd, NULL);
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return NULL;
}
if (connection == NULL)
{
_dbus_transport_unref (client_transport);
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return NULL;
}