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
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #define _PSYNCPOINTACK
00081
00082 #ifdef P_USE_PRAGMA
00083 #pragma interface
00084 #endif
00085
00086 #include <ptlib/mutex.h>
00087 #include <ptlib/syncpoint.h>
00088
00110 class PSyncPointAck : public PSyncPoint
00111 {
00112 PCLASSINFO(PSyncPointAck, PSyncPoint);
00113
00114 public:
00126 virtual void Signal();
00127 void Signal(const PTimeInterval & waitTime);
00128
00134 void Acknowledge();
00135
00136 protected:
00137 PSyncPoint ack;
00138 };
00139
00140
00146 class PCondMutex : public PMutex
00147 {
00148 PCLASSINFO(PCondMutex, PMutex);
00149
00150 public:
00155 virtual void WaitCondition();
00156
00161 virtual void Signal();
00162
00166 virtual BOOL Condition() = 0;
00167
00172 virtual void OnWait();
00173
00174 protected:
00175 PSyncPoint syncPoint;
00176 };
00177
00178
00181 class PIntCondMutex : public PCondMutex
00182 {
00183 PCLASSINFO(PIntCondMutex, PCondMutex);
00184
00185 public:
00188
00189 enum Operation {
00191 LT,
00193 LE,
00195 EQ,
00197 GE,
00199 GT
00200 };
00201
00205 PIntCondMutex(
00206 int value = 0,
00207 int target = 0,
00208 Operation operation = LE
00209 );
00211
00217 void PrintOn(ostream & strm) const;
00219
00227 virtual BOOL Condition();
00228
00232 operator int() const { return value; }
00233
00241 PIntCondMutex & operator=(int newval);
00242
00250 PIntCondMutex & operator++();
00251
00259 PIntCondMutex & operator+=(int inc);
00260
00268 PIntCondMutex & operator--();
00269
00277 PIntCondMutex & operator-=(int dec);
00279
00280
00281 protected:
00282 int value, target;
00283 Operation operation;
00284 };
00285
00286
00294 class PReadWriteMutex : public PObject
00295 {
00296 PCLASSINFO(PReadWriteMutex, PObject);
00297 public:
00300 PReadWriteMutex();
00302
00309 void StartRead();
00310
00313 void EndRead();
00314
00330 void StartWrite();
00331
00343 void EndWrite();
00345
00346 protected:
00347 PSemaphore readerSemaphore;
00348 PMutex readerMutex;
00349 unsigned readerCount;
00350 PMutex starvationPreventer;
00351
00352 PSemaphore writerSemaphore;
00353 PMutex writerMutex;
00354 unsigned writerCount;
00355
00356 class Nest : public PObject
00357 {
00358 PCLASSINFO(Nest, PObject);
00359 Nest() { readerCount = writerCount = 0; }
00360 unsigned readerCount;
00361 unsigned writerCount;
00362 };
00363 PDictionary<POrdinalKey, Nest> nestedThreads;
00364 PMutex nestingMutex;
00365
00366 Nest * GetNest() const;
00367 Nest & StartNest();
00368 void EndNest();
00369 void InternalStartRead();
00370 void InternalEndRead();
00371 };
00372
00373
00391 class PReadWaitAndSignal {
00392 public:
00397 PReadWaitAndSignal(
00398 const PReadWriteMutex & rw,
00399 BOOL start = TRUE
00400 );
00405 ~PReadWaitAndSignal();
00406
00407 protected:
00408 PReadWriteMutex & mutex;
00409 };
00410
00411
00429 class PWriteWaitAndSignal {
00430 public:
00435 PWriteWaitAndSignal(
00436 const PReadWriteMutex & rw,
00437 BOOL start = TRUE
00438 );
00443 ~PWriteWaitAndSignal();
00444
00445 protected:
00446 PReadWriteMutex & mutex;
00447 };
00448
00449
00450