| OLD | NEW |
| 1 // Copyright 2011 Google Inc. All Rights Reserved. | 1 // Copyright 2011 Google Inc. All Rights Reserved. |
| 2 // | 2 // |
| 3 // Use of this source code is governed by a BSD-style license | 3 // Use of this source code is governed by a BSD-style license |
| 4 // that can be found in the COPYING file in the root of the source | 4 // that can be found in the COPYING file in the root of the source |
| 5 // tree. An additional intellectual property rights grant can be found | 5 // tree. An additional intellectual property rights grant can be found |
| 6 // in the file PATENTS. All contributing project authors may | 6 // in the file PATENTS. All contributing project authors may |
| 7 // be found in the AUTHORS file in the root of the source tree. | 7 // be found in the AUTHORS file in the root of the source tree. |
| 8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
| 9 // | 9 // |
| 10 // Multi-threaded worker | 10 // Multi-threaded worker |
| 11 // | 11 // |
| 12 // Author: Skal (pascal.massimino@gmail.com) | 12 // Author: Skal (pascal.massimino@gmail.com) |
| 13 | 13 |
| 14 #include <assert.h> | 14 #include <assert.h> |
| 15 #include <string.h> // for memset() | 15 #include <string.h> // for memset() |
| 16 #include "./thread.h" | 16 #include "./thread_utils.h" |
| 17 #include "./utils.h" | 17 #include "./utils.h" |
| 18 | 18 |
| 19 #ifdef WEBP_USE_THREAD | 19 #ifdef WEBP_USE_THREAD |
| 20 | 20 |
| 21 #if defined(_WIN32) | 21 #if defined(_WIN32) |
| 22 | 22 |
| 23 #include <windows.h> | 23 #include <windows.h> |
| 24 typedef HANDLE pthread_t; | 24 typedef HANDLE pthread_t; |
| 25 typedef CRITICAL_SECTION pthread_mutex_t; | 25 typedef CRITICAL_SECTION pthread_mutex_t; |
| 26 | 26 |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 } | 176 } |
| 177 | 177 |
| 178 static int pthread_cond_wait(pthread_cond_t* const condition, | 178 static int pthread_cond_wait(pthread_cond_t* const condition, |
| 179 pthread_mutex_t* const mutex) { | 179 pthread_mutex_t* const mutex) { |
| 180 int ok; | 180 int ok; |
| 181 #ifdef USE_WINDOWS_CONDITION_VARIABLE | 181 #ifdef USE_WINDOWS_CONDITION_VARIABLE |
| 182 ok = SleepConditionVariableCS(condition, mutex, INFINITE); | 182 ok = SleepConditionVariableCS(condition, mutex, INFINITE); |
| 183 #else | 183 #else |
| 184 // note that there is a consumer available so the signal isn't dropped in | 184 // note that there is a consumer available so the signal isn't dropped in |
| 185 // pthread_cond_signal | 185 // pthread_cond_signal |
| 186 if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL)) | 186 if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL)) return 1; |
| 187 return 1; | |
| 188 // now unlock the mutex so pthread_cond_signal may be issued | 187 // now unlock the mutex so pthread_cond_signal may be issued |
| 189 pthread_mutex_unlock(mutex); | 188 pthread_mutex_unlock(mutex); |
| 190 ok = (WaitForSingleObject(condition->signal_event_, INFINITE) == | 189 ok = (WaitForSingleObject(condition->signal_event_, INFINITE) == |
| 191 WAIT_OBJECT_0); | 190 WAIT_OBJECT_0); |
| 192 ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL); | 191 ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL); |
| 193 pthread_mutex_lock(mutex); | 192 pthread_mutex_lock(mutex); |
| 194 #endif | 193 #endif |
| 195 return !ok; | 194 return !ok; |
| 196 } | 195 } |
| 197 | 196 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 219 done = 1; | 218 done = 1; |
| 220 } | 219 } |
| 221 // signal to the main thread that we're done (for Sync()) | 220 // signal to the main thread that we're done (for Sync()) |
| 222 pthread_cond_signal(&worker->impl_->condition_); | 221 pthread_cond_signal(&worker->impl_->condition_); |
| 223 pthread_mutex_unlock(&worker->impl_->mutex_); | 222 pthread_mutex_unlock(&worker->impl_->mutex_); |
| 224 } | 223 } |
| 225 return THREAD_RETURN(NULL); // Thread is finished | 224 return THREAD_RETURN(NULL); // Thread is finished |
| 226 } | 225 } |
| 227 | 226 |
| 228 // main thread state control | 227 // main thread state control |
| 229 static void ChangeState(WebPWorker* const worker, | 228 static void ChangeState(WebPWorker* const worker, WebPWorkerStatus new_status) { |
| 230 WebPWorkerStatus new_status) { | |
| 231 // No-op when attempting to change state on a thread that didn't come up. | 229 // No-op when attempting to change state on a thread that didn't come up. |
| 232 // Checking status_ without acquiring the lock first would result in a data | 230 // Checking status_ without acquiring the lock first would result in a data |
| 233 // race. | 231 // race. |
| 234 if (worker->impl_ == NULL) return; | 232 if (worker->impl_ == NULL) return; |
| 235 | 233 |
| 236 pthread_mutex_lock(&worker->impl_->mutex_); | 234 pthread_mutex_lock(&worker->impl_->mutex_); |
| 237 if (worker->status_ >= OK) { | 235 if (worker->status_ >= OK) { |
| 238 // wait for the worker to finish | 236 // wait for the worker to finish |
| 239 while (worker->status_ != OK) { | 237 while (worker->status_ != OK) { |
| 240 pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_); | 238 pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 } | 347 } |
| 350 g_worker_interface = *winterface; | 348 g_worker_interface = *winterface; |
| 351 return 1; | 349 return 1; |
| 352 } | 350 } |
| 353 | 351 |
| 354 const WebPWorkerInterface* WebPGetWorkerInterface(void) { | 352 const WebPWorkerInterface* WebPGetWorkerInterface(void) { |
| 355 return &g_worker_interface; | 353 return &g_worker_interface; |
| 356 } | 354 } |
| 357 | 355 |
| 358 //------------------------------------------------------------------------------ | 356 //------------------------------------------------------------------------------ |
| OLD | NEW |