summaryrefslogtreecommitdiffstats
path: root/runtime/jdwp/jdwp_main.cc
diff options
context:
space:
mode:
authorSebastien Hertz <shertz@google.com>2015-01-09 18:44:05 +0100
committerSebastien Hertz <shertz@google.com>2015-02-06 17:46:58 +0100
commit2bf93f48bbb417b358c9e3c77911ea6ec7307c15 (patch)
tree4a3cbadecf70b370423418d80bd738fc326aa846 /runtime/jdwp/jdwp_main.cc
parentb991d334e294cb9fb75bd1c36e2435171c084cd1 (diff)
downloadart-2bf93f48bbb417b358c9e3c77911ea6ec7307c15.zip
art-2bf93f48bbb417b358c9e3c77911ea6ec7307c15.tar.gz
art-2bf93f48bbb417b358c9e3c77911ea6ec7307c15.tar.bz2
JDWP: update thread synchronization
This CL ensures only one thread can do JDWP stuff at a time: either processing a command coming from the debugger (JDWP thread) or sending an event (breakpoint, class prepare, etc) to the debugger before suspending. The JDWP thread now uses AcquireJdwpTokenForCommand and ReleaseJdwpTokenForCommand, respectively acquiring and releasing the token used for synchronization. On the other hand, the event threads now use AcquireJdwpTokenForEvent and ReleaseJdwpTokenForEvent. During an invoke, the target thread needs to take the JDWP token to execute the method while it's already held by the JDWP handler thread waiting for the invocation to complete. To avoid both threads from waiting for each other (deadlock), the JDWP thread releases the token and acquires it again after the invocation is complete, so the target thread can run safely and prevents other threads from sending events. Bug: 19120467 Change-Id: Ie3208fb940a60573769d494128cf22f0fa30fa61
Diffstat (limited to 'runtime/jdwp/jdwp_main.cc')
-rw-r--r--runtime/jdwp/jdwp_main.cc16
1 files changed, 6 insertions, 10 deletions
diff --git a/runtime/jdwp/jdwp_main.cc b/runtime/jdwp/jdwp_main.cc
index b04aa6e..b6fedd9 100644
--- a/runtime/jdwp/jdwp_main.cc
+++ b/runtime/jdwp/jdwp_main.cc
@@ -220,12 +220,9 @@ JdwpState::JdwpState(const JdwpOptions* options)
event_list_lock_("JDWP event list lock", kJdwpEventListLock),
event_list_(nullptr),
event_list_size_(0),
- event_thread_lock_("JDWP event thread lock"),
- event_thread_cond_("JDWP event thread condition variable", event_thread_lock_),
- event_thread_id_(0),
- process_request_lock_("JDWP process request lock"),
- process_request_cond_("JDWP process request condition variable", process_request_lock_),
- processing_request_(false),
+ jdwp_token_lock_("JDWP token lock"),
+ jdwp_token_cond_("JDWP token condition variable", jdwp_token_lock_),
+ jdwp_token_owner_thread_id_(0),
ddm_is_active_(false),
should_exit_(false),
exit_status_(0) {
@@ -331,7 +328,7 @@ void JdwpState::ResetState() {
* Should not have one of these in progress. If the debugger went away
* mid-request, though, we could see this.
*/
- if (event_thread_id_ != 0) {
+ if (jdwp_token_owner_thread_id_ != 0) {
LOG(WARNING) << "Resetting state while event in progress";
DCHECK(false);
}
@@ -382,10 +379,9 @@ bool JdwpState::HandlePacket() {
ssize_t cc = netStateBase->WritePacket(pReply, replyLength);
/*
- * We processed this request and sent its reply. Notify other threads waiting for us they can now
- * send events.
+ * We processed this request and sent its reply so we can release the JDWP token.
*/
- EndProcessingRequest();
+ ReleaseJdwpTokenForCommand();
if (cc != static_cast<ssize_t>(replyLength)) {
PLOG(ERROR) << "Failed sending reply to debugger";