aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils
diff options
context:
space:
mode:
authorGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-14 15:40:05 +0000
committerGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-14 15:40:05 +0000
commit59bc8d4fa725da2a6cec3526859c488b577d5cce (patch)
tree2b9847b4fb5f20d7c0b5761bbf0cbbb885511ad8 /src/utils
parent620c3b4a9fdd0f0a77a8d3519a51542a01d0ae53 (diff)
Android does not support pthread_cancel / pthread_testcancel.
git-svn-id: http://skia.googlecode.com/svn/trunk@3923 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/SkThreadUtils_pthread.cpp74
-rw-r--r--src/utils/SkThreadUtils_pthread.h22
-rw-r--r--src/utils/SkThreadUtils_win.h2
3 files changed, 62 insertions, 36 deletions
diff --git a/src/utils/SkThreadUtils_pthread.cpp b/src/utils/SkThreadUtils_pthread.cpp
index 17a2075ab0..7dec907df1 100644
--- a/src/utils/SkThreadUtils_pthread.cpp
+++ b/src/utils/SkThreadUtils_pthread.cpp
@@ -13,39 +13,58 @@
#include <pthread.h>
#include <signal.h>
+PThreadEvent::PThreadEvent() : fConditionFlag(false) {
+ pthread_cond_init(&fCondition, NULL);
+ pthread_mutex_init(&fConditionMutex, NULL);
+}
+PThreadEvent::~PThreadEvent() {
+ pthread_mutex_destroy(&fConditionMutex);
+ pthread_cond_destroy(&fCondition);
+}
+void PThreadEvent::trigger() {
+ pthread_mutex_lock(&fConditionMutex);
+ fConditionFlag = true;
+ pthread_cond_signal(&fCondition);
+ pthread_mutex_unlock(&fConditionMutex);
+}
+void PThreadEvent::wait() {
+ pthread_mutex_lock(&fConditionMutex);
+ while (!fConditionFlag) {
+ pthread_cond_wait(&fCondition, &fConditionMutex);
+ }
+ pthread_mutex_unlock(&fConditionMutex);
+}
+bool PThreadEvent::isTriggered() {
+ bool currentFlag;
+ pthread_mutex_lock(&fConditionMutex);
+ currentFlag = fConditionFlag;
+ pthread_mutex_unlock(&fConditionMutex);
+ return currentFlag;
+}
+
SkThread_PThreadData::SkThread_PThreadData(SkThread::entryPointProc entryPoint, void* data)
: fPThread()
, fValidPThread(false)
, fParam(data)
, fEntryPoint(entryPoint)
- , fStarted(false)
{
- pthread_mutex_init(&fStartMutex, NULL);
-
- pthread_cond_init(&fStartCondition, NULL);
-
pthread_attr_init(&fAttr);
pthread_attr_setdetachstate(&fAttr, PTHREAD_CREATE_JOINABLE);
}
+
SkThread_PThreadData::~SkThread_PThreadData() {
pthread_attr_destroy(&fAttr);
- pthread_cond_destroy(&fStartCondition);
- pthread_mutex_destroy(&fStartMutex);
}
static void* thread_start(void* arg) {
SkThread_PThreadData* pthreadData = static_cast<SkThread_PThreadData*>(arg);
- //Wait for start signal
- pthread_mutex_lock(&(pthreadData->fStartMutex));
- while (!pthreadData->fStarted) {
- pthread_cond_wait(&(pthreadData->fStartCondition), &(pthreadData->fStartMutex));
- }
- pthread_mutex_unlock(&(pthreadData->fStartMutex));
-
- //See if this thread was canceled before starting.
- pthread_testcancel();
+ // Wait for start signal
+ pthreadData->fStarted.wait();
- pthreadData->fEntryPoint(pthreadData->fParam);
+ // Call entry point only if thread was not canceled before starting.
+ if (!pthreadData->fCanceled.isTriggered()) {
+ pthreadData->fEntryPoint(pthreadData->fParam);
+ }
return NULL;
}
@@ -65,14 +84,10 @@ SkThread::~SkThread() {
if (fData != NULL) {
SkThread_PThreadData* pthreadData = static_cast<SkThread_PThreadData*>(fData);
// If created thread but start was never called, kill the thread.
- if (pthreadData->fValidPThread && !pthreadData->fStarted) {
- if (pthread_cancel(pthreadData->fPThread) == 0) {
- if (this->start()) {
- this->join();
- }
- } else {
- //kill with prejudice
- pthread_kill(pthreadData->fPThread, SIGKILL);
+ if (pthreadData->fValidPThread && !pthreadData->fStarted.isTriggered()) {
+ pthreadData->fCanceled.trigger();
+ if (this->start()) {
+ this->join();
}
}
delete pthreadData;
@@ -85,19 +100,16 @@ bool SkThread::start() {
return false;
}
- if (pthreadData->fStarted) {
+ if (pthreadData->fStarted.isTriggered()) {
return false;
}
- pthreadData->fStarted = true;
- pthread_mutex_lock(&(pthreadData->fStartMutex));
- pthread_cond_signal(&(pthreadData->fStartCondition));
- pthread_mutex_unlock(&(pthreadData->fStartMutex));
+ pthreadData->fStarted.trigger();
return true;
}
void SkThread::join() {
SkThread_PThreadData* pthreadData = static_cast<SkThread_PThreadData*>(fData);
- if (!pthreadData->fValidPThread || !pthreadData->fStarted) {
+ if (!pthreadData->fValidPThread || !pthreadData->fStarted.isTriggered()) {
return;
}
diff --git a/src/utils/SkThreadUtils_pthread.h b/src/utils/SkThreadUtils_pthread.h
index 52b398c2e2..3e1020275c 100644
--- a/src/utils/SkThreadUtils_pthread.h
+++ b/src/utils/SkThreadUtils_pthread.h
@@ -11,19 +11,33 @@
#include "SkThreadUtils.h"
#include <pthread.h>
-class SkThread_PThreadData {
+class PThreadEvent : SkNoncopyable {
+public:
+ PThreadEvent();
+ ~PThreadEvent();
+ void trigger();
+ void wait();
+ bool isTriggered();
+
+private:
+ pthread_cond_t fCondition;
+ pthread_mutex_t fConditionMutex;
+ bool fConditionFlag;
+};
+
+class SkThread_PThreadData : SkNoncopyable {
public:
SkThread_PThreadData(SkThread::entryPointProc entryPoint, void* data);
~SkThread_PThreadData();
pthread_t fPThread;
bool fValidPThread;
- pthread_mutex_t fStartMutex;
- pthread_cond_t fStartCondition;
+ PThreadEvent fStarted;
+ PThreadEvent fCanceled;
+
pthread_attr_t fAttr;
void* fParam;
SkThread::entryPointProc fEntryPoint;
- bool fStarted;
};
#endif
diff --git a/src/utils/SkThreadUtils_win.h b/src/utils/SkThreadUtils_win.h
index 5861e5d0db..51b32fad6f 100644
--- a/src/utils/SkThreadUtils_win.h
+++ b/src/utils/SkThreadUtils_win.h
@@ -12,7 +12,7 @@
#include "SkThreadUtils.h"
-class SkThread_WinData {
+class SkThread_WinData : SkNoncopyable {
public:
SkThread_WinData(SkThread::entryPointProc entryPoint, void* data);
~SkThread_WinData();