00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef PTLIB_SYNCTHRD_H
00035 #define PTLIB_SYNCTHRD_H
00036
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040
00041 #include <ptlib/mutex.h>
00042 #include <ptlib/syncpoint.h>
00043
00065 class PSyncPointAck : public PSyncPoint
00066 {
00067 PCLASSINFO(PSyncPointAck, PSyncPoint);
00068
00069 public:
00081 virtual void Signal();
00082 void Signal(const PTimeInterval & waitTime);
00083
00089 void Acknowledge();
00090
00091 protected:
00092 PSyncPoint ack;
00093 };
00094
00095
00101 class PCondMutex : public PMutex
00102 {
00103 PCLASSINFO(PCondMutex, PMutex);
00104
00105 public:
00110 virtual void WaitCondition();
00111
00116 virtual void Signal();
00117
00121 virtual PBoolean Condition() = 0;
00122
00127 virtual void OnWait();
00128
00129 protected:
00130 PSyncPoint syncPoint;
00131 };
00132
00133
00136 class PIntCondMutex : public PCondMutex
00137 {
00138 PCLASSINFO(PIntCondMutex, PCondMutex);
00139
00140 public:
00143
00144 enum Operation {
00146 LT,
00148 LE,
00150 EQ,
00152 GE,
00154 GT
00155 };
00156
00160 PIntCondMutex(
00161 int value = 0,
00162 int target = 0,
00163 Operation operation = LE
00164 );
00166
00172 void PrintOn(ostream & strm) const;
00174
00182 virtual PBoolean Condition();
00183
00187 operator int() const { return value; }
00188
00196 PIntCondMutex & operator=(int newval);
00197
00205 PIntCondMutex & operator++();
00206
00214 PIntCondMutex & operator+=(int inc);
00215
00223 PIntCondMutex & operator--();
00224
00232 PIntCondMutex & operator-=(int dec);
00234
00235
00236 protected:
00237 int value, target;
00238 Operation operation;
00239 };
00240
00241
00249 class PReadWriteMutex : public PObject
00250 {
00251 PCLASSINFO(PReadWriteMutex, PObject);
00252 public:
00255 PReadWriteMutex();
00256 ~PReadWriteMutex();
00258
00265 void StartRead();
00266
00269 void EndRead();
00270
00286 void StartWrite();
00287
00299 void EndWrite();
00301
00302 protected:
00303 PSemaphore readerSemaphore;
00304 PMutex readerMutex;
00305 unsigned readerCount;
00306 PMutex starvationPreventer;
00307
00308 PSemaphore writerSemaphore;
00309 PMutex writerMutex;
00310 unsigned writerCount;
00311
00312 class Nest : public PObject
00313 {
00314 PCLASSINFO(Nest, PObject);
00315 Nest() { readerCount = writerCount = 0; }
00316 unsigned readerCount;
00317 unsigned writerCount;
00318 };
00319 PDictionary<POrdinalKey, Nest> nestedThreads;
00320 PMutex nestingMutex;
00321
00322 Nest * GetNest() const;
00323 Nest & StartNest();
00324 void EndNest();
00325 void InternalStartRead();
00326 void InternalEndRead();
00327 };
00328
00329
00347 class PReadWaitAndSignal {
00348 public:
00353 PReadWaitAndSignal(
00354 const PReadWriteMutex & rw,
00355 PBoolean start = PTrue
00356 );
00361 ~PReadWaitAndSignal();
00362
00363 protected:
00364 PReadWriteMutex & mutex;
00365 };
00366
00367
00385 class PWriteWaitAndSignal {
00386 public:
00391 PWriteWaitAndSignal(
00392 const PReadWriteMutex & rw,
00393 PBoolean start = PTrue
00394 );
00399 ~PWriteWaitAndSignal();
00400
00401 protected:
00402 PReadWriteMutex & mutex;
00403 };
00404
00405
00406 #endif // PTLIB_SYNCTHRD_H
00407
00408
00409