| // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // Implementation of threading classes using Linux pthreads. |
| // Also works under Native Client. |
| #include "threading.h" |
| |
| #include <pthread.h> |
| #include <sys/time.h> |
| |
| #include "base/basictypes.h" |
| #include "base/compiler_specific.h" |
| |
| #include "log.h" |
| |
| namespace speech_synthesis { |
| |
| namespace { |
| |
| // Implementation of a Mutex using pthreads |
| class PthreadMutex : public Mutex { |
| public: |
| PthreadMutex() { |
| pthread_mutex_init(&mutex_, NULL); |
| } |
| |
| virtual ~PthreadMutex() { |
| pthread_mutex_destroy(&mutex_); |
| } |
| |
| // Mutex overrides: |
| virtual void Lock() OVERRIDE { |
| pthread_mutex_lock(&mutex_); |
| } |
| |
| virtual void Unlock() OVERRIDE { |
| pthread_mutex_unlock(&mutex_); |
| } |
| |
| private: |
| pthread_mutex_t mutex_; |
| friend class PthreadCondVar; |
| |
| DISALLOW_COPY_AND_ASSIGN(PthreadMutex); |
| }; |
| |
| class PthreadCondVar : public CondVar { |
| public: |
| PthreadCondVar() { |
| pthread_cond_init(&cond_var_, NULL); |
| } |
| |
| virtual ~PthreadCondVar() { |
| pthread_cond_destroy(&cond_var_); |
| } |
| |
| // CondVar overrides: |
| virtual void Wait(Mutex* mutex) OVERRIDE { |
| pthread_cond_wait(&cond_var_, &(static_cast<PthreadMutex*>(mutex))->mutex_); |
| } |
| |
| virtual void WaitWithTimeout(Mutex* mutex, int timeout_ms) OVERRIDE { |
| struct timeval now; |
| struct timespec timeout; |
| int future_us; |
| |
| gettimeofday(&now, NULL); |
| future_us = now.tv_usec + timeout_ms * 1000; |
| timeout.tv_nsec = (future_us % 1000000) * 1000; |
| timeout.tv_sec = now.tv_sec + future_us / 1000000; |
| |
| pthread_cond_timedwait(&cond_var_, |
| &(static_cast<PthreadMutex*>(mutex))->mutex_, |
| &timeout); |
| } |
| |
| virtual void Signal() OVERRIDE { |
| pthread_cond_signal(&cond_var_); |
| } |
| |
| private: |
| pthread_cond_t cond_var_; |
| |
| DISALLOW_COPY_AND_ASSIGN(PthreadCondVar); |
| }; |
| |
| // Implementation of a joinable Thread using Pthread's Thread class |
| class PthreadThread : public Thread { |
| public: |
| explicit PthreadThread(pthread_t *thread) |
| : thread_(thread) { } |
| |
| virtual ~PthreadThread() { |
| CHECK(thread_ == NULL); |
| } |
| |
| // Thread override. |
| virtual void Join() OVERRIDE { |
| pthread_join(*thread_, NULL); |
| delete thread_; |
| thread_ = NULL; |
| } |
| |
| private: |
| pthread_t* thread_; |
| |
| DISALLOW_COPY_AND_ASSIGN(PthreadThread); |
| }; |
| |
| void* ThreadStart(void *userdata) { |
| Runnable *action = static_cast<Runnable *>(userdata); |
| action->Run(); |
| |
| return NULL; |
| } |
| |
| } // namespace |
| |
| // static |
| Mutex* Mutex::Create() { |
| return new PthreadMutex(); |
| } |
| |
| // static |
| CondVar* CondVar::Create() { |
| return new PthreadCondVar(); |
| } |
| |
| // static |
| Thread* Thread::StartJoinableThread(Runnable *action) { |
| pthread_t* thread = new pthread_t; |
| pthread_create(thread, NULL, ThreadStart, action); |
| |
| return new PthreadThread(thread); |
| } |
| |
| } // namespace speech_synthesis |