Bug 54270

Summary: Don't run the TplLogEventFilter from a separate thread
Product: Telepathy Reporter: Debarshi Ray <rishi.is>
Component: loggerAssignee: Telepathy bugs list <telepathy-bugs>
Status: RESOLVED FIXED QA Contact: Telepathy bugs list <telepathy-bugs>
Severity: normal    
Priority: medium    
Version: git master   
Hardware: Other   
OS: All   
URL: http://cgit.freedesktop.org/~debarshir/telepathy-logger/log/?h=event-filter
Whiteboard:
i915 platform: i915 features:

Description Debarshi Ray 2012-08-30 15:18:47 UTC
The TplLogEventFilter function used by  tpl_log_manager_get_filtered_events_async and the new TplLogWalker API should not be run from a thread other than the one from which the API was called. Empathy, which uses a filter function while retrieving the logs, calls telepathy-glib methods from its filter which leads to bad things as tp-glib is not thread safe.
Comment 1 Debarshi Ray 2012-08-31 13:26:45 UTC
I have fixed the TplLogWalker API so that the filter is always called from the same thread that invoked the walker.

Added some test cases that use a filter for get_events and rewind too.

See the attached branch.
Comment 2 Nicolas Dufresne 2012-09-04 16:30:40 UTC
I have simplified your branch a bit. I removed the callback indirection, by setting the real callback/user_data in the GSimpleAsyncResult. I also fixed events leak in an unlikely case that get_events_finish() is not called and used complete_in_idle() instead of g_idle_add().

http://cgit.collabora.com/git/user/nicolas/telepathy-logger.git/log/?h=event-filter

The remaining issue is the lock in get_events_async(). Calling this method a second time before the previous call has finish has undefined result according to mutex documentation.
Comment 3 Debarshi Ray 2013-01-09 16:18:59 UTC
The lock was used to serialize multiple calls get_events and rewind at a time when both the async operations were implemented in a thread. Now only rewind is done in a thread, but not get_events.

So you are correct that two successive calls to get_events will now cause problems because it is not implemented in a thread anymore.

I was looking at using a queue to do the serialization now. So if you make the following calls without returning to the main loop:
 - get_events
 - get_events
 - rewind
 - get_events
... they will be kept in the queue and executed in FIFO order one by one.

However I am wondering how we could hook into the completion of an operation (eg., rewind which is done using g_simple_async_result_run_in_thread). When an operation completes we want to check if there are pending operations in the queue and if so, execute them.
Comment 4 Debarshi Ray 2013-01-10 14:59:13 UTC
As discussed in #telepathy, I restored the wrapper callbacks for get_events and rewind (but not fill_cache) to hook into their completion stage.

The latest version of the code is in my branch:
http://cgit.freedesktop.org/~debarshir/telepathy-logger/log/?h=event-filter
Comment 5 Nicolas Dufresne 2013-01-10 15:51:32 UTC
Only problem I see atm is that GQueue is not threadsafe. I know there exist GAsyncQueue, which is thread safe queue specialised to thread communication. If that does not work, then I guess protecting the GQueue with a mutex would be sufficient.
Comment 6 Debarshi Ray 2013-01-10 17:31:46 UTC
Accesses to the queue are not made from run_in_thread, but only from the main thread, so it should be ok.
Comment 7 Debarshi Ray 2013-01-15 16:16:26 UTC
From #telepathy:

<rishi> stormer: Any other comments on the walker refactoring?
<stormer> rishi: nop, you got my ++

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.