diff options
author | Philip Langdale <philipl@overt.org> | 2016-04-10 10:44:46 -0700 |
---|---|---|
committer | Philip Langdale <philipl@overt.org> | 2016-04-15 08:44:03 -0700 |
commit | e625ffe4fbab40a1b2d25a67308c8dafe8e71212 (patch) | |
tree | 237a538c4851458573fc83fb8a6f1bbedc54505a /daemon/gvfsbackendmtp.h | |
parent | 50f92a55e8a08855cb684eedcc7eed5eeee01e4f (diff) | |
download | gvfs-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.h | 4 |
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 |