Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(281)

Side by Side Diff: third_party/libwebp/utils/thread.c

Issue 116213006: Update libwebp to 0.4.0 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: After Blink Roll Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/libwebp/utils/thread.h ('k') | third_party/libwebp/utils/utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.h"
17 17
18 #if defined(__cplusplus) || defined(c_plusplus)
19 extern "C" {
20 #endif
21
22 #ifdef WEBP_USE_THREAD 18 #ifdef WEBP_USE_THREAD
23 19
24 #if defined(_WIN32) 20 #if defined(_WIN32)
25 21
26 //------------------------------------------------------------------------------ 22 //------------------------------------------------------------------------------
27 // simplistic pthread emulation layer 23 // simplistic pthread emulation layer
28 24
29 #include <process.h> 25 #include <process.h>
30 26
31 // _beginthreadex requires __stdcall 27 // _beginthreadex requires __stdcall
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 return 1; 115 return 1;
120 // now unlock the mutex so pthread_cond_signal may be issued 116 // now unlock the mutex so pthread_cond_signal may be issued
121 pthread_mutex_unlock(mutex); 117 pthread_mutex_unlock(mutex);
122 ok = (WaitForSingleObject(condition->signal_event_, INFINITE) == 118 ok = (WaitForSingleObject(condition->signal_event_, INFINITE) ==
123 WAIT_OBJECT_0); 119 WAIT_OBJECT_0);
124 ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL); 120 ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL);
125 pthread_mutex_lock(mutex); 121 pthread_mutex_lock(mutex);
126 return !ok; 122 return !ok;
127 } 123 }
128 124
129 #else // _WIN32 125 #else // !_WIN32
130 # define THREADFN void* 126 # define THREADFN void*
131 # define THREAD_RETURN(val) val 127 # define THREAD_RETURN(val) val
132 #endif 128 #endif // _WIN32
133 129
134 //------------------------------------------------------------------------------ 130 //------------------------------------------------------------------------------
135 131
136 static THREADFN WebPWorkerThreadLoop(void *ptr) { // thread loop 132 static THREADFN ThreadLoop(void* ptr) {
137 WebPWorker* const worker = (WebPWorker*)ptr; 133 WebPWorker* const worker = (WebPWorker*)ptr;
138 int done = 0; 134 int done = 0;
139 while (!done) { 135 while (!done) {
140 pthread_mutex_lock(&worker->mutex_); 136 pthread_mutex_lock(&worker->mutex_);
141 while (worker->status_ == OK) { // wait in idling mode 137 while (worker->status_ == OK) { // wait in idling mode
142 pthread_cond_wait(&worker->condition_, &worker->mutex_); 138 pthread_cond_wait(&worker->condition_, &worker->mutex_);
143 } 139 }
144 if (worker->status_ == WORK) { 140 if (worker->status_ == WORK) {
145 if (worker->hook) { 141 WebPWorkerExecute(worker);
146 worker->had_error |= !worker->hook(worker->data1, worker->data2);
147 }
148 worker->status_ = OK; 142 worker->status_ = OK;
149 } else if (worker->status_ == NOT_OK) { // finish the worker 143 } else if (worker->status_ == NOT_OK) { // finish the worker
150 done = 1; 144 done = 1;
151 } 145 }
152 // signal to the main thread that we're done (for Sync()) 146 // signal to the main thread that we're done (for Sync())
153 pthread_cond_signal(&worker->condition_); 147 pthread_cond_signal(&worker->condition_);
154 pthread_mutex_unlock(&worker->mutex_); 148 pthread_mutex_unlock(&worker->mutex_);
155 } 149 }
156 return THREAD_RETURN(NULL); // Thread is finished 150 return THREAD_RETURN(NULL); // Thread is finished
157 } 151 }
158 152
159 // main thread state control 153 // main thread state control
160 static void WebPWorkerChangeState(WebPWorker* const worker, 154 static void ChangeState(WebPWorker* const worker,
161 WebPWorkerStatus new_status) { 155 WebPWorkerStatus new_status) {
162 // no-op when attempting to change state on a thread that didn't come up 156 // no-op when attempting to change state on a thread that didn't come up
163 if (worker->status_ < OK) return; 157 if (worker->status_ < OK) return;
164 158
165 pthread_mutex_lock(&worker->mutex_); 159 pthread_mutex_lock(&worker->mutex_);
166 // wait for the worker to finish 160 // wait for the worker to finish
167 while (worker->status_ != OK) { 161 while (worker->status_ != OK) {
168 pthread_cond_wait(&worker->condition_, &worker->mutex_); 162 pthread_cond_wait(&worker->condition_, &worker->mutex_);
169 } 163 }
170 // assign new status and release the working thread if needed 164 // assign new status and release the working thread if needed
171 if (new_status != OK) { 165 if (new_status != OK) {
172 worker->status_ = new_status; 166 worker->status_ = new_status;
173 pthread_cond_signal(&worker->condition_); 167 pthread_cond_signal(&worker->condition_);
174 } 168 }
175 pthread_mutex_unlock(&worker->mutex_); 169 pthread_mutex_unlock(&worker->mutex_);
176 } 170 }
177 171
178 #endif 172 #endif // WEBP_USE_THREAD
179 173
180 //------------------------------------------------------------------------------ 174 //------------------------------------------------------------------------------
181 175
182 void WebPWorkerInit(WebPWorker* const worker) { 176 void WebPWorkerInit(WebPWorker* const worker) {
183 memset(worker, 0, sizeof(*worker)); 177 memset(worker, 0, sizeof(*worker));
184 worker->status_ = NOT_OK; 178 worker->status_ = NOT_OK;
185 } 179 }
186 180
187 int WebPWorkerSync(WebPWorker* const worker) { 181 int WebPWorkerSync(WebPWorker* const worker) {
188 #ifdef WEBP_USE_THREAD 182 #ifdef WEBP_USE_THREAD
189 WebPWorkerChangeState(worker, OK); 183 ChangeState(worker, OK);
190 #endif 184 #endif
191 assert(worker->status_ <= OK); 185 assert(worker->status_ <= OK);
192 return !worker->had_error; 186 return !worker->had_error;
193 } 187 }
194 188
195 int WebPWorkerReset(WebPWorker* const worker) { 189 int WebPWorkerReset(WebPWorker* const worker) {
196 int ok = 1; 190 int ok = 1;
197 worker->had_error = 0; 191 worker->had_error = 0;
198 if (worker->status_ < OK) { 192 if (worker->status_ < OK) {
199 #ifdef WEBP_USE_THREAD 193 #ifdef WEBP_USE_THREAD
200 if (pthread_mutex_init(&worker->mutex_, NULL) || 194 if (pthread_mutex_init(&worker->mutex_, NULL) ||
201 pthread_cond_init(&worker->condition_, NULL)) { 195 pthread_cond_init(&worker->condition_, NULL)) {
202 return 0; 196 return 0;
203 } 197 }
204 pthread_mutex_lock(&worker->mutex_); 198 pthread_mutex_lock(&worker->mutex_);
205 ok = !pthread_create(&worker->thread_, NULL, WebPWorkerThreadLoop, worker); 199 ok = !pthread_create(&worker->thread_, NULL, ThreadLoop, worker);
206 if (ok) worker->status_ = OK; 200 if (ok) worker->status_ = OK;
207 pthread_mutex_unlock(&worker->mutex_); 201 pthread_mutex_unlock(&worker->mutex_);
208 #else 202 #else
209 worker->status_ = OK; 203 worker->status_ = OK;
210 #endif 204 #endif
211 } else if (worker->status_ > OK) { 205 } else if (worker->status_ > OK) {
212 ok = WebPWorkerSync(worker); 206 ok = WebPWorkerSync(worker);
213 } 207 }
214 assert(!ok || (worker->status_ == OK)); 208 assert(!ok || (worker->status_ == OK));
215 return ok; 209 return ok;
216 } 210 }
217 211
212 void WebPWorkerExecute(WebPWorker* const worker) {
213 if (worker->hook != NULL) {
214 worker->had_error |= !worker->hook(worker->data1, worker->data2);
215 }
216 }
217
218 void WebPWorkerLaunch(WebPWorker* const worker) { 218 void WebPWorkerLaunch(WebPWorker* const worker) {
219 #ifdef WEBP_USE_THREAD 219 #ifdef WEBP_USE_THREAD
220 WebPWorkerChangeState(worker, WORK); 220 ChangeState(worker, WORK);
221 #else 221 #else
222 if (worker->hook) 222 WebPWorkerExecute(worker);
223 worker->had_error |= !worker->hook(worker->data1, worker->data2);
224 #endif 223 #endif
225 } 224 }
226 225
227 void WebPWorkerEnd(WebPWorker* const worker) { 226 void WebPWorkerEnd(WebPWorker* const worker) {
228 if (worker->status_ >= OK) { 227 if (worker->status_ >= OK) {
229 #ifdef WEBP_USE_THREAD 228 #ifdef WEBP_USE_THREAD
230 WebPWorkerChangeState(worker, NOT_OK); 229 ChangeState(worker, NOT_OK);
231 pthread_join(worker->thread_, NULL); 230 pthread_join(worker->thread_, NULL);
232 pthread_mutex_destroy(&worker->mutex_); 231 pthread_mutex_destroy(&worker->mutex_);
233 pthread_cond_destroy(&worker->condition_); 232 pthread_cond_destroy(&worker->condition_);
234 #else 233 #else
235 worker->status_ = NOT_OK; 234 worker->status_ = NOT_OK;
236 #endif 235 #endif
237 } 236 }
238 assert(worker->status_ == NOT_OK); 237 assert(worker->status_ == NOT_OK);
239 } 238 }
240 239
241 //------------------------------------------------------------------------------ 240 //------------------------------------------------------------------------------
242 241
243 #if defined(__cplusplus) || defined(c_plusplus)
244 } // extern "C"
245 #endif
OLDNEW
« no previous file with comments | « third_party/libwebp/utils/thread.h ('k') | third_party/libwebp/utils/utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698