thread.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2011 Google Inc. All Rights Reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// that can be found in the COPYING file in the root of the source 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// tree. An additional intellectual property rights grant can be found 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// in the file PATENTS. All contributing project authors may 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// be found in the AUTHORS file in the root of the source tree. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ----------------------------------------------------------------------------- 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Multi-threaded worker 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: Skal (pascal.massimino@gmail.com) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef WEBP_UTILS_THREAD_H_ 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WEBP_UTILS_THREAD_H_ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef HAVE_CONFIG_H 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "config.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef __cplusplus 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef WEBP_USE_THREAD 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_WIN32) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef HANDLE pthread_t; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CRITICAL_SECTION pthread_mutex_t; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE waiting_sem_; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE received_sem_; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE signal_event_; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} pthread_cond_t; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pthread.h> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* _WIN32 */ 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* WEBP_USE_THREAD */ 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// State of the worker thread object 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOT_OK = 0, // object is unusable 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OK, // ready to work 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WORK // busy finishing the current task 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} WebPWorkerStatus; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Function to be called by the worker thread. Takes two opaque pointers as 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// arguments (data1 and data2), and should return false in case of error. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int (*WebPWorkerHook)(void*, void*); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Synchronize object used to launch job in the worker thread 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct { 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef WEBP_USE_THREAD 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_mutex_t mutex_; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_cond_t condition_; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_t thread_; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebPWorkerStatus status_; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebPWorkerHook hook; // hook to call 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* data1; // first argument passed to 'hook' 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* data2; // second argument passed to 'hook' 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int had_error; // return value of the last call to 'hook' 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} WebPWorker; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Must be called first, before any other method. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPWorkerInit(WebPWorker* const worker); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Must be called to initialize the object and spawn the thread. Re-entrant. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Will potentially launch the thread. Returns false in case of error. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int WebPWorkerReset(WebPWorker* const worker); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Makes sure the previous work is finished. Returns true if worker->had_error 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// was not set and no error condition was triggered by the working thread. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int WebPWorkerSync(WebPWorker* const worker); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Triggers the thread to call hook() with data1 and data2 argument. These 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// hook/data1/data2 can be changed at any time before calling this function, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but not be changed afterward until the next call to WebPWorkerSync(). 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPWorkerLaunch(WebPWorker* const worker); 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This function is similar to WebPWorkerLaunch() except that it calls the 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// hook directly instead of using a thread. Convenient to bypass the thread 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// mechanism while still using the WebPWorker structs. WebPWorkerSync() must 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// still be called afterward (for error reporting). 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebPWorkerExecute(WebPWorker* const worker); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Kill the thread and terminate the object. To use the object again, one 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// must call WebPWorkerReset() again. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPWorkerEnd(WebPWorker* const worker); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef __cplusplus 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // extern "C" 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* WEBP_UTILS_THREAD_H_ */ 98