IlmThread.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2005-2012, 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. #ifndef INCLUDED_ILM_THREAD_H
  35. #define INCLUDED_ILM_THREAD_H
  36. //-----------------------------------------------------------------------------
  37. //
  38. // class Thread
  39. //
  40. // Class Thread is a portable interface to a system-dependent thread
  41. // primitive. In order to make a thread actually do something useful,
  42. // you must derive a subclass from class Thread and implement the
  43. // run() function. If the operating system supports threading then
  44. // the run() function will be executed int a new thread.
  45. //
  46. // The actual creation of the thread is done by the start() routine
  47. // which then calls the run() function. In general the start()
  48. // routine should be called from the constructor of the derived class.
  49. //
  50. // The base-class thread destructor will join/destroy the thread.
  51. //
  52. // IMPORTANT: Due to the mechanisms that encapsulate the low-level
  53. // threading primitives in a C++ class there is a race condition
  54. // with code resembling the following:
  55. //
  56. // {
  57. // WorkerThread myThread;
  58. // } // myThread goes out of scope, is destroyed
  59. // // and the thread is joined
  60. //
  61. // The race is between the parent thread joining the child thread
  62. // in the destructor of myThread, and the run() function in the
  63. // child thread. If the destructor gets executed first then run()
  64. // will be called with an invalid "this" pointer.
  65. //
  66. // This issue can be fixed by using a Semaphore to keep track of
  67. // whether the run() function has already been called. You can
  68. // include a Semaphore member variable within your derived class
  69. // which you post() on in the run() function, and wait() on in the
  70. // destructor before the thread is joined. Alternatively you could
  71. // do something like this:
  72. //
  73. // Semaphore runStarted;
  74. //
  75. // void WorkerThread::run ()
  76. // {
  77. // runStarted.post()
  78. // // do some work
  79. // ...
  80. // }
  81. //
  82. // {
  83. // WorkerThread myThread;
  84. // runStarted.wait (); // ensure that we have started
  85. // // the run function
  86. // } // myThread goes out of scope, is destroyed
  87. // // and the thread is joined
  88. //
  89. //-----------------------------------------------------------------------------
  90. #include "IlmBaseConfig.h"
  91. #include "IlmThreadExport.h"
  92. #include "IlmThreadNamespace.h"
  93. #ifdef ILMBASE_FORCE_CXX03
  94. # if defined _WIN32 || defined _WIN64
  95. # ifdef NOMINMAX
  96. # undef NOMINMAX
  97. # endif
  98. # define NOMINMAX
  99. # include <windows.h>
  100. # include <process.h>
  101. # elif HAVE_PTHREAD
  102. # include <pthread.h>
  103. # endif
  104. #else
  105. # include <thread>
  106. #endif
  107. ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
  108. //
  109. // Query function to determine if the current platform supports
  110. // threads AND this library was compiled with threading enabled.
  111. //
  112. ILMTHREAD_EXPORT bool supportsThreads ();
  113. class Thread
  114. {
  115. public:
  116. ILMTHREAD_EXPORT Thread ();
  117. ILMTHREAD_EXPORT virtual ~Thread ();
  118. ILMTHREAD_EXPORT void start ();
  119. ILMTHREAD_EXPORT virtual void run () = 0;
  120. private:
  121. #ifdef ILMBASE_FORCE_CXX03
  122. # if defined _WIN32 || defined _WIN64
  123. HANDLE _thread;
  124. # elif HAVE_PTHREAD
  125. pthread_t _thread;
  126. # endif
  127. void operator = (const Thread& t); // not implemented
  128. Thread (const Thread& t); // not implemented
  129. #else
  130. std::thread _thread;
  131. Thread &operator= (const Thread& t) = delete;
  132. Thread (const Thread& t) = delete;
  133. #endif
  134. };
  135. ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
  136. #endif // INCLUDED_ILM_THREAD_H