diff options
author | stanisc <stanisc@chromium.org> | 2014-10-20 15:11:35 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-20 22:11:53 +0000 |
commit | 8e84bfcc1c33fc0b63392d48ee8288d73f4a7675 (patch) | |
tree | 1d30a9a94debea734f9f7955f8a607eac1acbf70 /ppapi/nacl_irt/plugin_main.h | |
parent | 63f233bcd3a8a6d7f3cfb5183b62160c96ded98e (diff) | |
download | chromium_src-8e84bfcc1c33fc0b63392d48ee8288d73f4a7675.zip chromium_src-8e84bfcc1c33fc0b63392d48ee8288d73f4a7675.tar.gz chromium_src-8e84bfcc1c33fc0b63392d48ee8288d73f4a7675.tar.bz2 |
Sync: Avoid deadlock in SyncBackendRegistrar / ModelSafeWorker on sync backend shutdown.
This deadlock involves SyncBackendRegistrar running on the sync thread and at least two
workers - one of them (worker A) running on UI thread and
another (worker B) running on some other background thread.
In this particular case it was a password worker running on Password model thread.
The deadlock occurs when the SyncBackendRegistrar shutdown
code running in the sync thread blocks on a waitable event
set by worker B, at the same time the worker B's thread is
blocked for whatever reason waiting to make a synchronous
call into the UI thread, and at the same time the worker A
is blocked on a lock owned by the sync thread while it attempts
to unregister itself with SyncBackendRegistrar.
I think the main issue here is that the sync thread might
block on a worker. This is possible in only one situation -
when that worker hasn't have a chance to run any tasks because
its own thread was blocked doing something else.
The fix removes this dependency. The only reason this
blocking occurs is because ModelSafeWorker has a mechanism
for subscribing / unsubscribing to the MessageLoop descruction
which has to be done in the right thread context.
In order to unsubscribe the worker needs to remember the message loop it runs on which is done
in SetWorkingLoopToCurrent callback, which is called from a task
posted on the worker's thread. There is also a waitable
event which is signalled at that time. The even is used to
block ModelSafeWorker::UnregisterForLoopDestruction from
delegating the call on an uninitialized message loop which
is possible only when SetWorkingLoopToCurrent has never been called.
There is no need to block in UnregisterForLoopDestruction.
If the registration for even loop destruction hasn't been
been done yet (because the thread is blocked) then there
really no reason to wait for that and then immediately
unsubscribe. We can skip both subscription to the even loop
notification altogether and let the registrar know that
it is OK to remove the worker. That's essentially what the
fix does.
I added a test that verifies that SyncBackendRegistrar::Shutdown
doesn't block on a blocked model type thread anymore.
BUG=423078
Review URL: https://codereview.chromium.org/637413003
Cr-Commit-Position: refs/heads/master@{#300350}
Diffstat (limited to 'ppapi/nacl_irt/plugin_main.h')
0 files changed, 0 insertions, 0 deletions