Version 4 of the patch: added changes to dbus/dbus-misc.c and
cmake/dbus/dbus-1.def.cmake, i.e. dbus_kde_patch symbol for {lib}dbus-1{d}.
--
regards / pozdrawiam, Jaroslaw Staniek
Sponsored by OpenOffice Polska (http://www.openoffice.com.pl/en) to work on
Kexi & KOffice (http://www.kexi.pl/en, http://www.koffice.org/kexi)
KDE Libraries for MS Windows (http://windows.kde.org)
Index: bus/services.c
===================================================================
--- bus/services.c (wersja 782)
+++ bus/services.c (kopia robocza)
@@ -35,6 +35,10 @@
#include "bus.h"
#include "selinux.h"
+#ifdef DBUS_WIN
+#define DBUS_CLEANUP_OLD_SERVICES
+#endif
+
struct BusService
{
int refcount;
@@ -64,6 +68,9 @@
DBusHashTable *service_hash;
DBusMemPool *service_pool;
DBusMemPool *owner_pool;
+#ifdef DBUS_CLEANUP_OLD_SERVICES
+ DBusHashTable *unique_pid_hash;
+#endif
DBusHashTable *service_sid_table;
};
@@ -85,6 +92,14 @@
if (registry->service_hash == NULL)
goto failed;
+
+#ifdef DBUS_CLEANUP_OLD_SERVICES
+ registry->unique_pid_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
+ dbus_free, NULL);
+ if (registry->unique_pid_hash == NULL)
+ goto failed;
+#endif
+
registry->service_pool = _dbus_mem_pool_new (sizeof (BusService),
TRUE);
@@ -125,6 +140,10 @@
{
if (registry->service_hash)
_dbus_hash_table_unref (registry->service_hash);
+#ifdef DBUS_CLEANUP_OLD_SERVICES
+ if (registry->unique_pid_hash)
+ _dbus_hash_table_unref (registry->unique_pid_hash);
+#endif
if (registry->service_pool)
_dbus_mem_pool_free (registry->service_pool);
if (registry->owner_pool)
@@ -372,10 +391,147 @@
return FALSE;
}
+#ifdef DBUS_CLEANUP_OLD_SERVICES
+#include <stdlib.h>
+#include <windows.h>
+#include <Tlhelp32.h>
+
+int _dbus_get_base_service_name_and_pid (const char *service_name,
+ char **base_service_name)
+{
+ static const char* unique_part = ".unique-";
+ char* unique_part_pos;
+ char* result;
+ int pid;
+ unique_part_pos = strstr (service_name, unique_part);
+ if (unique_part_pos == NULL)
+ return 0;
+ pid = 0;
+ if (strlen(unique_part_pos + 8 /*".unique-"*/) > 0)
+ pid = atoi( unique_part_pos + 8 );
+ if (pid == 0)
+ return 0;
+ result = _dbus_strdup (service_name);
+ result[ unique_part_pos - service_name ] = 0; // cut off before .unique.
+ *base_service_name = result;
+ return pid;
+}
+
+static void
+bus_service_unlink (BusService *service);
+
dbus_bool_t
+_dbus_process_exists (int pid)
+{
+ HANDLE proc_handle;
+ HANDLE hProcessSnap;
+ PROCESSENTRY32 pe32;
+
+ proc_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
+ if (proc_handle == 0)
+ return FALSE;
+ // this process _may_ still exists: do nothing, so
DBUS_REQUEST_NAME_REPLY_EXISTS result will be set
+ CloseHandle (proc_handle);
+ // find out if the process isn't a zombie
+ hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
+ if (hProcessSnap == INVALID_HANDLE_VALUE)
+ return TRUE;
+ pe32.dwSize = sizeof( PROCESSENTRY32 );
+ if (!Process32First(hProcessSnap, &pe32))
+ {
+ CloseHandle (hProcessSnap);
+ return TRUE;
+ }
+ do
+ {
+ if (pe32.th32ProcessID == pid)
+ {
+ CloseHandle (hProcessSnap);
+ return TRUE;
+ }
+ } while (Process32Next (hProcessSnap,&pe32));
+ CloseHandle (hProcessSnap);
+ return FALSE;
+}
+
+int
+_dbus_find_unique_pid (BusRegistry *registry, const char *service_name)
+{
+ return (int)_dbus_hash_table_lookup_string (registry->unique_pid_hash,
+ service_name);
+}
+
+static dbus_bool_t
+_dbus_registry_release_old_service_win_if_unique (BusRegistry *registry,
+ DBusConnection *connection,
+ const char
*base_service_name,
+ int pid,
+ BusTransaction
*transaction,
+ DBusError *error)
+{
+ BusService *service;
+ DBusConnection *connection_to_release;
+ DBusString base_service_name_str;
+ dbus_uint32_t service_reply;
+ char *base_service_name_copy;
+ int old_pid;
+
+ old_pid = _dbus_find_unique_pid (registry, base_service_name);
+ if (pid == old_pid)
+ return TRUE;
+
+ if (old_pid != 0)
+ {
+ if (_dbus_process_exists (old_pid))
+ return TRUE;
+ // no such process:
+ // release old service
+ _dbus_string_init_const (&base_service_name_str, base_service_name);
+ _dbus_verbose ("Attempt to release old unique service \"%s\"",
+ base_service_name);
+ service = bus_registry_lookup (registry, &base_service_name_str);
+ if (service) {
+ struct DBusList *link;
+ BusOwner* owner;
+ link = _dbus_list_get_first_link (&service->owners);
+ owner = (BusOwner *)link->data;
+ connection_to_release = owner->conn;
+ }
+ else
+ {
+ connection_to_release = connection;
+ }
+
+ if (!bus_registry_release_service (registry, connection_to_release,
&base_service_name_str, &service_reply,
+ transaction, error))
+ {
+ _dbus_string_free (&base_service_name_str);
+ dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+ "Cannot release old unique service \"%s\"",
+ base_service_name);
+ return FALSE;
+ }
+ _dbus_string_free (&base_service_name_str);
+ _dbus_verbose ("_dbus_registry_release_old_service_win_if_unique():
Service \"%s\" released\n",
+ base_service_name);
+ }
+ // remember new PID for this service
+ base_service_name_copy = _dbus_strdup (base_service_name);
+ if (!_dbus_hash_table_insert_string (registry->unique_pid_hash,
+ base_service_name_copy,
+ (void*)pid))
+ {
+ dbus_free (base_service_name_copy);
+ return FALSE;
+ }
+ return TRUE;
+}
+#endif
+
+dbus_bool_t
bus_registry_acquire_service (BusRegistry *registry,
DBusConnection *connection,
- const DBusString *service_name,
+ const DBusString *a_service_name,
dbus_uint32_t flags,
dbus_uint32_t *result,
BusTransaction *transaction,
@@ -389,9 +545,28 @@
BusActivation *activation;
BusSELinuxID *sid;
BusOwner *primary_owner;
+ int pid;
+ char *service_name_tmp;
+ DBusString *service_name; // real name
+ DBusString service_name_stack;
retval = FALSE;
+ pid = _dbus_get_base_service_name_and_pid (_dbus_string_get_const_data
(a_service_name),
+ &service_name_tmp);
+ if (pid == 0)
+ {
+ service_name = a_service_name;
+ service_name_tmp = 0;
+ }
+ else
+ {
+ _dbus_string_init_const (&service_name_stack, service_name_tmp);
+ service_name = &service_name_stack;
+ _dbus_registry_release_old_service_win_if_unique (
+ registry, connection, service_name_tmp, pid, transaction, error);
+ }
+
if (!_dbus_validate_bus_name (service_name, 0,
_dbus_string_get_length (service_name)))
{
@@ -594,6 +769,10 @@
error);
out:
+#ifdef DBUS_CLEANUP_OLD_SERVICES
+ if (service_name_tmp)
+ free (service_name_tmp);
+#endif
return retval;
}
@@ -671,6 +850,14 @@
retval = TRUE;
out:
+#ifdef DBUS_CLEANUP_OLD_SERVICES
+ if (retval)
+ {
+ // remove old entry
+ _dbus_hash_table_remove_string (registry->unique_pid_hash,
+
_dbus_string_get_const_data(service_name));
+ }
+#endif
return retval;
}
Index: bus/driver.c
===================================================================
--- bus/driver.c (wersja 782)
+++ bus/driver.c (kopia robocza)
@@ -35,6 +35,10 @@
#include <dbus/dbus-marshal-recursive.h>
#include <string.h>
+#ifdef DBUS_WIN
+#define DBUS_CLEANUP_OLD_SERVICES
+#endif
+
static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
DBusMessage
*hello_message,
BusTransaction
*transaction,
@@ -676,6 +680,11 @@
return retval;
}
+#ifdef DBUS_CLEANUP_OLD_SERVICES
+extern _dbus_process_exists (int pid);
+extern int _dbus_find_unique_pid (BusRegistry *registry, const char
*service_name);
+#endif
+
static dbus_bool_t
bus_driver_handle_service_exists (DBusConnection *connection,
BusTransaction *transaction,
@@ -709,6 +718,15 @@
{
_dbus_string_init_const (&service_name, name);
service = bus_registry_lookup (registry, &service_name);
+
+#ifdef DBUS_CLEANUP_OLD_SERVICES
+ if (service)
+ {
+ int pid = _dbus_find_unique_pid (registry, name);
+ if (pid != 0 && !_dbus_process_exists (pid))
+ service = NULL;
+ }
+#endif
service_exists = service != NULL;
}
Index: dbus/dbus-misc.c
===================================================================
--- dbus/dbus-misc.c (wersja 782)
+++ dbus/dbus-misc.c (kopia robocza)
@@ -170,6 +170,13 @@
*micro_version_p = DBUS_MICRO_VERSION;
}
+/**
+ * Indicates that this is KDE modification of dbus; used in
KUniqueApplication::start().
+ */
+void
+dbus_kde_patch (void)
+{
+}
/** @} */ /* End of public API */
Index: cmake/dbus/dbus-1.def.cmake
===================================================================
--- cmake/dbus/dbus-1.def.cmake (wersja 782)
+++ cmake/dbus/dbus-1.def.cmake (kopia robocza)
@@ -870,3 +870,4 @@
dbus_watch_get_unix_fd
dbus_watch_handle
dbus_watch_set_data
+dbus_kde_patch
_______________________________________________
Kde-windows mailing list
[email protected]
https://mail.kde.org/mailman/listinfo/kde-windows