name watching: fix for freeing client prematurely 78/107178/1
authorAdrian Szyndela <adrian.s@samsung.com>
Thu, 22 Dec 2016 11:57:32 +0000 (12:57 +0100)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Tue, 27 Dec 2016 05:17:19 +0000 (21:17 -0800)
commitdc8a71bcd7e904a6419f8e7cd1a772d8a066c95f
tree69e069adeb2c9f8b9e75e98cab3cefb868d77c31
parent70702d2dbbab3732878903e03178b49f48c8ee1c
name watching: fix for freeing client prematurely

on_name_owner_changed() is called with user_data being client
with no additional reference kept (ref_count is most probably 1,
taken with one of g_bus_watch_name*() functions).
This function calls user code through call_vanished_handler()
and call_appeared_handler(). The handlers may decrease client's
reference count by calling g_bus_unwatch_name().
Thus, we need to keep this reference locally to prevent freeing
client.
Note: this is also a bug in upstream glib, but it needs two things to happen:
1. call_vanished_handler must call user code that in turn calls g_bus_unwatch_name().
2. signal NameOwnerChanged for watched name, with not empty old and new owner
- it happens when a name changes its owner.

Note: if g_bus_unwatch_name() is called from other thread than the thread,
whose main context was default while calling g_bus_watch_name*, race condition
may appear. This is not changed. This is glib's design:
https://developer.gnome.org/glib/stable/glib-Threads.html

Quote:
   [...] individual data structure instances are not automatically
   locked for performance reasons. For example, you must coordinate accesses
   to the same GHashTable from multiple threads.

It seems the same applies for data structures kept in global data, but for which
users keep their id, as in the above case.

Change-Id: Iaa125555f6908e05f999e407fb3ba9364995b21b
gio/gdbusnamewatching.c