remove WebPWorkerImpl declaration from the header

BUG=webp:355

Change-Id: Ia4efce4e8f3745e5cdcac495f4a79a8c03062d88
This commit is contained in:
Pascal Massimino 2017-11-05 12:31:48 -08:00
parent f1f437cc89
commit 2a270c1df5
2 changed files with 31 additions and 29 deletions

View File

@ -50,11 +50,11 @@ typedef struct {
#endif // _WIN32 #endif // _WIN32
struct WebPWorkerImpl { typedef struct {
pthread_mutex_t mutex_; pthread_mutex_t mutex_;
pthread_cond_t condition_; pthread_cond_t condition_;
pthread_t thread_; pthread_t thread_;
}; } WebPWorkerImpl;
#if defined(_WIN32) #if defined(_WIN32)
@ -205,11 +205,12 @@ static void Execute(WebPWorker* const worker); // Forward declaration.
static THREADFN ThreadLoop(void* ptr) { static THREADFN ThreadLoop(void* ptr) {
WebPWorker* const worker = (WebPWorker*)ptr; WebPWorker* const worker = (WebPWorker*)ptr;
WebPWorkerImpl* const impl = (WebPWorkerImpl*)worker->impl_;
int done = 0; int done = 0;
while (!done) { while (!done) {
pthread_mutex_lock(&worker->impl_->mutex_); pthread_mutex_lock(&impl->mutex_);
while (worker->status_ == OK) { // wait in idling mode while (worker->status_ == OK) { // wait in idling mode
pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_); pthread_cond_wait(&impl->condition_, &impl->mutex_);
} }
if (worker->status_ == WORK) { if (worker->status_ == WORK) {
Execute(worker); Execute(worker);
@ -218,8 +219,8 @@ static THREADFN ThreadLoop(void* ptr) {
done = 1; done = 1;
} }
// signal to the main thread that we're done (for Sync()) // signal to the main thread that we're done (for Sync())
pthread_cond_signal(&worker->impl_->condition_); pthread_cond_signal(&impl->condition_);
pthread_mutex_unlock(&worker->impl_->mutex_); pthread_mutex_unlock(&impl->mutex_);
} }
return THREAD_RETURN(NULL); // Thread is finished return THREAD_RETURN(NULL); // Thread is finished
} }
@ -229,21 +230,22 @@ static void ChangeState(WebPWorker* const worker, WebPWorkerStatus new_status) {
// No-op when attempting to change state on a thread that didn't come up. // No-op when attempting to change state on a thread that didn't come up.
// Checking status_ without acquiring the lock first would result in a data // Checking status_ without acquiring the lock first would result in a data
// race. // race.
if (worker->impl_ == NULL) return; WebPWorkerImpl* const impl = (WebPWorkerImpl*)worker->impl_;
if (impl == NULL) return;
pthread_mutex_lock(&worker->impl_->mutex_); pthread_mutex_lock(&impl->mutex_);
if (worker->status_ >= OK) { if (worker->status_ >= OK) {
// wait for the worker to finish // wait for the worker to finish
while (worker->status_ != OK) { while (worker->status_ != OK) {
pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_); pthread_cond_wait(&impl->condition_, &impl->mutex_);
} }
// assign new status and release the working thread if needed // assign new status and release the working thread if needed
if (new_status != OK) { if (new_status != OK) {
worker->status_ = new_status; worker->status_ = new_status;
pthread_cond_signal(&worker->impl_->condition_); pthread_cond_signal(&impl->condition_);
} }
} }
pthread_mutex_unlock(&worker->impl_->mutex_); pthread_mutex_unlock(&impl->mutex_);
} }
#endif // WEBP_USE_THREAD #endif // WEBP_USE_THREAD
@ -268,26 +270,28 @@ static int Reset(WebPWorker* const worker) {
worker->had_error = 0; worker->had_error = 0;
if (worker->status_ < OK) { if (worker->status_ < OK) {
#ifdef WEBP_USE_THREAD #ifdef WEBP_USE_THREAD
worker->impl_ = (WebPWorkerImpl*)WebPSafeCalloc(1, sizeof(*worker->impl_)); WebPWorkerImpl* const impl =
(WebPWorkerImpl*)WebPSafeCalloc(1, sizeof(WebPWorkerImpl));
worker->impl_ = (void*)impl;
if (worker->impl_ == NULL) { if (worker->impl_ == NULL) {
return 0; return 0;
} }
if (pthread_mutex_init(&worker->impl_->mutex_, NULL)) { if (pthread_mutex_init(&impl->mutex_, NULL)) {
goto Error; goto Error;
} }
if (pthread_cond_init(&worker->impl_->condition_, NULL)) { if (pthread_cond_init(&impl->condition_, NULL)) {
pthread_mutex_destroy(&worker->impl_->mutex_); pthread_mutex_destroy(&impl->mutex_);
goto Error; goto Error;
} }
pthread_mutex_lock(&worker->impl_->mutex_); pthread_mutex_lock(&impl->mutex_);
ok = !pthread_create(&worker->impl_->thread_, NULL, ThreadLoop, worker); ok = !pthread_create(&impl->thread_, NULL, ThreadLoop, worker);
if (ok) worker->status_ = OK; if (ok) worker->status_ = OK;
pthread_mutex_unlock(&worker->impl_->mutex_); pthread_mutex_unlock(&impl->mutex_);
if (!ok) { if (!ok) {
pthread_mutex_destroy(&worker->impl_->mutex_); pthread_mutex_destroy(&impl->mutex_);
pthread_cond_destroy(&worker->impl_->condition_); pthread_cond_destroy(&impl->condition_);
Error: Error:
WebPSafeFree(worker->impl_); WebPSafeFree(impl);
worker->impl_ = NULL; worker->impl_ = NULL;
return 0; return 0;
} }
@ -318,11 +322,12 @@ static void Launch(WebPWorker* const worker) {
static void End(WebPWorker* const worker) { static void End(WebPWorker* const worker) {
#ifdef WEBP_USE_THREAD #ifdef WEBP_USE_THREAD
if (worker->impl_ != NULL) { if (worker->impl_ != NULL) {
WebPWorkerImpl* const impl = (WebPWorkerImpl*)worker->impl_;
ChangeState(worker, NOT_OK); ChangeState(worker, NOT_OK);
pthread_join(worker->impl_->thread_, NULL); pthread_join(impl->thread_, NULL);
pthread_mutex_destroy(&worker->impl_->mutex_); pthread_mutex_destroy(&impl->mutex_);
pthread_cond_destroy(&worker->impl_->condition_); pthread_cond_destroy(&impl->condition_);
WebPSafeFree(worker->impl_); WebPSafeFree(impl);
worker->impl_ = NULL; worker->impl_ = NULL;
} }
#else #else

View File

@ -35,12 +35,9 @@ typedef enum {
// arguments (data1 and data2), and should return false in case of error. // arguments (data1 and data2), and should return false in case of error.
typedef int (*WebPWorkerHook)(void*, void*); typedef int (*WebPWorkerHook)(void*, void*);
// Platform-dependent implementation details for the worker.
typedef struct WebPWorkerImpl WebPWorkerImpl;
// Synchronization object used to launch job in the worker thread // Synchronization object used to launch job in the worker thread
typedef struct { typedef struct {
WebPWorkerImpl* impl_; void* impl_; // platform-dependent implementation worker details
WebPWorkerStatus status_; WebPWorkerStatus status_;
WebPWorkerHook hook; // hook to call WebPWorkerHook hook; // hook to call
void* data1; // first argument passed to 'hook' void* data1; // first argument passed to 'hook'