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