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
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "../webp/config.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "../webp/types.h"
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef __cplusplus
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// State of the worker thread object
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOT_OK = 0,   // object is unusable
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OK,           // ready to work
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WORK          // busy finishing the current task
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} WebPWorkerStatus;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Function to be called by the worker thread. Takes two opaque pointers as
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// arguments (data1 and data2), and should return false in case of error.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int (*WebPWorkerHook)(void*, void*);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Platform-dependent implementation details for the worker.
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)typedef struct WebPWorkerImpl WebPWorkerImpl;
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Synchronization object used to launch job in the worker thread
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct {
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebPWorkerImpl* impl_;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebPWorkerStatus status_;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebPWorkerHook hook;    // hook to call
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* data1;            // first argument passed to 'hook'
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* data2;            // second argument passed to 'hook'
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int had_error;          // return value of the last call to 'hook'
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} WebPWorker;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// The interface for all thread-worker related functions. All these functions
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// must be implemented.
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)typedef struct {
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Must be called first, before any other method.
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void (*Init)(WebPWorker* const worker);
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Must be called to initialize the object and spawn the thread. Re-entrant.
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Will potentially launch the thread. Returns false in case of error.
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int (*Reset)(WebPWorker* const worker);
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Makes sure the previous work is finished. Returns true if worker->had_error
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // was not set and no error condition was triggered by the working thread.
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int (*Sync)(WebPWorker* const worker);
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Triggers the thread to call hook() with data1 and data2 arguments. These
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // hook/data1/data2 values can be changed at any time before calling this
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // function, but not be changed afterward until the next call to Sync().
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void (*Launch)(WebPWorker* const worker);
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // This function is similar to Launch() except that it calls the
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // hook directly instead of using a thread. Convenient to bypass the thread
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // mechanism while still using the WebPWorker structs. Sync() must
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // still be called afterward (for error reporting).
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void (*Execute)(WebPWorker* const worker);
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Kill the thread and terminate the object. To use the object again, one
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // must call Reset() again.
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void (*End)(WebPWorker* const worker);
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} WebPWorkerInterface;
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Install a new set of threading functions, overriding the defaults. This
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// should be done before any workers are started, i.e., before any encoding or
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// decoding takes place. The contents of the interface struct are copied, it
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// is safe to free the corresponding memory after this call. This function is
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// not thread-safe. Return false in case of invalid pointer or methods.
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WEBP_EXTERN(int) WebPSetWorkerInterface(
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const WebPWorkerInterface* const interface);
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Retrieve the currently set thread worker interface.
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WEBP_EXTERN(const WebPWorkerInterface*) WebPGetWorkerInterface(void);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef __cplusplus
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}    // extern "C"
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  /* WEBP_UTILS_THREAD_H_ */
94