1/////////////////////////////////////////////////////////////////////////// 2// 3// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas 4// Digital Ltd. LLC 5// 6// All rights reserved. 7// 8// Redistribution and use in source and binary forms, with or without 9// modification, are permitted provided that the following conditions are 10// met: 11// * Redistributions of source code must retain the above copyright 12// notice, this list of conditions and the following disclaimer. 13// * Redistributions in binary form must reproduce the above 14// copyright notice, this list of conditions and the following disclaimer 15// in the documentation and/or other materials provided with the 16// distribution. 17// * Neither the name of Industrial Light & Magic nor the names of 18// its contributors may be used to endorse or promote products derived 19// from this software without specific prior written permission. 20// 21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32// 33/////////////////////////////////////////////////////////////////////////// 34 35#ifndef INCLUDED_ILM_THREAD_H 36#define INCLUDED_ILM_THREAD_H 37 38//----------------------------------------------------------------------------- 39// 40// class Thread 41// 42// Class Thread is a portable interface to a system-dependent thread 43// primitive. In order to make a thread actually do something useful, 44// you must derive a subclass from class Thread and implement the 45// run() function. If the operating system supports threading then 46// the run() function will be executed int a new thread. 47// 48// The actual creation of the thread is done by the start() routine 49// which then calls the run() function. In general the start() 50// routine should be called from the constructor of the derived class. 51// 52// The base-class thread destructor will join/destroy the thread. 53// 54// IMPORTANT: Due to the mechanisms that encapsulate the low-level 55// threading primitives in a C++ class there is a race condition 56// with code resembling the following: 57// 58// { 59// WorkerThread myThread; 60// } // myThread goes out of scope, is destroyed 61// // and the thread is joined 62// 63// The race is between the parent thread joining the child thread 64// in the destructor of myThread, and the run() function in the 65// child thread. If the destructor gets executed first then run() 66// will be called with an invalid "this" pointer. 67// 68// This issue can be fixed by using a Semaphore to keep track of 69// whether the run() function has already been called. You can 70// include a Semaphore member variable within your derived class 71// which you post() on in the run() function, and wait() on in the 72// destructor before the thread is joined. Alternatively you could 73// do something like this: 74// 75// Semaphore runStarted; 76// 77// void WorkerThread::run () 78// { 79// runStarted.post() 80// // do some work 81// ... 82// } 83// 84// { 85// WorkerThread myThread; 86// runStarted.wait (); // ensure that we have started 87// // the run function 88// } // myThread goes out of scope, is destroyed 89// // and the thread is joined 90// 91//----------------------------------------------------------------------------- 92 93#include "IlmBaseConfig.h" 94 95#if defined _WIN32 || defined _WIN64 96 #ifdef NOMINMAX 97 #undef NOMINMAX 98 #endif 99 #define NOMINMAX 100 #include <windows.h> 101 #include <process.h> 102#elif HAVE_PTHREAD 103 #include <pthread.h> 104#endif 105 106#if defined(OPENEXR_DLL) && !defined(ZENO_STATIC) 107 #ifdef ILMTHREAD_EXPORTS 108 #define ILMTHREAD_EXPORT __declspec(dllexport) 109 #else 110 #define ILMTHREAD_EXPORT __declspec(dllimport) 111 #endif 112#else 113 #define ILMTHREAD_EXPORT 114#endif 115 116namespace IlmThread { 117 118// 119// Query function to determine if the current platform supports 120// threads AND this library was compiled with threading enabled. 121// 122 123ILMTHREAD_EXPORT bool supportsThreads (); 124 125 126class ILMTHREAD_EXPORT Thread 127{ 128 public: 129 130 Thread (); 131 virtual ~Thread (); 132 133 void start (); 134 virtual void run () = 0; 135 136 private: 137 138 #if defined _WIN32 || defined _WIN64 139 HANDLE _thread; 140 #elif HAVE_PTHREAD 141 pthread_t _thread; 142 #endif 143 144 void operator = (const Thread& t); // not implemented 145 Thread (const Thread& t); // not implemented 146}; 147 148 149} // namespace IlmThread 150 151#endif 152