You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
5.8 KiB
C
203 lines
5.8 KiB
C
3 weeks ago
|
/*=========================================================================
|
||
|
|
||
|
Program: Visualization Toolkit
|
||
|
Module: vtkConditionVariable.h
|
||
|
|
||
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
||
|
All rights reserved.
|
||
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
||
|
|
||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
PURPOSE. See the above copyright notice for more information.
|
||
|
|
||
|
=========================================================================*/
|
||
|
/**
|
||
|
* @class vtkConditionVariable
|
||
|
* @brief mutual exclusion locking class
|
||
|
*
|
||
|
* vtkConditionVariable allows the locking of variables which are accessed
|
||
|
* through different threads. This header file also defines
|
||
|
* vtkSimpleConditionVariable which is not a subclass of vtkObject.
|
||
|
*
|
||
|
* The win32 implementation is based on notes provided by
|
||
|
* Douglas C. Schmidt and Irfan Pyarali,
|
||
|
* Department of Computer Science,
|
||
|
* Washington University, St. Louis, Missouri.
|
||
|
* http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
|
||
|
*/
|
||
|
|
||
|
#ifndef vtkConditionVariable_h
|
||
|
#define vtkConditionVariable_h
|
||
|
|
||
|
#include "vtkCommonCoreModule.h" // For export macro
|
||
|
#include "vtkObject.h"
|
||
|
|
||
|
#include "vtkMutexLock.h" // Need for friend access to vtkSimpleMutexLock
|
||
|
|
||
|
#if defined(VTK_USE_PTHREADS)
|
||
|
#include <pthread.h> // Need POSIX thread implementation of mutex (even win32 provides mutexes)
|
||
|
typedef pthread_cond_t vtkConditionType;
|
||
|
#endif
|
||
|
|
||
|
// Typically a top level windows application sets _WIN32_WINNT. If it is not set we set it to
|
||
|
// 0x0501 (Windows XP)
|
||
|
#ifdef VTK_USE_WIN32_THREADS
|
||
|
#ifndef _WIN32_WINNT
|
||
|
#define _WIN32_WINNT 0x0501 // 0x0501 means target Windows XP or later
|
||
|
#endif
|
||
|
#include "vtkWindows.h" // Needed for win32 CRITICAL_SECTION, HANDLE, etc.
|
||
|
#endif
|
||
|
|
||
|
#ifdef VTK_USE_WIN32_THREADS
|
||
|
#if 1
|
||
|
typedef struct
|
||
|
{
|
||
|
// Number of threads waiting on condition.
|
||
|
int WaitingThreadCount;
|
||
|
|
||
|
// Lock for WaitingThreadCount
|
||
|
CRITICAL_SECTION WaitingThreadCountCritSec;
|
||
|
|
||
|
// Semaphore to block threads waiting for the condition to change.
|
||
|
vtkWindowsHANDLE Semaphore;
|
||
|
|
||
|
// An event used to wake up thread(s) waiting on the semaphore
|
||
|
// when pthread_cond_signal or pthread_cond_broadcast is called.
|
||
|
vtkWindowsHANDLE DoneWaiting;
|
||
|
|
||
|
// Was pthread_cond_broadcast called?
|
||
|
size_t WasBroadcast;
|
||
|
} pthread_cond_t;
|
||
|
|
||
|
typedef pthread_cond_t vtkConditionType;
|
||
|
#else // 0
|
||
|
typedef struct
|
||
|
{
|
||
|
// Number of threads waiting on condition.
|
||
|
int WaitingThreadCount;
|
||
|
|
||
|
// Lock for WaitingThreadCount
|
||
|
CRITICAL_SECTION WaitingThreadCountCritSec;
|
||
|
|
||
|
// Number of threads to release when pthread_cond_broadcast()
|
||
|
// or pthread_cond_signal() is called.
|
||
|
int ReleaseCount;
|
||
|
|
||
|
// Used to prevent one thread from decrementing ReleaseCount all
|
||
|
// by itself instead of letting others respond.
|
||
|
int NotifyCount;
|
||
|
|
||
|
// A manual-reset event that's used to block and release waiting threads.
|
||
|
vtkWindowsHANDLE Event;
|
||
|
} pthread_cond_t;
|
||
|
|
||
|
typedef pthread_cond_t vtkConditionType;
|
||
|
#endif // 0
|
||
|
#endif // VTK_USE_WIN32_THREADS
|
||
|
|
||
|
#ifndef VTK_USE_PTHREADS
|
||
|
#ifndef VTK_USE_WIN32_THREADS
|
||
|
typedef int vtkConditionType;
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
// Condition variable that is not a vtkObject.
|
||
|
class VTKCOMMONCORE_EXPORT vtkSimpleConditionVariable
|
||
|
{
|
||
|
public:
|
||
|
vtkSimpleConditionVariable();
|
||
|
~vtkSimpleConditionVariable();
|
||
|
|
||
|
static vtkSimpleConditionVariable* New();
|
||
|
|
||
|
void Delete() { delete this; }
|
||
|
|
||
|
/**
|
||
|
* Wake one thread waiting for the condition to change.
|
||
|
*/
|
||
|
void Signal();
|
||
|
|
||
|
/**
|
||
|
* Wake all threads waiting for the condition to change.
|
||
|
*/
|
||
|
void Broadcast();
|
||
|
|
||
|
/**
|
||
|
* Wait for the condition to change.
|
||
|
* Upon entry, the mutex must be locked and the lock held by the calling thread.
|
||
|
* Upon exit, the mutex will be locked and held by the calling thread.
|
||
|
* Between entry and exit, the mutex will be unlocked and may be held by other threads.
|
||
|
|
||
|
* @param mutex The mutex that should be locked on entry and will be locked on exit (but not in
|
||
|
between)
|
||
|
* @retval Normally, this function returns 0. Should a thread be interrupted by a signal, a
|
||
|
non-zero value may be returned.
|
||
|
*/
|
||
|
int Wait(vtkSimpleMutexLock& mutex);
|
||
|
|
||
|
protected:
|
||
|
vtkConditionType ConditionVariable;
|
||
|
|
||
|
private:
|
||
|
vtkSimpleConditionVariable(const vtkSimpleConditionVariable& other) = delete;
|
||
|
vtkSimpleConditionVariable& operator=(const vtkSimpleConditionVariable& rhs) = delete;
|
||
|
};
|
||
|
|
||
|
class VTKCOMMONCORE_EXPORT vtkConditionVariable : public vtkObject
|
||
|
{
|
||
|
public:
|
||
|
static vtkConditionVariable* New();
|
||
|
vtkTypeMacro(vtkConditionVariable, vtkObject);
|
||
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
||
|
|
||
|
/**
|
||
|
* Wake one thread waiting for the condition to change.
|
||
|
*/
|
||
|
void Signal();
|
||
|
|
||
|
/**
|
||
|
* Wake all threads waiting for the condition to change.
|
||
|
*/
|
||
|
void Broadcast();
|
||
|
|
||
|
/**
|
||
|
* Wait for the condition to change.
|
||
|
* Upon entry, the mutex must be locked and the lock held by the calling thread.
|
||
|
* Upon exit, the mutex will be locked and held by the calling thread.
|
||
|
* Between entry and exit, the mutex will be unlocked and may be held by other threads.
|
||
|
|
||
|
* @param mutex The mutex that should be locked on entry and will be locked on exit (but not in
|
||
|
between)
|
||
|
* @retval Normally, this function returns 0. Should a thread be interrupted by a signal, a
|
||
|
non-zero value may be returned.
|
||
|
*/
|
||
|
int Wait(vtkMutexLock* mutex);
|
||
|
|
||
|
protected:
|
||
|
vtkConditionVariable() {}
|
||
|
|
||
|
vtkSimpleConditionVariable SimpleConditionVariable;
|
||
|
|
||
|
private:
|
||
|
vtkConditionVariable(const vtkConditionVariable&) = delete;
|
||
|
void operator=(const vtkConditionVariable&) = delete;
|
||
|
};
|
||
|
|
||
|
inline void vtkConditionVariable::Signal()
|
||
|
{
|
||
|
this->SimpleConditionVariable.Signal();
|
||
|
}
|
||
|
|
||
|
inline void vtkConditionVariable::Broadcast()
|
||
|
{
|
||
|
this->SimpleConditionVariable.Broadcast();
|
||
|
}
|
||
|
|
||
|
inline int vtkConditionVariable::Wait(vtkMutexLock* lock)
|
||
|
{
|
||
|
return this->SimpleConditionVariable.Wait(lock->SimpleMutexLock);
|
||
|
}
|
||
|
|
||
|
#endif // vtkConditionVariable_h
|