Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Unified Diff: src/v8threads.cc

Issue 503022: Add locker support to DebugMessageDispatchHandler (Closed)
Patch Set: make compilable with debugger support off Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/v8threads.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/v8threads.cc
diff --git a/src/v8threads.cc b/src/v8threads.cc
index 80a7cd94fb8ce3b3e6e004b12c9f49e5bd001fcc..15512c06fa55ddd3e84d2656d4f5dea268f3d51e 100644
--- a/src/v8threads.cc
+++ b/src/v8threads.cc
@@ -46,15 +46,28 @@ static internal::Thread::LocalStorageKey thread_id_key =
// API code to verify that the lock is always held when V8 is being entered.
bool Locker::active_ = false;
-
// Constructor for the Locker object. Once the Locker is constructed the
// current thread will be guaranteed to have the big V8 lock.
-Locker::Locker() : has_lock_(false), top_level_(true) {
+Locker::Locker(LockParameters* lock_parameters) : has_lock_(false), top_level_(true) {
// Record that the Locker has been used at least once.
active_ = true;
+ effective_ = false;
// Get the big lock if necessary.
if (!internal::ThreadManager::IsLockedByCurrentThread()) {
+
+#ifdef ENABLE_DEBUGGER_SUPPORT
+ if (lock_parameters == NULL) {
+ internal::ThreadManager::Lock();
+ } else {
+ bool res = internal::ThreadManager::LockOrAsk(&internal::Promises::promise_to_process_debug_commands);
+ if (!res) {
+ lock_parameters->successfully_relaied = true;
+ return;
+ }
+ }
+#else
internal::ThreadManager::Lock();
+#endif
has_lock_ = true;
// Make sure that V8 is initialized. Archiving of threads interferes
// with deserialization by adding additional root pointers, so we must
@@ -76,6 +89,7 @@ Locker::Locker() : has_lock_(false), top_level_(true) {
// Make sure this thread is assigned a thread id.
internal::ThreadManager::AssignId();
+ effective_ = true;
}
@@ -85,6 +99,9 @@ bool Locker::IsLocked() {
Locker::~Locker() {
+ if (!effective_) {
+ return;
+ }
ASSERT(internal::ThreadManager::IsLockedByCurrentThread());
if (has_lock_) {
if (top_level_) {
@@ -176,6 +193,81 @@ bool ThreadManager::RestoreThread() {
return true;
}
+#ifdef ENABLE_DEBUGGER_SUPPORT
+
+class PromisesHandler {
+ public:
+ static bool CanUnlock(Promises* promises) {
+ return !promises->promise_to_process_debug_commands;
+ }
+ static void KeepPromises(const Promises* promises) {
+ v8::Debug::ProcessDebuggerCommands();
+ }
+};
+
+
+MutexWithResponsibilities::MutexWithResponsibilities()
+: flag_mutex_(OS::CreateMutex()),
+ sem_(OS::CreateSemaphore(1)), // Am I accurate with semaphore?
+ locked_(false)
+{
+}
+
+MutexWithResponsibilities::~MutexWithResponsibilities() {
+ delete sem_;
+ delete flag_mutex_;
+}
+
+
+void MutexWithResponsibilities::Lock() {
+ while (true) {
+ {
+ ScopedLock lock(flag_mutex_);
+ if (!locked_) {
+ locked_ = true;
+ has_promises_ = true;
+ return;
+ }
+ }
+ sem_->Wait();
+ }
+}
+
+bool MutexWithResponsibilities::LockOrAsk(bool Promises::* promise) {
+ ScopedLock lock(flag_mutex_);
+ if (locked_) {
+ ASSERT(has_promises_);
+ promises_.*promise = true;
+ return false;
+ } else {
+ locked_ = true;
+ has_promises_ = false;
+ return true;
+ }
+}
+
+void MutexWithResponsibilities::Unlock() {
+ while (true) {
+ Promises promises_copy;
+ {
+ ScopedLock lock(flag_mutex_);
+ ASSERT(locked_);
+ bool has_to_do = has_promises_ && PromisesHandler::CanUnlock(&promises_);
+ if (!has_to_do) {
+ locked_ = false;
+ break;
+ }
+ promises_copy = promises_;
+ promises_.Reset();
+ }
+ PromisesHandler::KeepPromises(&promises_copy);
+ }
+ sem_->Signal();
+}
+
+#endif
+
+
void ThreadManager::Lock() {
mutex_->Lock();
@@ -189,6 +281,17 @@ void ThreadManager::Unlock() {
mutex_->Unlock();
}
+#ifdef ENABLE_DEBUGGER_SUPPORT
+bool ThreadManager::LockOrAsk(bool Promises::* promise) {
+ bool res = mutex_->LockOrAsk(promise);
+ if (res) {
+ mutex_owner_.Initialize(ThreadHandle::SELF);
+ ASSERT(IsLockedByCurrentThread());
+ }
+ return res;
+}
+#endif
+
static int ArchiveSpacePerThread() {
return HandleScopeImplementer::ArchiveSpacePerThread() +
@@ -261,7 +364,11 @@ ThreadState* ThreadState::Next() {
// be distinguished from not having a thread id at all (since NULL is
// defined as 0.)
int ThreadManager::last_id_ = 0;
+#ifdef ENABLE_DEBUGGER_SUPPORT
+MutexWithResponsibilities* ThreadManager::mutex_ = new MutexWithResponsibilities;
+#else
Mutex* ThreadManager::mutex_ = OS::CreateMutex();
+#endif
ThreadHandle ThreadManager::mutex_owner_(ThreadHandle::INVALID);
ThreadHandle ThreadManager::lazily_archived_thread_(ThreadHandle::INVALID);
ThreadState* ThreadManager::lazily_archived_thread_state_ = NULL;
« no previous file with comments | « src/v8threads.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698