[PATCH] Handle case when autolaunched daemon address is already published on windows.
Ralf Habacker
ralf.habacker at freenet.de
Mon Dec 13 23:12:59 PST 2010
---
dbus/dbus-server-protected.h | 3 +-
dbus/dbus-server-win.c | 6 +++-
dbus/dbus-server.c | 10 ++++++
dbus/dbus-sysdeps-win.c | 65 +++++++++++++++++++++++++++++++++--------
dbus/dbus-sysdeps.h | 4 ++-
5 files changed, 72 insertions(+), 16 deletions(-)
diff --git a/dbus/dbus-server-protected.h b/dbus/dbus-server-protected.h
index 9e759c1..31976e3 100644
--- a/dbus/dbus-server-protected.h
+++ b/dbus/dbus-server-protected.h
@@ -118,7 +118,8 @@ typedef enum
DBUS_SERVER_LISTEN_NOT_HANDLED, /**< we aren't in charge of this address type */
DBUS_SERVER_LISTEN_OK, /**< we set up the listen */
DBUS_SERVER_LISTEN_BAD_ADDRESS, /**< malformed address */
- DBUS_SERVER_LISTEN_DID_NOT_CONNECT /**< well-formed address but failed to set it up */
+ DBUS_SERVER_LISTEN_DID_NOT_CONNECT, /**< well-formed address but failed to set it up */
+ DBUS_SERVER_LISTEN_ADDRESS_ALREADY_USED /**< address is already used */
} DBusServerListenResult;
DBusServerListenResult _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
diff --git a/dbus/dbus-server-win.c b/dbus/dbus-server-win.c
index 860978d..bf1c896 100644
--- a/dbus/dbus-server-win.c
+++ b/dbus/dbus-server-win.c
@@ -91,18 +91,22 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
const char *family = "ipv4";
const char *scope = dbus_address_entry_get_value (entry, "scope");
+ if (_dbus_daemon_is_session_bus_address_published (scope))
+ return DBUS_SERVER_LISTEN_ADDRESS_ALREADY_USED;
+
*server_p = _dbus_server_new_for_tcp_socket (host, bind, port,
family, error, FALSE);
if (*server_p)
{
_DBUS_ASSERT_ERROR_IS_CLEAR(error);
- /// @todo should we return an error when address could not be published ?
(*server_p)->published_address =
_dbus_daemon_publish_session_bus_address ((*server_p)->address, scope);
return DBUS_SERVER_LISTEN_OK;
}
else
{
+ // make sure no handle is open
+ _dbus_daemon_unpublish_session_bus_address ();
_DBUS_ASSERT_ERROR_IS_SET(error);
return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
}
diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c
index 91fdcb6..60d14b3 100644
--- a/dbus/dbus-server.c
+++ b/dbus/dbus-server.c
@@ -577,6 +577,16 @@ dbus_server_listen (const char *address,
handled_once = TRUE;
goto out;
}
+ else if (result == DBUS_SERVER_LISTEN_ADDRESS_ALREADY_USED)
+ {
+ _dbus_assert (server == NULL);
+ dbus_set_error (error,
+ DBUS_ERROR_ADDRESS_IN_USE,
+ "Address '%s' already used",
+ dbus_address_entry_get_method (entries[0]));
+ handled_once = TRUE;
+ goto out;
+ }
else if (result == DBUS_SERVER_LISTEN_BAD_ADDRESS)
{
_dbus_assert (server == NULL);
diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c
index bacfcb2..024a833 100644
--- a/dbus/dbus-sysdeps-win.c
+++ b/dbus/dbus-sysdeps-win.c
@@ -4,9 +4,9 @@
* Copyright (C) 2002, 2003 Red Hat, Inc.
* Copyright (C) 2003 CodeFactory AB
* Copyright (C) 2005 Novell, Inc.
- * Copyright (C) 2006 Ralf Habacker <ralf.habacker at freenet.de>
* Copyright (C) 2006 Peter Kümmel <syntheticpp at gmx.net>
* Copyright (C) 2006 Christian Ehrlicher <ch.ehrlicher at gmx.de>
+ * Copyright (C) 2006-2010 Ralf Habacker <ralf.habacker at freenet.de>
*
* Licensed under the Academic Free License version 2.1
*
@@ -2623,6 +2623,48 @@ _dbus_get_mutex_name (DBusString *out,const char *scope)
}
dbus_bool_t
+_dbus_daemon_is_session_bus_address_published (const char *scope)
+{
+ HANDLE lock;
+ HANDLE mutex;
+ DBusString mutex_name;
+ DWORD ret;
+
+ if (!_dbus_get_mutex_name(&mutex_name,scope))
+ {
+ _dbus_string_free( &mutex_name );
+ return FALSE;
+ }
+
+ if (hDBusDaemonMutex)
+ return TRUE;
+
+ // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
+ lock = _dbus_global_lock( cUniqueDBusInitMutex );
+
+ // we use CreateMutex instead of OpenMutex because of possible race conditions,
+ // see http://msdn.microsoft.com/en-us/library/ms684315%28VS.85%29.aspx
+ hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
+
+ _dbus_global_unlock( lock );
+
+ _dbus_string_free( &mutex_name );
+
+ if (hDBusDaemonMutex == NULL)
+ return FALSE;
+ if (GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ CloseHandle(hDBusDaemonMutex);
+ hDBusDaemonMutex = NULL;
+ return TRUE;
+ }
+ // mutex wasn't created before, so return false.
+ // We leave the mutex name allocated for later reusage
+ // in _dbus_daemon_publish_session_bus_address.
+ return FALSE;
+}
+
+dbus_bool_t
_dbus_daemon_publish_session_bus_address (const char* address, const char *scope)
{
HANDLE lock;
@@ -2640,24 +2682,22 @@ _dbus_daemon_publish_session_bus_address (const char* address, const char *scope
return FALSE;
}
- // before _dbus_global_lock to keep correct lock/release order
- hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
- ret = WaitForSingleObject( hDBusDaemonMutex, 1000 );
- if ( ret != WAIT_OBJECT_0 ) {
- _dbus_warn("Could not lock mutex %s (return code %d). daemon already running? Bus address not published.\n", _dbus_string_get_const_data(&mutex_name), ret );
- return FALSE;
- }
+ // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
+ lock = _dbus_global_lock( cUniqueDBusInitMutex );
+
+ if (!hDBusDaemonMutex)
+ {
+ hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
+ }
+ _dbus_string_free( &mutex_name );
if (!_dbus_get_shm_name(&shm_name,scope))
{
- _dbus_string_free( &mutex_name );
_dbus_string_free( &shm_name );
+ _dbus_global_unlock( lock );
return FALSE;
}
- // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
- lock = _dbus_global_lock( cUniqueDBusInitMutex );
-
// create shm
hDBusSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
0, strlen( address ) + 1, _dbus_string_get_const_data(&shm_name) );
@@ -2676,7 +2716,6 @@ _dbus_daemon_publish_session_bus_address (const char* address, const char *scope
_dbus_verbose( "published session bus address at %s\n",_dbus_string_get_const_data (&shm_name) );
_dbus_string_free( &shm_name );
- _dbus_string_free( &mutex_name );
return TRUE;
}
diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h
index a0f62ee..eb91957 100644
--- a/dbus/dbus-sysdeps.h
+++ b/dbus/dbus-sysdeps.h
@@ -207,7 +207,9 @@ dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid)
dbus_bool_t _dbus_append_keyring_directory_for_credentials (DBusString *directory,
DBusCredentials *credentials);
-dbus_bool_t _dbus_daemon_publish_session_bus_address (const char* address, const char* shm_address);
+dbus_bool_t _dbus_daemon_is_session_bus_address_published (const char *scope);
+
+dbus_bool_t _dbus_daemon_publish_session_bus_address (const char* address, const char* shm_name);
void _dbus_daemon_unpublish_session_bus_address (void);
--
1.5.6.5
--------------040108060009030807070208--
More information about the dbus
mailing list