diff options
author | Ralf Habacker <ralf.habacker@freenet.de> | 2010-12-14 08:12:59 +0100 |
---|---|---|
committer | Ralf Habacker <ralf.habacker@freenet.de> | 2010-12-14 08:12:59 +0100 |
commit | 4bf509b6fd8309ba7b6e179bd2567b57e8b71b80 (patch) | |
tree | 53b72b70d617ce10ce4a3723a07e4885b86281a3 | |
parent | 3bacc897c70f5585d76df5429c51fa56bb3196cf (diff) |
Handle case when autolaunched daemon address is already pulished on windows.
-rw-r--r-- | dbus/dbus-server-protected.h | 3 | ||||
-rw-r--r-- | dbus/dbus-server-win.c | 6 | ||||
-rw-r--r-- | dbus/dbus-server.c | 10 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-win.c | 65 | ||||
-rw-r--r-- | 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 9e759c17..31976e31 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 860978d2..bf1c896c 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 91fdcb6d..60d14b33 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 bacfcb2a..024a8338 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@freenet.de> * Copyright (C) 2006 Peter Kümmel <syntheticpp@gmx.net> * Copyright (C) 2006 Christian Ehrlicher <ch.ehrlicher@gmx.de> + * Copyright (C) 2006-2010 Ralf Habacker <ralf.habacker@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 a0f62eec..eb919576 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); |