193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Copyright 2011 Google Inc. All Rights Reserved.
293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)//
393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license
493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// that can be found in the COPYING file in the root of the source
593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// tree. An additional intellectual property rights grant can be found
693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// in the file PATENTS. All contributing project authors may
793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// be found in the AUTHORS file in the root of the source tree.
893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// -----------------------------------------------------------------------------
993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)//
1093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Multi-threaded worker
1193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)//
1293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Author: Skal (pascal.massimino@gmail.com)
1393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#ifndef WEBP_UTILS_THREAD_H_
1593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#define WEBP_UTILS_THREAD_H_
1693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#ifdef HAVE_CONFIG_H
1893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "config.h"
1993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#endif
2093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
2193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "webp/types.h"
2293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
2393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#ifdef __cplusplus
2493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)extern "C" {
2593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#endif
2693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
2793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// State of the worker thread object
2893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)typedef enum {
2993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)  NOT_OK = 0,   // object is unusable
3093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)  OK,           // ready to work
3193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)  WORK          // busy finishing the current task
3293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} WebPWorkerStatus;
3393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
3406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)// Function to be called by the worker thread. Takes two opaque pointers as
3506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)// arguments (data1 and data2), and should return false in case of error.
3693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)typedef int (*WebPWorkerHook)(void*, void*);
3793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)// Platform-dependent implementation details for the worker.
391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)typedef struct WebPWorkerImpl WebPWorkerImpl;
4093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
4193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Synchronization object used to launch job in the worker thread
42521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)typedef struct {
43521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)  WebPWorkerImpl* impl_;
44521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)  WebPWorkerStatus status_;
45521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)  WebPWorkerHook hook;    // hook to call
46521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)  void* data1;            // first argument passed to 'hook'
471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  void* data2;            // second argument passed to 'hook'
481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  int had_error;          // return value of the last call to 'hook'
491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)} WebPWorker;
501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)// The interface for all thread-worker related functions. All these functions
521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)// must be implemented.
531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)typedef struct {
541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // Must be called first, before any other method.
551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  void (*Init)(WebPWorker* const worker);
561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // Must be called to initialize the object and spawn the thread. Re-entrant.
571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // Will potentially launch the thread. Returns false in case of error.
581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  int (*Reset)(WebPWorker* const worker);
591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // Makes sure the previous work is finished. Returns true if worker->had_error
601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // was not set and no error condition was triggered by the working thread.
611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  int (*Sync)(WebPWorker* const worker);
621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // Triggers the thread to call hook() with data1 and data2 arguments. These
631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // hook/data1/data2 values can be changed at any time before calling this
641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // function, but not be changed afterward until the next call to Sync().
651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  void (*Launch)(WebPWorker* const worker);
661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // This function is similar to Launch() except that it calls the
671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // hook directly instead of using a thread. Convenient to bypass the thread
68521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)  // mechanism while still using the WebPWorker structs. Sync() must
691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // still be called afterward (for error reporting).
701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  void (*Execute)(WebPWorker* const worker);
711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // Kill the thread and terminate the object. To use the object again, one
72521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)  // must call Reset() again.
73521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)  void (*End)(WebPWorker* const worker);
74521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} WebPWorkerInterface;
7593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
7693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Install a new set of threading functions, overriding the defaults. This
7793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// should be done before any workers are started, i.e., before any encoding or
7893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// decoding takes place. The contents of the interface struct are copied, it
7993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// is safe to free the corresponding memory after this call. This function is
8093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// not thread-safe. Return false in case of invalid pointer or methods.
8193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)WEBP_EXTERN(int) WebPSetWorkerInterface(
8293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const WebPWorkerInterface* const interface);
8393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
8493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Retrieve the currently set thread worker interface.
8593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)WEBP_EXTERN(const WebPWorkerInterface*) WebPGetWorkerInterface(void);
86591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
87f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)//------------------------------------------------------------------------------
88f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
8993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#ifdef __cplusplus
9093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}    // extern "C"
9151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#endif
9293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
93f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#endif  /* WEBP_UTILS_THREAD_H_ */
94f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)