home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / h / vd2 / system / thread.h < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  8.2 KB  |  270 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    System library component
  3. //    Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
  4. //
  5. //    Beginning with 1.6.0, the VirtualDub system library is licensed
  6. //    differently than the remainder of VirtualDub.  This particular file is
  7. //    thus licensed as follows (the "zlib" license):
  8. //
  9. //    This software is provided 'as-is', without any express or implied
  10. //    warranty.  In no event will the authors be held liable for any
  11. //    damages arising from the use of this software.
  12. //
  13. //    Permission is granted to anyone to use this software for any purpose,
  14. //    including commercial applications, and to alter it and redistribute it
  15. //    freely, subject to the following restrictions:
  16. //
  17. //    1.    The origin of this software must not be misrepresented; you must
  18. //        not claim that you wrote the original software. If you use this
  19. //        software in a product, an acknowledgment in the product
  20. //        documentation would be appreciated but is not required.
  21. //    2.    Altered source versions must be plainly marked as such, and must
  22. //        not be misrepresented as being the original software.
  23. //    3.    This notice may not be removed or altered from any source
  24. //        distribution.
  25.  
  26. #ifndef f_VD2_SYSTEM_THREAD_H
  27. #define f_VD2_SYSTEM_THREAD_H
  28.  
  29. #ifdef _MSC_VER
  30.     #pragma once
  31. #endif
  32.  
  33. #include <vd2/system/vdtypes.h>
  34. #include <vd2/system/atomic.h>
  35.  
  36. typedef void *VDThreadHandle;
  37. typedef uint32 VDThreadID;
  38. typedef uint32 VDThreadId;
  39. typedef uint32 VDProcessId;
  40.  
  41. struct _RTL_CRITICAL_SECTION;
  42.  
  43. extern "C" void __declspec(dllimport) __stdcall InitializeCriticalSection(_RTL_CRITICAL_SECTION *lpCriticalSection);
  44. extern "C" void __declspec(dllimport) __stdcall LeaveCriticalSection(_RTL_CRITICAL_SECTION *lpCriticalSection);
  45. extern "C" void __declspec(dllimport) __stdcall EnterCriticalSection(_RTL_CRITICAL_SECTION *lpCriticalSection);
  46. extern "C" void __declspec(dllimport) __stdcall DeleteCriticalSection(_RTL_CRITICAL_SECTION *lpCriticalSection);
  47. extern "C" unsigned long __declspec(dllimport) __stdcall WaitForSingleObject(void *hHandle, unsigned long dwMilliseconds);
  48. extern "C" int __declspec(dllimport) __stdcall ReleaseSemaphore(void *hSemaphore, long lReleaseCount, long *lpPreviousCount);
  49.  
  50. VDThreadID VDGetCurrentThreadID();
  51. VDProcessId VDGetCurrentProcessId();
  52.  
  53. void VDSetThreadDebugName(VDThreadID tid, const char *name);
  54. void VDThreadSleep(int milliseconds);
  55.  
  56. ///////////////////////////////////////////////////////////////////////////
  57. //
  58. //    VDThread
  59. //
  60. //    VDThread is a quick way to portably create threads -- to use it,
  61. //    derive a subclass from it that implements the ThreadRun() function.
  62. //
  63. //    Win32 notes:
  64. //
  65. //    The thread startup code will attempt to notify the VC++ debugger of
  66. //    the debug name of the thread.  Only the first 9 characters are used
  67. //    by Visual C 6.0; Visual Studio .NET will accept a few dozen.
  68. //
  69. //    VDThread objects must not be WaitThread()ed or destructed from a
  70. //    DllMain() function, TLS callback for an executable, or static
  71. //    destructor unless the thread has been detached from the object.
  72. //  The reason is that Win32 serializes calls to DllMain() functions.
  73. //  If you attempt to do so, you will cause a deadlock when Win32
  74. //  attempts to fire thread detach notifications.
  75. //
  76. ///////////////////////////////////////////////////////////////////////////
  77.  
  78. class VDThread {
  79. public:
  80.     VDThread(const char *pszDebugName = NULL);    // NOTE: pszDebugName must have static duration
  81.     ~VDThread() throw();
  82.  
  83.     // external functions
  84.  
  85.     bool ThreadStart();                            // start thread
  86.     void ThreadDetach();                        // detach thread (wait() won't be called)
  87.     void ThreadWait();                            // wait for thread to finish
  88.  
  89.     bool isThreadActive();
  90.  
  91.     bool isThreadAttached() const {                // NOTE: Will return true if thread started, even if thread has since exited
  92.         return mhThread != 0;
  93.     }
  94.  
  95.     VDThreadHandle getThreadHandle() const {    // get handle to thread (Win32: HANDLE)
  96.         return mhThread;
  97.     }
  98.  
  99.     VDThreadID getThreadID() const {            // get ID of thread (Win32: DWORD)
  100.         return mThreadID;
  101.     }
  102.  
  103.     void *ThreadLocation() const;                // retrieve current EIP of thread (use only for debug purposes -- may not return reliable information on syscall, etc.)
  104.  
  105.     // thread-local functions
  106.  
  107.     virtual void ThreadRun() = 0;                // thread, come to life
  108.     void ThreadFinish();                        // exit thread
  109.  
  110. private:
  111.     static unsigned __stdcall StaticThreadStart(void *pThis);
  112.  
  113.     const char *mpszDebugName;
  114.     VDThreadHandle    mhThread;
  115.     VDThreadID        mThreadID;
  116. };
  117.  
  118. ///////////////////////////////////////////////////////////////////////////
  119.  
  120. class VDCriticalSection {
  121. private:
  122.     struct CritSec {                // This is a clone of CRITICAL_SECTION.
  123.         void    *DebugInfo;
  124.         sint32    LockCount;
  125.         sint32    RecursionCount;
  126.         void    *OwningThread;
  127.         void    *LockSemaphore;
  128.         uint32    SpinCount;
  129.     } csect;
  130.  
  131.     VDCriticalSection(const VDCriticalSection&);
  132.     const VDCriticalSection& operator=(const VDCriticalSection&);
  133.     static void StructCheck();
  134. public:
  135.     class AutoLock {
  136.     private:
  137.         VDCriticalSection& cs;
  138.     public:
  139.         AutoLock(VDCriticalSection& csect) : cs(csect) { cs.Lock(); }
  140.         ~AutoLock() { cs.Unlock(); }
  141.  
  142.         inline operator bool() const { return false; }
  143.     };
  144.  
  145.     VDCriticalSection() {
  146.         InitializeCriticalSection((_RTL_CRITICAL_SECTION *)&csect);
  147.     }
  148.  
  149.     ~VDCriticalSection() {
  150.         DeleteCriticalSection((_RTL_CRITICAL_SECTION *)&csect);
  151.     }
  152.  
  153.     void operator++() {
  154.         EnterCriticalSection((_RTL_CRITICAL_SECTION *)&csect);
  155.     }
  156.  
  157.     void operator--() {
  158.         LeaveCriticalSection((_RTL_CRITICAL_SECTION *)&csect);
  159.     }
  160.  
  161.     void Lock() {
  162.         EnterCriticalSection((_RTL_CRITICAL_SECTION *)&csect);
  163.     }
  164.  
  165.     void Unlock() {
  166.         LeaveCriticalSection((_RTL_CRITICAL_SECTION *)&csect);
  167.     }
  168. };
  169.  
  170. // 'vdsynchronized' keyword
  171. //
  172. // The vdsynchronized(lock) keyword emulates Java's 'synchronized' keyword, which
  173. // protects the following statement or block from race conditions by obtaining a
  174. // lock during its execution:
  175. //
  176. //        vdsynchronized(list_lock) {
  177. //            mList.pop_back();
  178. //            if (mList.empty())
  179. //                return false;
  180. //        }
  181. //
  182. // The construct is exception safe and will release the lock even if a return,
  183. // continue, break, or thrown exception exits the block.  However, hardware
  184. // exceptions (access violations) may not work due to synchronous model
  185. // exception handling.
  186. //
  187. // There are two Visual C++ bugs we need to work around here (both are in VC6 and VC7).
  188. //
  189. // 1) Declaring an object with a non-trivial destructor in a switch() condition
  190. //    causes a C1001 INTERNAL COMPILER ERROR.
  191. //
  192. // 2) Using __LINE__ in a macro expanded in a function with Edit and Continue (/ZI)
  193. //    breaks the preprocessor (KB article Q199057).  Shame, too, because without it
  194. //    all the autolocks look the same.
  195.  
  196. #define vdsynchronized2(lock) if(VDCriticalSection::AutoLock vd__lock=(lock))VDNEVERHERE;else
  197. #define vdsynchronized1(lock) vdsynchronized2(lock)
  198. #define vdsynchronized(lock) vdsynchronized1(lock)
  199.  
  200. ///////////////////////////////////////////////////////////////////////////
  201.  
  202. class VDSignalBase {
  203. protected:
  204.     void *hEvent;
  205.  
  206. public:
  207.     ~VDSignalBase();
  208.  
  209.     void signal();
  210.     bool check();
  211.     void wait();
  212.     int wait(VDSignalBase *second);
  213.     int wait(VDSignalBase *second, VDSignalBase *third);
  214.     static int waitMultiple(const VDSignalBase **signals, int count);
  215.     void *getHandle() { return hEvent; }
  216.  
  217.     void operator()() { signal(); }
  218. };
  219.  
  220. class VDSignal : public VDSignalBase {
  221.     VDSignal(const VDSignal&);
  222.     VDSignal& operator=(const VDSignal&);
  223. public:
  224.     VDSignal();
  225. };
  226.  
  227. class VDSignalPersistent : public VDSignalBase {
  228.     VDSignalPersistent(const VDSignalPersistent&);
  229.     VDSignalPersistent& operator=(const VDSignalPersistent&);
  230. public:
  231.     VDSignalPersistent();
  232.  
  233.     void unsignal();
  234. };
  235.  
  236. ///////////////////////////////////////////////////////////////////////////
  237.  
  238. class VDSemaphore {
  239. public:
  240.     VDSemaphore(int initial);
  241.     ~VDSemaphore();
  242.  
  243.     void *GetHandle() const {
  244.         return mKernelSema;
  245.     }
  246.  
  247.     void Reset(int count);
  248.  
  249.     void Wait() {
  250.         WaitForSingleObject(mKernelSema, 0xFFFFFFFFU);
  251.     }
  252.  
  253.     bool Wait(int timeout) {
  254.         return 0 == WaitForSingleObject(mKernelSema, timeout);
  255.     }
  256.  
  257.     bool TryWait() {
  258.         return 0 == WaitForSingleObject(mKernelSema, 0);
  259.     }
  260.  
  261.     void Post() {
  262.         ReleaseSemaphore(mKernelSema, 1, NULL);
  263.     }
  264.  
  265. private:
  266.     void *mKernelSema;
  267. };
  268.  
  269. #endif
  270.