00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef LOW_OBJECTSYNCHRONIZER_H
00019 #define LOW_OBJECTSYNCHRONIZER_H
00020
00021
00022 #include "LOW_platformMisc.h"
00023 #include "LOW_platformMiscFactory.h"
00024 #include "LOW_helper_msglog.h"
00025 #include "LOW_thread_Factory.h"
00026 #include "LOW_thread_rwlock.h"
00027
00028
00029
00030 #ifdef DEBUG_LOCKING
00031 #include <string>
00032 #endif
00033
00034
00035 #include "LOW_objectSynchronizerMacros.h"
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 class LOW_objectSynchronizer {
00068
00069
00070 public:
00071
00072
00073
00074
00075
00076
00077
00078
00079 LOW_objectSynchronizer& operator= ( const LOW_objectSynchronizer &inRightSide);
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 class __synchronizeStaticRead {
00094 public:
00095
00096
00097
00098
00099
00100 #ifdef DEBUG_LOCKING
00101 inline __synchronizeStaticRead( LOW_thread_rwlock **inRwlockSingleton, std::string inFile, int inLine) :
00102 #else
00103 inline __synchronizeStaticRead( LOW_thread_rwlock **inRwlockSingleton) :
00104 #endif
00105 staticRwLock( inRwlockSingleton)
00106 {
00107 if ( *staticRwLock == 0 )
00108 *staticRwLock = LOW_thread_Factory::new_rwlock();
00109 #ifdef DEBUG_LOCKING
00110 try {
00111 (*staticRwLock)->tryLockRead();
00112 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00113 "__synchronizeStaticRead: obtained lock from file %s, line %d\n", inFile.c_str(), inLine);
00114 }
00115 catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00116 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00117 "__synchronizeStaticRead: failed to obtain lock from file %s, line %d\n", inFile.c_str(), inLine);
00118 (*staticRwLock)->lockRead();
00119 }
00120 #else
00121 (*staticRwLock)->lockRead();
00122 #endif
00123 };
00124
00125
00126
00127
00128 inline ~__synchronizeStaticRead()
00129 {
00130 (*staticRwLock)->unlock();
00131 };
00132
00133 private:
00134 LOW_thread_rwlock **staticRwLock;
00135 };
00136
00137
00138
00139
00140
00141
00142
00143
00144 class __synchronizeStaticWrite {
00145 public:
00146
00147
00148
00149
00150
00151 #ifdef DEBUG_LOCKING
00152 inline __synchronizeStaticWrite( LOW_thread_rwlock **inRwlockSingleton, LOW_platformMiscFactory::threadIdent_t &inWriteLockHolder, std::string inFile, int inLine) :
00153 #else
00154 inline __synchronizeStaticWrite( LOW_thread_rwlock **inRwlockSingleton, LOW_platformMiscFactory::threadIdent_t &inWriteLockHolder) :
00155 #endif
00156 staticRwLock( inRwlockSingleton),
00157 writeLockHolder(inWriteLockHolder)
00158 {
00159 if ( *staticRwLock == 0 )
00160 *staticRwLock = LOW_thread_Factory::new_rwlock();
00161 #ifdef DEBUG_LOCKING
00162 try {
00163 (*staticRwLock)->tryLockWrite();
00164 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00165 "__synchronizeStaticWrite: obtained lock from file %s, line %d\n", inFile.c_str(), inLine);
00166 }
00167 catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00168 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00169 "__synchronizeStaticWrite: failed to obtain lock from file %s, line %d\n", inFile.c_str(), inLine);
00170 (*staticRwLock)->lockWrite();
00171 }
00172 #else
00173 (*staticRwLock)->lockWrite();
00174 #endif
00175
00176
00177
00178 writeLockHolder = LOW_platformMisc::getThreadID();
00179 };
00180
00181
00182
00183
00184 inline ~__synchronizeStaticWrite()
00185 {
00186
00187
00188
00189 writeLockHolder = 0;
00190 (*staticRwLock)->unlock();
00191 };
00192
00193 private:
00194 LOW_thread_rwlock **staticRwLock;
00195 LOW_platformMiscFactory::threadIdent_t &writeLockHolder;
00196 };
00197
00198
00199
00200
00201
00202
00203
00204
00205 class __synchronizeStaticReadWeak {
00206 public:
00207
00208
00209
00210
00211
00212 #ifdef DEBUG_LOCKING
00213 inline __synchronizeStaticReadWeak( LOW_thread_rwlock **inRwlockSingleton, LOW_platformMiscFactory::threadIdent_t &inWriteLockHolder, std::string inFile, int inLine) :
00214 #else
00215 inline __synchronizeStaticReadWeak( LOW_thread_rwlock **inRwlockSingleton, LOW_platformMiscFactory::threadIdent_t &inWriteLockHolder) :
00216 #endif
00217 staticRwLock( inRwlockSingleton)
00218 {
00219 if ( *staticRwLock == 0 )
00220 *staticRwLock = LOW_thread_Factory::new_rwlock();
00221 wasObtainedWeakly = false;
00222 try {
00223 (*staticRwLock)->tryLockRead();
00224 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00225 "__synchronizeStaticReadWeak: obtained lock from file %s, line %d\n", inFile.c_str(), inLine);
00226 }
00227 catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00228 if ( LOW_platformMisc::getThreadID() == inWriteLockHolder )
00229 wasObtainedWeakly = true;
00230 else {
00231 #ifdef DEBUG_LOCKING
00232 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00233 "__synchronizeStaticReadWeak: failed to obtain lock from file %s, line %d\n", inFile.c_str(), inLine);
00234 #endif
00235 (*staticRwLock)->lockRead();
00236 }
00237 }
00238 };
00239
00240
00241
00242
00243 inline ~__synchronizeStaticReadWeak()
00244 {
00245 if ( ! wasObtainedWeakly )
00246 (*staticRwLock)->unlock();
00247 };
00248
00249 private:
00250 LOW_thread_rwlock **staticRwLock;
00251 bool wasObtainedWeakly;
00252 };
00253
00254
00255
00256
00257
00258
00259
00260
00261 class __synchronizeStaticWriteWeak {
00262 public:
00263
00264
00265
00266
00267
00268 #ifdef DEBUG_LOCKING
00269 inline __synchronizeStaticWriteWeak( LOW_thread_rwlock **inRwlockSingleton, LOW_platformMiscFactory::threadIdent_t &inWriteLockHolder, std::string inFile, int inLine) :
00270 #else
00271 inline __synchronizeStaticWriteWeak( LOW_thread_rwlock **inRwlockSingleton, LOW_platformMiscFactory::threadIdent_t &inWriteLockHolder) :
00272 #endif
00273 staticRwLock( inRwlockSingleton),
00274 writeLockHolder(inWriteLockHolder)
00275 {
00276 if ( *staticRwLock == 0 )
00277 *staticRwLock = LOW_thread_Factory::new_rwlock();
00278 wasObtainedWeakly = false;
00279 try {
00280 (*staticRwLock)->tryLockWrite();
00281
00282
00283
00284 writeLockHolder = LOW_platformMisc::getThreadID();
00285 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00286 "__synchronizeStaticWriteWeak: obtained lock from file %s, line %d\n", inFile.c_str(), inLine);
00287 }
00288 catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00289 if ( LOW_platformMisc::getThreadID() == writeLockHolder )
00290 wasObtainedWeakly = true;
00291 else {
00292 #ifdef DEBUG_LOCKING
00293 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00294 "__synchronizeStaticWriteWeak: failed to obtain lock from file %s, line %d\n", inFile.c_str(), inLine);
00295 #endif
00296 (*staticRwLock)->lockWrite();
00297 }
00298 }
00299 };
00300
00301
00302
00303
00304 inline ~__synchronizeStaticWriteWeak()
00305 {
00306 if ( ! wasObtainedWeakly ) {
00307
00308
00309
00310 writeLockHolder = 0;
00311 (*staticRwLock)->unlock();
00312 }
00313 };
00314
00315 private:
00316 LOW_thread_rwlock **staticRwLock;
00317 bool wasObtainedWeakly;
00318 LOW_platformMiscFactory::threadIdent_t &writeLockHolder;
00319 };
00320
00321
00322
00323
00324 protected:
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 class __synchronizeMethodRead {
00338 public:
00339
00340
00341
00342
00343
00344 #ifdef DEBUG_LOCKING
00345 inline __synchronizeMethodRead( const LOW_objectSynchronizer &inObjectSynchronizer, std::string inFile, int inLine) :
00346 #else
00347 inline __synchronizeMethodRead( const LOW_objectSynchronizer &inObjectSynchronizer) :
00348 #endif
00349 objectSynchronizer( inObjectSynchronizer)
00350 {
00351 #ifdef DEBUG_LOCKING
00352 try {
00353 objectSynchronizer.objectSyncRwlock->tryLockRead();
00354 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00355 "__synchronizeMethodRead: obtained read lock from file %s, line %d\n", inFile.c_str(), inLine);
00356 }
00357 catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00358 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00359 "__synchronizeMethodRead: failed to obtain read lock from file %s, line %d\n", inFile.c_str(), inLine);
00360 objectSynchronizer.objectSyncRwlock->lockRead();
00361 }
00362 #else
00363 objectSynchronizer.objectSyncRwlock->lockRead();
00364 #endif
00365 };
00366
00367
00368
00369
00370 inline ~__synchronizeMethodRead()
00371 {
00372 objectSynchronizer.objectSyncRwlock->unlock();
00373 };
00374
00375 private:
00376 const LOW_objectSynchronizer &objectSynchronizer;
00377 };
00378
00379
00380
00381
00382
00383
00384
00385
00386 class __synchronizeMethodWrite {
00387 public:
00388
00389
00390
00391
00392
00393 #ifdef DEBUG_LOCKING
00394 inline __synchronizeMethodWrite( LOW_objectSynchronizer &inObjectSynchronizer, std::string inFile, int inLine) :
00395 #else
00396 inline __synchronizeMethodWrite( LOW_objectSynchronizer &inObjectSynchronizer) :
00397 #endif
00398 objectSynchronizer( inObjectSynchronizer)
00399 {
00400 #ifdef DEBUG_LOCKING
00401 try {
00402 objectSynchronizer.objectSyncRwlock->tryLockWrite();
00403 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00404 "__synchronizeMethodWrite: obtained write lock from file %s, line %d\n", inFile.c_str(), inLine);
00405 }
00406 catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00407 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00408 "__synchronizeMethodWrite: failed to obtain write lock from file %s, line %d\n", inFile.c_str(), inLine);
00409 objectSynchronizer.objectSyncRwlock->lockWrite();
00410 }
00411 #else
00412 objectSynchronizer.objectSyncRwlock->lockWrite();
00413 #endif
00414
00415
00416
00417 objectSynchronizer.writeLockHolder = LOW_platformMisc::getThreadID();
00418 };
00419
00420
00421
00422
00423 inline ~__synchronizeMethodWrite()
00424 {
00425
00426
00427
00428 objectSynchronizer.writeLockHolder = 0;
00429 objectSynchronizer.objectSyncRwlock->unlock();
00430 };
00431
00432 private:
00433 LOW_objectSynchronizer &objectSynchronizer;
00434 };
00435
00436
00437
00438
00439
00440
00441
00442
00443 class __synchronizeMethodReadWeak {
00444 public:
00445
00446
00447
00448
00449
00450 #ifdef DEBUG_LOCKING
00451 inline __synchronizeMethodReadWeak( const LOW_objectSynchronizer &inObjectSynchronizer, std::string inFile, int inLine) :
00452 #else
00453 inline __synchronizeMethodReadWeak( const LOW_objectSynchronizer &inObjectSynchronizer) :
00454 #endif
00455 objectSynchronizer( inObjectSynchronizer)
00456 {
00457 wasObtainedWeakly = false;
00458 try {
00459 objectSynchronizer.objectSyncRwlock->tryLockRead();
00460 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00461 "__synchronizeMethodReadWeak: obtain weak read lock from file %s, line %d\n", inFile.c_str(), inLine);
00462 }
00463 catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00464 if ( LOW_platformMisc::getThreadID() == objectSynchronizer.writeLockHolder )
00465 wasObtainedWeakly = true;
00466 else {
00467 #ifdef DEBUG_LOCKING
00468 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00469 "__synchronizeMethodReadWeak: failed to obtain lock from file %s, line %d\n", inFile.c_str(), inLine);
00470 #endif
00471 objectSynchronizer.objectSyncRwlock->lockRead();
00472 }
00473 }
00474 };
00475
00476
00477
00478
00479 inline ~__synchronizeMethodReadWeak()
00480 {
00481 if ( ! wasObtainedWeakly )
00482 objectSynchronizer.objectSyncRwlock->unlock();
00483 };
00484
00485 private:
00486 const LOW_objectSynchronizer &objectSynchronizer;
00487 bool wasObtainedWeakly;
00488 };
00489
00490
00491
00492
00493
00494
00495
00496
00497 class __synchronizeMethodWriteWeak {
00498 public:
00499
00500
00501
00502
00503
00504 #ifdef DEBUG_LOCKING
00505 inline __synchronizeMethodWriteWeak( LOW_objectSynchronizer &inObjectSynchronizer, std::string inFile, int inLine) :
00506 #else
00507 inline __synchronizeMethodWriteWeak( LOW_objectSynchronizer &inObjectSynchronizer) :
00508 #endif
00509 objectSynchronizer( inObjectSynchronizer)
00510 {
00511 wasObtainedWeakly = false;
00512 try {
00513 objectSynchronizer.objectSyncRwlock->tryLockWrite();
00514 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00515 "__synchronizeMethodWriteWeak: obtained weak write lock from file %s, line %d\n", inFile.c_str(), inLine);
00516
00517
00518
00519 objectSynchronizer.writeLockHolder = LOW_platformMisc::getThreadID();
00520 }
00521 catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00522 if ( LOW_platformMisc::getThreadID() == objectSynchronizer.writeLockHolder )
00523 wasObtainedWeakly = true;
00524 else {
00525 #ifdef DEBUG_LOCKING
00526 LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00527 "__synchronizeMethodWriteWeak: failed to obtain lock from file %s, line %d\n", inFile.c_str(), inLine);
00528 #endif
00529 objectSynchronizer.objectSyncRwlock->lockWrite();
00530 }
00531 }
00532 };
00533
00534
00535
00536
00537 inline ~__synchronizeMethodWriteWeak()
00538 {
00539 if ( ! wasObtainedWeakly ) {
00540
00541
00542
00543 objectSynchronizer.writeLockHolder = 0;
00544 objectSynchronizer.objectSyncRwlock->unlock();
00545 }
00546 };
00547
00548 private:
00549 LOW_objectSynchronizer &objectSynchronizer;
00550 bool wasObtainedWeakly;
00551 };
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 LOW_objectSynchronizer();
00563
00564
00565
00566
00567 LOW_objectSynchronizer( const LOW_objectSynchronizer &inObjectSynchronizer);
00568
00569
00570
00571
00572 virtual ~LOW_objectSynchronizer();
00573
00574
00575
00576 private:
00577
00578
00579
00580
00581
00582
00583 friend class __synchronizeMethodRead;
00584 friend class __synchronizeMethodWrite;
00585 friend class __synchronizeMethodReadWeak;
00586 friend class __synchronizeMethodWriteWeak;
00587
00588
00589
00590
00591
00592
00593
00594 LOW_thread_rwlock *objectSyncRwlock;
00595 LOW_platformMiscFactory::threadIdent_t writeLockHolder;
00596 };
00597
00598 #endif