diff options
author | zork@google.com <zork@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-16 23:43:58 +0000 |
---|---|---|
committer | zork@google.com <zork@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-16 23:43:58 +0000 |
commit | edf4898029126a651010d85c55c9bc0f54f23436 (patch) | |
tree | 156ba1730ee1b9db40fb2411ee89b883bc7b6616 /third_party/libjingle | |
parent | e19d7133ce2bcb816fbd6e707622cc43a5735c1d (diff) | |
download | chromium_src-edf4898029126a651010d85c55c9bc0f54f23436.zip chromium_src-edf4898029126a651010d85c55c9bc0f54f23436.tar.gz chromium_src-edf4898029126a651010d85c55c9bc0f54f23436.tar.bz2 |
Prevent thread creation if Join has already been called.
Tracking the thread id in the constructor, destructor and Start()
shows that the thread object can be started and stopped on
different threads. This means that there is a race condition
if Stop() or Join() gets called during Start(), which could cause
the thread to start with a pointer to a deleted object.
BUG=23251
TEST=none
Review URL: http://codereview.chromium.org/274079
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29356 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/libjingle')
-rw-r--r-- | third_party/libjingle/files/talk/base/thread.cc | 9 | ||||
-rw-r--r-- | third_party/libjingle/files/talk/base/thread.h | 1 |
2 files changed, 10 insertions, 0 deletions
diff --git a/third_party/libjingle/files/talk/base/thread.cc b/third_party/libjingle/files/talk/base/thread.cc index 760ddc1..99fa701 100644 --- a/third_party/libjingle/files/talk/base/thread.cc +++ b/third_party/libjingle/files/talk/base/thread.cc @@ -106,6 +106,7 @@ bool ThreadManager::ThreadActive(Thread *thread) { Thread::Thread(SocketServer* ss) : MessageQueue(ss), priority_(PRIORITY_NORMAL) { g_thmgr.Add(this); started_ = false; + stopped_ = false; has_sends_ = false; } @@ -127,12 +128,16 @@ void Thread::Start() { pthread_attr_setschedparam(&attr, ¶m); } CritScope cs(&started_crit_); + // Make sure Join() hasn't been called yet. + if (stopped_) + return; pthread_create(&thread_, &attr, PreRun, this); started_ = true; } void Thread::Join() { CritScope cs(&started_crit_); + stopped_ = true; if (started_) { void *pv; pthread_join(thread_, &pv); @@ -174,6 +179,9 @@ void Thread::Start() { flags = CREATE_SUSPENDED; } CritScope cs(&started_crit_); + // Make sure Join() hasn't been called yet. + if (stopped_) + return; thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PreRun, this, flags, NULL); if (thread_) { if (priority_ != PRIORITY_NORMAL) { @@ -188,6 +196,7 @@ void Thread::Start() { void Thread::Join() { CritScope cs(&started_crit_); + stopped_ = true; if (started_) { WaitForSingleObject(thread_, INFINITE); CloseHandle(thread_); diff --git a/third_party/libjingle/files/talk/base/thread.h b/third_party/libjingle/files/talk/base/thread.h index 0f305f0..a2642f0 100644 --- a/third_party/libjingle/files/talk/base/thread.h +++ b/third_party/libjingle/files/talk/base/thread.h @@ -135,6 +135,7 @@ private: ThreadPriority priority_; CriticalSection started_crit_; bool started_; + bool stopped_; bool has_sends_; #ifdef POSIX |