diff options
author | Ralf Habacker <ralf.habacker@freenet.de> | 2021-10-29 13:02:13 +0200 |
---|---|---|
committer | Ralf Habacker <ralf.habacker@freenet.de> | 2021-11-23 08:38:14 +0100 |
commit | 3f7c36f4b1d290eeb115921820ba945fc467cad3 (patch) | |
tree | 7c9b33b2998c86c58ee9bb43e3e331ee3a3667b4 | |
parent | 18b8883213179a5a14272b2c9dc7772b32e8a549 (diff) | |
download | dbus-3f7c36f4b1d290eeb115921820ba945fc467cad3.tar.gz |
dbus-sysdeps-win.c: Add helper functions to handle events on Windows
These functions are in the dbus library to be used everywhere
-rw-r--r-- | dbus/dbus-sysdeps-win.c | 171 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-win.h | 14 |
2 files changed, 184 insertions, 1 deletions
diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 10a3c4a8..650af7fc 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -6,7 +6,7 @@ * Copyright (C) 2005 Novell, Inc. * Copyright (C) 2006 Peter Kümmel <syntheticpp@gmx.net> * Copyright (C) 2006 Christian Ehrlicher <ch.ehrlicher@gmx.de> - * Copyright (C) 2006-2013 Ralf Habacker <ralf.habacker@freenet.de> + * Copyright (C) 2006-2021 Ralf Habacker <ralf.habacker@freenet.de> * * Licensed under the Academic Free License version 2.1 * @@ -4009,5 +4009,174 @@ _dbus_get_low_level_socket_errno (void) return WSAGetLastError (); } +void +_dbus_win_set_error_from_last_error (DBusError *error, + const char *format, + ...) +{ + const char *name; + char *message = NULL; + + if (error == NULL) + return; + + /* make sure to do this first, in case subsequent library calls overwrite GetLastError() */ + name = _dbus_win_error_from_last_error (); + message = _dbus_win_error_string (GetLastError ()); + + if (format != NULL) + { + DBusString str; + va_list args; + dbus_bool_t retval; + + if (!_dbus_string_init (&str)) + goto out; + + va_start (args, format); + retval = _dbus_string_append_printf_valist (&str, format, args); + va_end (args); + if (!retval) + { + _dbus_string_free (&str); + goto out; + } + + dbus_set_error (error, name, "%s: %s", _dbus_string_get_const_data (&str), message); + _dbus_string_free (&str); + } + else + { + dbus_set_error (error, name, "%s", message); + } + +out: + if (message != NULL) + _dbus_win_free_error_string (message); +} + +/** + * Creates a Windows event object and returns the corresponding handle + * + * The returned object is unnamed, is a manual-reset event object, + * is initially in the non-signalled state, and is inheritable by child + * processes. + * + * @param error the error to set + * @return handle for the created event + * @return #NULL if an error has occurred, the reason is returned in \p error + */ +HANDLE +_dbus_win_event_create_inheritable (DBusError *error) +{ + HANDLE handle; + + handle = CreateEvent (NULL, TRUE, FALSE, NULL); + if (handle == NULL) + { + _dbus_win_set_error_from_last_error (error, "Could not create event"); + return NULL; + } + else if (GetLastError () == ERROR_ALREADY_EXISTS) + { + _dbus_win_set_error_from_last_error (error, "Event already exists"); + return NULL; + } + + if (!SetHandleInformation (handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) + { + _dbus_win_set_error_from_last_error (error, "Could not set inheritance for event %s", handle); + CloseHandle (handle); + return NULL; + } + return handle; +} + +/** + * Set a Windows event to the signalled state + * + * @param handle the handle for the event to be set + * @return TRUE the event was set successfully + * @return FALSE an error has occurred, the reason is returned in \p error + */ +dbus_bool_t +_dbus_win_event_set (HANDLE handle, DBusError *error) +{ + _dbus_assert (handle != NULL); + + if (!SetEvent (handle)) + { + _dbus_win_set_error_from_last_error (error, "Could not trigger event (handle %p)", handle); + return FALSE; + } + return TRUE; +} + +/** + * Wait for a Windows event to enter the signalled state + * + * @param handle the handle for the event to wait for + * @param timeout the waiting time in milliseconds, or INFINITE to wait forever, + * or 0 to check immediately and not wait (polling) + * @param error the error to set + * @return TRUE the event was set successfully + * @return FALSE an error has occurred, the reason is returned in \p error + */ +dbus_bool_t +_dbus_win_event_wait (HANDLE handle, int timeout, DBusError *error) +{ + DWORD status; + + _dbus_assert (handle != NULL); + + status = WaitForSingleObject (handle, timeout); + switch (status) + { + case WAIT_OBJECT_0: + return TRUE; + + case WAIT_FAILED: + { + _dbus_win_set_error_from_last_error (error, "Unable to wait for event (handle %p)", handle); + return FALSE; + } + + case WAIT_TIMEOUT: + /* GetLastError() is not set */ + dbus_set_error (error, DBUS_ERROR_TIMEOUT, "Timed out waiting for event (handle %p)", handle); + return FALSE; + + default: + /* GetLastError() is probably not set? */ + dbus_set_error (error, DBUS_ERROR_FAILED, "Unknown result '%lu' while waiting for event (handle %p)", status, handle); + return FALSE; + } +} + +/** + * Delete a Windows event + * + * @param handle handle for the event to delete + * @param error the error to set (optional) + * @return TRUE the event has been deleted successfully or the handle specifies a #NULL or invalid handle + * @return FALSE an error has occurred, the reason is returned in \p error if specified + */ +dbus_bool_t +_dbus_win_event_free (HANDLE handle, DBusError *error) +{ + if (handle == NULL || handle == INVALID_HANDLE_VALUE) + return TRUE; + + if (CloseHandle (handle)) + return TRUE; + + /* the handle may already be closed */ + if (GetLastError () == ERROR_INVALID_HANDLE) + return TRUE; + + _dbus_win_set_error_from_last_error (error, "Could not close event (handle %p)", handle); + return FALSE; +} + /** @} end of sysdeps-win */ /* tests in dbus-sysdeps-util.c */ diff --git a/dbus/dbus-sysdeps-win.h b/dbus/dbus-sysdeps-win.h index edce99a3..e9932ff5 100644 --- a/dbus/dbus-sysdeps-win.h +++ b/dbus/dbus-sysdeps-win.h @@ -95,6 +95,20 @@ dbus_bool_t _dbus_getsid(char **sid, dbus_pid_t process_id); HANDLE _dbus_spawn_program (const char *name, char **argv, char **envp); +DBUS_PRIVATE_EXPORT +void _dbus_win_set_error_from_last_error (DBusError *error, + const char *format, + ...); + +DBUS_PRIVATE_EXPORT +HANDLE _dbus_win_event_create_inheritable (DBusError *error); +DBUS_PRIVATE_EXPORT +dbus_bool_t _dbus_win_event_set (HANDLE handle, DBusError *error); +DBUS_PRIVATE_EXPORT +dbus_bool_t _dbus_win_event_wait (HANDLE handle, int timeout, DBusError *error); +DBUS_PRIVATE_EXPORT +dbus_bool_t _dbus_win_event_free (HANDLE handle, DBusError *error); + #endif /** @} end of sysdeps-win.h */ |