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++

/*=========================================================================
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