#include <coherence/util/ThreadGate.hpp>
Inherits Object.
The algorithm is based on a gate concept, allowing threads in (enter) and out (exit), but occasionally shutting the gate (close) such that other threads cannot enter and exit. However, since threads may "be inside", the gate cannot fully close until they leave (exit). Once all threads are out, the gate is closed, and can be re-opened (open) or permanently closed (destroy).
Each call to enter requires a corresponding call to exit, similar to the implementation of the COH_SYNCHRONIZED macro that calls Object::lock at the the beginning of the synchronized portion and protects the synchronized portion with a try..catch construct that ensures the execution of a Object::unlock call. For example, the following would ensure proper clean-up using a ThreadGate: The enter/exit calls can be nested; the same thread can invoke enter multiple times as long as exit is invoked a corresponding number of times. The close/open calls work in the same manner. Lastly, the thread that closes the gate may continue to enter/exit the gate even when it is closed since that thread has exclusive control of the gate.
To make usage of these calls easier, the following macros have been defined:
COH_GATE_ENTER (hGate) // read lock acquired { // read operations go here // ... // ... } // read lock released // outside of sync block
COH_GATE_CLOSE (hGate) // write lock acquired { // write operations go here // ... // ... } // write lock released // outside of sync block
COH_GATE_BAR (hGate) // additional readers are blocked { // non-synchronized ops COH_GATE_CLOSE (hGate) // write lock acquired { // ... // ... } // inner-write lock released // gate still locked } // gate opened // outside of sync block
Public Types | |
enum | Status |
State identifiers. | |
typedef spec::Handle | Handle |
ThreadGate Handle definition. | |
typedef spec::View | View |
ThreadGate View definition. | |
typedef spec::Holder | Holder |
ThreadGate Holder definition. | |
Public Member Functions | |
virtual bool | barEntry (int64_t cMillis=infinite) |
Bar entry of the thread gate by other threads, but do not wait for the gate to close. | |
virtual bool | close (int64_t cMillis=infinite) |
Close the thread gate. | |
virtual void | destroy () |
Destroy the thread gate. | |
virtual bool | enter (int64_t cMillis=infinite) |
Enter the thread gate. | |
virtual void | exit () |
Exit the gate. | |
virtual void | open () |
After entry into the ThreadGate is restricted by a call to barEntry() or close(), it can be re-opened by calling this method. | |
virtual int32_t | getActiveCount () const |
Return the number of entered threads. | |
virtual bool | isActiveThread () const |
Determine if the current thread has entered and not exited. | |
virtual int32_t | getCloseCount () const |
Return the number of unmatched completed close/barEntry calls. | |
virtual Status | getStatus () const |
Return the current thread gate status. | |
virtual TypedHandle < const String > | toString () const |
Output a human-readable description of this Object to the given stream. Note that when overriding this method the return type must be TypedHandle<const String> rather then String::View. These two types are assignment compatible but not equivalent and declaring the override with String::View will not be a compatible override. coherence::lang::operator<<(std::ostream, Object::View) is defined and will call into the toString method, to output Objects. If a managed String object is desired, the COH_TO_STRING macro can be used to build up a String from streamable contents and is generally how toString() will be implemented.
Object::View vKey = ... Object::View vValue = ... std::cout << vKey << " = " << vValue << std::endl; String::View vs = COH_TO_STRING(vKey << " = " << vValue); The COH_TO_STRING macro is also the most common way to implement the toString method. For example:
virtual TypedHandle<const String> Person::toString() const { return COH_TO_STRING("Name: " << f_sName << " SSN: " << f_nSSN); }
| |
Static Public Attributes | |
static const int32_t | max_enters |
The maximum number of threads allowed in the gate at one time. | |
static const int64_t | infinite |
The constant representing wait forever. | |
static const int64_t | immediate |
The constant representing not to wait. | |
Protected Member Functions | |
ThreadGate () | |
Create a new ThreadGate. | |
virtual void | setCloseCount (int32_t cClose) |
Specify the number of unmatched completed close/barEntry calls. | |
virtual Thread::View | getClosingThread () const |
Return the thread that is closing the gate. | |
virtual void | setClosingThread (Thread::View vThread) |
Specify the thread id that is closing the gate. | |
virtual Status | updateStatus (Status nStatus) |
Update the current thread gate status, without changing the active count. | |
virtual int64_t | doWait (int64_t cMillis) |
Wait up to the specified number of milliseconds for notification. | |
Classes | |
class | Counter |
Counter is a mutable integer class. More... | |
class | GateBlock |
The EnterBlock class allows for easy creation of ThreadGate::enter code. More... |
virtual bool barEntry | ( | int64_t | cMillis = infinite |
) | [virtual] |
Bar entry of the thread gate by other threads, but do not wait for the gate to close.
When all other threads have exited, the thread gate will be closeable by the thread which barred entry. Each successful invocation of this method must ultimately have a corresponding invocation of the open() method (assuming the thread gate is not destroyed), even if the calling thread does not subsequently close the gate.
cMillis | maximum number of milliseconds to wait; pass infinite for forever or immediate for no wait |
virtual bool close | ( | int64_t | cMillis = infinite |
) | [virtual] |
Close the thread gate.
A thread uses this method to obtain exclusive access to the resource represented by the thread gate. Each invocation of this method must ultimately have a corresponding invocation of the open() method.
cMillis | maximum number of milliseconds to wait; pass infinite for forever or immediate for no wait |
virtual void destroy | ( | ) | [virtual] |
Destroy the thread gate.
This method can only be invoked if the gate is already closed by the calling thread.
virtual bool enter | ( | int64_t | cMillis = infinite |
) | [virtual] |
Enter the thread gate.
A thread uses this method to obtain non-exclusive access to the resource represented by the thread gate. Each successful invocation of this method must ultimately have a corresponding invocation of the exit() method.
cMillis | maximum number of milliseconds to wait; pass infinite for forever or immediate for no wait |
virtual void exit | ( | ) | [virtual] |
Exit the gate.
A thread must invoke this method corresponding to each successful invocation of the enter method.
virtual void open | ( | ) | [virtual] |
After entry into the ThreadGate is restricted by a call to barEntry() or close(), it can be re-opened by calling this method.
Only the thread that called barEntry() or close() can call open().
virtual int32_t getActiveCount | ( | ) | const [virtual] |
Return the number of entered threads.
virtual bool isActiveThread | ( | ) | const [virtual] |
Determine if the current thread has entered and not exited.
This is useful for detecting re-entrancy.
virtual int32_t getCloseCount | ( | ) | const [virtual] |
Return the number of unmatched completed close/barEntry calls.
virtual Status getStatus | ( | ) | const [virtual] |
Return the current thread gate status.
virtual void setCloseCount | ( | int32_t | cClose | ) | [protected, virtual] |
Specify the number of unmatched completed close/barEntry calls.
The caller must have the gate closed/closing.
cClose | the number of unmatched completed close/barEntry calls. |
virtual Thread::View getClosingThread | ( | ) | const [protected, virtual] |
Return the thread that is closing the gate.
virtual void setClosingThread | ( | Thread::View | vThread | ) | [protected, virtual] |
Specify the thread id that is closing the gate.
The caller must be synchronized on the thread gate.
vThread | the thread id that is closing the gate. |
Update the current thread gate status, without changing the active count.
The caller must hold synchronization on the ThreadGate.
nStatus | the new status |
virtual int64_t doWait | ( | int64_t | cMillis | ) | [protected, virtual] |
Wait up to the specified number of milliseconds for notification.
Caller must be synchronized on this gate.
cMillis | the number of milliseconds to wait;; pass infinite for forever or immediate for no wait |