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
00035 #define _PSYNCPOINTACK
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();
00257
00264 void StartRead();
00265
00268 void EndRead();
00269
00285 void StartWrite();
00286
00298 void EndWrite();
00300
00301 protected:
00302 PSemaphore readerSemaphore;
00303 PMutex readerMutex;
00304 unsigned readerCount;
00305 PMutex starvationPreventer;
00306
00307 PSemaphore writerSemaphore;
00308 PMutex writerMutex;
00309 unsigned writerCount;
00310
00311 class Nest : public PObject
00312 {
00313 PCLASSINFO(Nest, PObject);
00314 Nest() { readerCount = writerCount = 0; }
00315 unsigned readerCount;
00316 unsigned writerCount;
00317 };
00318 PDictionary<POrdinalKey, Nest> nestedThreads;
00319 PMutex nestingMutex;
00320
00321 Nest * GetNest() const;
00322 Nest & StartNest();
00323 void EndNest();
00324 void InternalStartRead();
00325 void InternalEndRead();
00326 };
00327
00328
00346 class PReadWaitAndSignal {
00347 public:
00352 PReadWaitAndSignal(
00353 const PReadWriteMutex & rw,
00354 PBoolean start = PTrue
00355 );
00360 ~PReadWaitAndSignal();
00361
00362 protected:
00363 PReadWriteMutex & mutex;
00364 };
00365
00366
00384 class PWriteWaitAndSignal {
00385 public:
00390 PWriteWaitAndSignal(
00391 const PReadWriteMutex & rw,
00392 PBoolean start = PTrue
00393 );
00398 ~PWriteWaitAndSignal();
00399
00400 protected:
00401 PReadWriteMutex & mutex;
00402 };
00403
00404
00405