summaryrefslogtreecommitdiff
path: root/daemon/gvfsbackendmtp.h
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2016-04-10 10:44:46 -0700
committerPhilip Langdale <philipl@overt.org>2016-04-15 08:44:03 -0700
commite625ffe4fbab40a1b2d25a67308c8dafe8e71212 (patch)
tree237a538c4851458573fc83fb8a6f1bbedc54505a /daemon/gvfsbackendmtp.h
parent50f92a55e8a08855cb684eedcc7eed5eeee01e4f (diff)
downloadgvfs-e625ffe4fbab40a1b2d25a67308c8dafe8e71212.tar.gz
MTP: Move handling of events to a thread pool
In the next, and hopefully final, change in this series, I'm going to introduce a new way of checking for events that avoids the race condition which can lead to crashes on unmount in the current code. As part of that, event handling must move off the checking thread to a separate thread. But even the existing checking mechanism could stand to benefit from using a separate thread. It's generally undesirable for a thread that's polling for activity to potentially block for a long time, and this is what could happen today if there's a long transfer happening when an event comes in. With the separate handler thread, we can dispatch the work and then resume polling for activity quickly. I used a single-thread thread pool to handle the heavy lifting of queuing events - there's no benefit to writing that yourself. Finally, some thoughts on synchronization: 1) The thread pool has the lifetime of the backend. It is important not to tie it to mount state, as this would lead to requiring holding the backend mutex to know it is safe to push an event to the pool, and that brings us back to potentially blocking the checking thread again. 2) While the thread pool needs the extended lifetime, we don't want to handle events once unmount has started. We enforce this in two ways. a) We set the pool thread count to 0 in unmount. From here on, newly queued events will not get dispatched. b) We reorder the checks in handle_event() so that it always attempts to take the backend mutex first. After taking the mutex, it will check if an unmount is underway. This ensures that either an unmount has not started and it is safe to handle the event, or the unmount is complete, and we know we should drop the event.
Diffstat (limited to 'daemon/gvfsbackendmtp.h')
-rw-r--r--daemon/gvfsbackendmtp.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/daemon/gvfsbackendmtp.h b/daemon/gvfsbackendmtp.h
index a62f3263..0669f94f 100644
--- a/daemon/gvfsbackendmtp.h
+++ b/daemon/gvfsbackendmtp.h
@@ -65,6 +65,10 @@ struct _GVfsBackendMtp
gboolean android_extension;
gboolean get_partial_object_capability;
+
+#ifdef HAVE_LIBMTP_1_1_5
+ GThreadPool *event_pool;
+#endif
};
struct _GVfsBackendMtpClass