summaryrefslogtreecommitdiffstats
path: root/third_party/libjingle
diff options
context:
space:
mode:
authorzork@google.com <zork@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-16 23:43:58 +0000
committerzork@google.com <zork@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-16 23:43:58 +0000
commitedf4898029126a651010d85c55c9bc0f54f23436 (patch)
tree156ba1730ee1b9db40fb2411ee89b883bc7b6616 /third_party/libjingle
parente19d7133ce2bcb816fbd6e707622cc43a5735c1d (diff)
downloadchromium_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.cc9
-rw-r--r--third_party/libjingle/files/talk/base/thread.h1
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, &param);
}
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