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