Android does not support pthread_cancel / pthread_testcancel.
authorbungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 14 May 2012 15:40:05 +0000 (15:40 +0000)
committerbungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 14 May 2012 15:40:05 +0000 (15:40 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@3923 2bbb7eff-a529-9590-31e7-b0007b416f81

src/utils/SkThreadUtils_pthread.cpp
src/utils/SkThreadUtils_pthread.h
src/utils/SkThreadUtils_win.h

index 17a2075..7dec907 100644 (file)
 #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;
     }
 
index 52b398c..3e10202 100644 (file)
 #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
index 5861e5d..51b32fa 100644 (file)
@@ -12,7 +12,7 @@
 
 #include "SkThreadUtils.h"
 
-class SkThread_WinData {
+class SkThread_WinData : SkNoncopyable {
 public:
     SkThread_WinData(SkThread::entryPointProc entryPoint, void* data);
     ~SkThread_WinData();