return TRUE;
}
+/**
+ * Get server bus address from shared memory segment provided by running dbus-daemon
+ *
+ * @param address initialized DBusString instance to store the retrieved address
+ * @param shm_name the name of the shared memory segment
+ * @param wait if TRUE wait maximum 2 seconds for the presence of the shared memory segment
+ * @return #TRUE the bus address was fetched from the shared memory segment
+ * @return #FALSE error during execution
+ */
static dbus_bool_t
-_dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name)
+_dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name, dbus_bool_t wait)
{
- HANDLE sharedMem;
+ HANDLE sharedMem = NULL;
char *shared_addr;
int i;
+ int max = 20; /* max 2 seconds */
+ dbus_bool_t retval = FALSE;
+
+ if (!wait)
+ max = 1;
// read shm
- for (i = 0; i < 20; ++i)
+ for (i = 0; i < max; ++i)
{
// we know that dbus-daemon is available, so we wait until shm is available
sharedMem = OpenFileMappingA (FILE_MAP_READ, FALSE, _dbus_string_get_const_data (shm_name));
shared_addr = MapViewOfFile (sharedMem, FILE_MAP_READ, 0, 0, 0);
if (!shared_addr)
- return FALSE;
-
- _dbus_string_init (address);
+ goto out;
- _dbus_string_append (address, shared_addr);
+ retval = _dbus_string_append (address, shared_addr);
- // cleanup
UnmapViewOfFile (shared_addr);
+out:
CloseHandle (sharedMem);
-
- return TRUE;
+ return retval;
}
static dbus_bool_t
goto out;
}
- // read shm
- retval = _dbus_get_autolaunch_shm (address, shm_name);
+ // read shm, wait max 2 seconds
+ retval = _dbus_get_autolaunch_shm (address, shm_name, TRUE);
// cleanup
CloseHandle (daemon);
DBusString dbus_args = _DBUS_STRING_INIT_INVALID;
const char *daemon_name = DBUS_DAEMON_NAME ".exe";
DBusString shm_name;
+ HANDLE ready_event_handle = NULL;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
if (!_dbus_string_append_printf (&dbus_args, "\"%s\" %s", dbus_exe_path,
autolaunch_custom_command_line_parameter ? autolaunch_custom_command_line_parameter : "--session"))
{
- dbus_set_error_const (error, DBUS_ERROR_NO_MEMORY, "Failed to append string to argument buffer");
+ _DBUS_SET_OOM (error);
retval = FALSE;
goto out;
}
- // argv[i] = "--config-file=bus\\session.conf";
- if (CreateProcessA (dbus_exe_path, _dbus_string_get_data (&dbus_args), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
+ ready_event_handle = _dbus_win_event_create_inheritable (error);
+ if (ready_event_handle == NULL)
+ goto out;
+
+ _dbus_verbose ("Creating connection readiness event: handle=%p\n", ready_event_handle);
+ if (!_dbus_string_append_printf (&dbus_args, " \"--ready-event-handle=%p\"", ready_event_handle))
{
+ _DBUS_SET_OOM (error);
+ goto out;
+ }
+
+ _dbus_verbose ("Starting dbus daemon with args: '%s'\n", _dbus_string_get_const_data (&dbus_args));
+ if (CreateProcessA (dbus_exe_path, _dbus_string_get_data (&dbus_args), NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
+ {
+ DWORD status;
+ HANDLE events[2];
+
CloseHandle (pi.hThread);
+
+ _dbus_verbose ("Wait until dbus-daemon is ready for connections (event handle %p)\n", ready_event_handle);
+
+ events[0] = ready_event_handle;
+ events[1] = pi.hProcess;
+ status = WaitForMultipleObjects (2, events, FALSE, 30000);
+
+ switch (status)
+ {
+ case WAIT_OBJECT_0:
+ /* ready event signalled, everything is okay */
+ retval = TRUE;
+ break;
+
+ case WAIT_OBJECT_0 + 1:
+ /* dbus-daemon process has exited */
+ dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED, "dbus-daemon exited before signalling ready");
+ goto out;
+
+ case WAIT_FAILED:
+ _dbus_win_set_error_from_last_error (error, "Unable to wait for server readiness (handle %p)", ready_event_handle);
+ goto out;
+
+ case WAIT_TIMEOUT:
+ /* GetLastError() is not set */
+ dbus_set_error (error, DBUS_ERROR_TIMEOUT, "Timed out waiting for server readiness or exit (handle %p)", ready_event_handle);
+ goto out;
+
+ default:
+ /* GetLastError() is probably not set? */
+ dbus_set_error (error, DBUS_ERROR_FAILED, "Unknown result '%lu' while waiting for server readiness (handle %p)", status, ready_event_handle);
+ goto out;
+ }
+ _dbus_verbose ("Got signal that dbus-daemon is ready for connections\n");
+
if (autolaunch_handle_location != NULL)
{
*autolaunch_handle_location = pi.hProcess;
{
CloseHandle (pi.hProcess);
}
- retval = _dbus_get_autolaunch_shm (address, &shm_name);
+
+ /* do not wait for the appearance of shm, we can assume that it is present */
+ retval = _dbus_get_autolaunch_shm (address, &shm_name, FALSE);
if (retval == FALSE)
dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to get autolaunch address from launched dbus-daemon");
}
_dbus_platform_rmutex_free (lock);
_dbus_string_free (&shm_name);
_dbus_string_free (&dbus_args);
+ if (ready_event_handle)
+ _dbus_win_event_free (ready_event_handle, NULL);
+ _DBUS_ASSERT_ERROR_XOR_BOOL (error, retval);
return retval;
}