summaryrefslogtreecommitdiff
path: root/openjdkjvmti/events.cc
diff options
context:
space:
mode:
Diffstat (limited to 'openjdkjvmti/events.cc')
-rw-r--r--openjdkjvmti/events.cc88
1 files changed, 49 insertions, 39 deletions
diff --git a/openjdkjvmti/events.cc b/openjdkjvmti/events.cc
index 4f978444f8..beb864be23 100644
--- a/openjdkjvmti/events.cc
+++ b/openjdkjvmti/events.cc
@@ -59,7 +59,6 @@
#include "thread-inl.h"
#include "thread_list.h"
#include "ti_phase.h"
-#include "ti_thread.h"
#include "well_known_classes.h"
namespace openjdkjvmti {
@@ -1275,48 +1274,59 @@ jvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env,
art::Thread* self = art::Thread::Current();
art::Thread* target = nullptr;
- ScopedNoUserCodeSuspension snucs(self);
-
- bool old_state;
- bool new_state;
- {
- // From now on we know we cannot get suspended by user-code.
- // NB This does a SuspendCheck (during thread state change) so we need to
- // make sure we don't have the 'suspend_lock' locked here.
- art::ScopedObjectAccess soa(self);
- art::WriterMutexLock el_mu(self, envs_lock_);
- art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
- jvmtiError err = ERR(INTERNAL);
- if (thread != nullptr) {
- if (!ThreadUtil::GetAliveNativeThread(thread, soa, &target, &err)) {
- return err;
- } else if (target->IsStillStarting() ||
- target->GetState() == art::ThreadState::kStarting) {
- target->Dump(LOG_STREAM(WARNING) << "Is not alive: ");
- return ERR(THREAD_NOT_ALIVE);
- }
+ do {
+ ThreadUtil::SuspendCheck(self);
+ art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_);
+ // Make sure we won't be suspended in the middle of holding the
+ // thread_suspend_count_lock_ by a user-code suspension. We retry and do
+ // another SuspendCheck to clear this.
+ if (ThreadUtil::WouldSuspendForUserCodeLocked(self)) {
+ continue;
}
+ bool old_state;
+ bool new_state;
+ {
+ // From now on we know we cannot get suspended by user-code.
+ // NB This does a SuspendCheck (during thread state change) so we need to
+ // make sure we don't have the 'suspend_lock' locked here.
+ art::ScopedObjectAccess soa(self);
+ art::WriterMutexLock el_mu(self, envs_lock_);
+ art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
+ jvmtiError err = ERR(INTERNAL);
+ if (thread != nullptr) {
+ if (!ThreadUtil::GetAliveNativeThread(thread, soa, &target, &err)) {
+ return err;
+ } else if (target->IsStillStarting() ||
+ target->GetState() == art::ThreadState::kStarting) {
+ target->Dump(LOG_STREAM(WARNING) << "Is not alive: ");
+ return ERR(THREAD_NOT_ALIVE);
+ }
+ }
- art::WriterMutexLock ei_mu(self, env->event_info_mutex_);
- old_state = global_mask.Test(event);
- if (mode == JVMTI_ENABLE) {
- env->event_masks.EnableEvent(env, target, event);
- global_mask.Set(event);
- new_state = true;
- } else {
- DCHECK_EQ(mode, JVMTI_DISABLE);
- env->event_masks.DisableEvent(env, target, event);
- RecalculateGlobalEventMaskLocked(event);
- new_state = global_mask.Test(event);
+ {
+ art::WriterMutexLock ei_mu(self, env->event_info_mutex_);
+ old_state = global_mask.Test(event);
+ if (mode == JVMTI_ENABLE) {
+ env->event_masks.EnableEvent(env, target, event);
+ global_mask.Set(event);
+ new_state = true;
+ } else {
+ DCHECK_EQ(mode, JVMTI_DISABLE);
+
+ env->event_masks.DisableEvent(env, target, event);
+ RecalculateGlobalEventMaskLocked(event);
+ new_state = global_mask.Test(event);
+ }
+ }
}
- }
- // Handle any special work required for the event type. We still have the
- // user_code_suspend_count_lock_ so there won't be any interleaving here.
- if (new_state != old_state) {
- return HandleEventType(event, thread, mode == JVMTI_ENABLE);
- }
- return OK;
+ // Handle any special work required for the event type. We still have the
+ // user_code_suspend_count_lock_ so there won't be any interleaving here.
+ if (new_state != old_state) {
+ return HandleEventType(event, thread, mode == JVMTI_ENABLE);
+ }
+ return OK;
+ } while (true);
}
void EventHandler::HandleBreakpointEventsChanged(bool added) {