diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/apps/dcmconv.cc dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/apps/dcmconv.cc --- dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/apps/dcmconv.cc 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/apps/dcmconv.cc 2018-01-19 09:58:04.601534500 +0100 @@ -70,7 +70,7 @@ } else { tagKey = dicent->getKey(); } - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); return tagKey; } else /* tag name has format "gggg,eeee" */ { diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/apps/dcmdump.cc dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/apps/dcmdump.cc --- dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/apps/dcmdump.cc 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/apps/dcmdump.cc 2018-01-23 15:12:19.947386700 +0100 @@ -96,7 +96,7 @@ } else { tagKey = dicent->getKey(); } - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); return tagKey; } else /* tag name has format "gggg,eeee" */ { @@ -120,13 +120,13 @@ const DcmDictEntry *dicent = globalDataDict.findEntry(tagName); if (dicent == NULL) { OFLOG_WARN(dcmdumpLogger, "unrecognized tag name: '" << tagName << "'"); - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); return OFFalse; } else { /* note for later */ printTagKeys[printTagCount] = new DcmTagKey(dicent->getKey()); } - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); } else { /* tag name has format xxxx,xxxx */ /* do not lookup in dictionary, tag could be private */ diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/apps/mdfdsman.cc dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/apps/mdfdsman.cc --- dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/apps/mdfdsman.cc 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/apps/mdfdsman.cc 2018-01-23 16:08:21.239644400 +0100 @@ -105,7 +105,7 @@ { key = dicent->getKey(); } - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); return key; } @@ -724,7 +724,7 @@ const DcmDataDictionary& globalDataDict = dcmDataDict.rdlock(); const DcmDictEntry *dicent = globalDataDict.findEntry(search_key,NULL); // successfull lookup in dictionary -> translate to tag and return - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); if (dicent) return OFTrue; else return OFFalse; diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/include/dcmtk/dcmdata/dcdict.h dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/include/dcmtk/dcmdata/dcdict.h --- dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/include/dcmtk/dcmdata/dcdict.h 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/include/dcmtk/dcmdata/dcdict.h 2018-01-23 15:12:37.143696900 +0100 @@ -238,7 +238,8 @@ /** unlocks the read or write lock which must have been acquired previously. */ - void unlock(); + void rdunlock(); + void wrunlock(); /** checks if a data dictionary has been loaded. This method acquires and * releases a read lock. It must not be called with another lock on the diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/libsrc/dcdict.cc dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/libsrc/dcdict.cc --- dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/libsrc/dcdict.cc 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/libsrc/dcdict.cc 2018-01-23 15:13:09.880569700 +0100 @@ -815,7 +815,7 @@ if (!dataDict) dataDict = new DcmDataDictionary(OFTrue /*loadBuiltin*/, loadExternal); #ifdef WITH_THREADS - dataDictLock.unlock(); + dataDictLock.wrunlock(); #endif } @@ -828,7 +828,7 @@ { /* dataDictLock must not be locked during createDataDict() */ #ifdef WITH_THREADS - dataDictLock.unlock(); + dataDictLock.rdunlock(); #endif createDataDict(); #ifdef WITH_THREADS @@ -847,7 +847,7 @@ { /* dataDictLock must not be locked during createDataDict() */ #ifdef WITH_THREADS - dataDictLock.unlock(); + dataDictLock.wrunlock(); #endif createDataDict(); #ifdef WITH_THREADS @@ -857,22 +857,36 @@ return *dataDict; } -void GlobalDcmDataDictionary::unlock() +// void GlobalDcmDataDictionary::unlock() +// { +// #ifdef WITH_THREADS +// dataDictLock.unlock(); +// #endif +// } + +void GlobalDcmDataDictionary::rdunlock() +{ +#ifdef WITH_THREADS + dataDictLock.rdunlock(); +#endif +} + +void GlobalDcmDataDictionary::wrunlock() { #ifdef WITH_THREADS - dataDictLock.unlock(); + dataDictLock.wrunlock(); #endif } OFBool GlobalDcmDataDictionary::isDictionaryLoaded() { OFBool result = rdlock().isDictionaryLoaded(); - unlock(); + rdunlock(); return result; } void GlobalDcmDataDictionary::clear() { wrlock().clear(); - unlock(); + wrunlock(); } diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/libsrc/dctag.cc dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/libsrc/dctag.cc --- dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/libsrc/dctag.cc 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/libsrc/dctag.cc 2018-01-23 15:13:32.029332900 +0100 @@ -129,7 +129,7 @@ vr = dictRef->getVR(); errorFlag = EC_Normal; } - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); } // ******************************** @@ -162,7 +162,7 @@ if (newTagName == NULL) newTagName = DcmTag_ERROR_TagName; updateTagName(newTagName); - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); if (tagName) return tagName; @@ -222,7 +222,7 @@ } else result = EC_TagNotFound; - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); } } return result; diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/tests/tnewdcme.cc dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/tests/tnewdcme.cc --- dcmtk-for-dcmjp2k-3.6.2-unix/dcmdata/tests/tnewdcme.cc 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmdata/tests/tnewdcme.cc 2018-01-23 15:13:38.470173500 +0100 @@ -43,7 +43,7 @@ { DcmDataDictionary &dict = dcmDataDict.wrlock(); dict.addEntry(new DcmDictEntry(PRIVATE_ELEMENT_STRINGELEM, EVR_LO, "StringAttributeForTesting", 1, 1, "private", OFTrue, PRIVATE_CREATOR_NAME)); - dcmDataDict.unlock(); + dcmDataDict.wrunlock(); } diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/dcmiod/libsrc/iodutil.cc dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmiod/libsrc/iodutil.cc --- dcmtk-for-dcmjp2k-3.6.2-unix/dcmiod/libsrc/iodutil.cc 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmiod/libsrc/iodutil.cc 2018-01-23 15:13:46.391194600 +0100 @@ -556,7 +556,7 @@ { vr = dictRef->getVR(); } - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); if (vr.getEVR() == EVR_SQ) return OFTrue; return OFFalse; diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/dcmnet/apps/movescu.cc dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmnet/apps/movescu.cc --- dcmtk-for-dcmjp2k-3.6.2-unix/dcmnet/apps/movescu.cc 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmnet/apps/movescu.cc 2018-01-23 15:14:04.574071000 +0100 @@ -168,7 +168,7 @@ DcmTagKey key(0xffff,0xffff); const DcmDataDictionary& globalDataDict = dcmDataDict.rdlock(); const DcmDictEntry *dicent = globalDataDict.findEntry(dicName.c_str()); - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); if (dicent!=NULL) { // found dictionary name, copy group and element number key = dicent->getKey(); diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/dcmpstat/apps/dcmpschk.cc dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmpstat/apps/dcmpschk.cc --- dcmtk-for-dcmjp2k-3.6.2-unix/dcmpstat/apps/dcmpschk.cc 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmpstat/apps/dcmpschk.cc 2018-01-23 15:15:19.179049600 +0100 @@ -245,7 +245,7 @@ if (dictRef && (t.getEVR() == EVR_up) && (t.getEVR() == dictRef->getEVR())) result = OFTrue; - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); return result; } @@ -557,7 +557,7 @@ } //end of if (isaStringVR(vr)) } - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); return 0; } diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/dcmsign/apps/dcmsign.cc dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmsign/apps/dcmsign.cc --- dcmtk-for-dcmjp2k-3.6.2-unix/dcmsign/apps/dcmsign.cc 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/dcmsign/apps/dcmsign.cc 2018-01-23 15:15:31.011522400 +0100 @@ -100,7 +100,7 @@ { if (EC_Normal == tagList.putTagVal(dicent->getKey(), tagList.getVM())) result = OFTrue; } - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); } else { if (EC_Normal == tagList.putTagVal(DcmTagKey(group,elem), tagList.getVM())) result = OFTrue; } @@ -158,11 +158,11 @@ if (dicent) { key = dicent->getKey(); - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); pos = lpos; return 1; // tag key; } - dcmDataDict.unlock(); + dcmDataDict.rdunlock(); OFLOG_ERROR(dcmsignLogger, "attribute name '" << aString.c_str() << "' unknown."); return 0; // parse error } diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/ofstd/include/dcmtk/ofstd/ofthread.h dcmtk-for-dcmjp2k-3.6.2-unix.patched/ofstd/include/dcmtk/ofstd/ofthread.h --- dcmtk-for-dcmjp2k-3.6.2-unix/ofstd/include/dcmtk/ofstd/ofthread.h 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/ofstd/include/dcmtk/ofstd/ofthread.h 2018-01-23 15:16:11.185530700 +0100 @@ -353,6 +353,8 @@ * @return 0 upon success, an error code otherwise. */ int lock(); + int rdlock(); + int wrlock(); /** tries to lock the mutex object. If the mutex is already locked, * returns OFMutex::busy. @@ -360,6 +362,8 @@ * an error code otherwise. */ int trylock(); + int tryrdlock(); + int trywrlock(); /** releases the lock on the mutex object. The mutex must be locked and * the calling thread must be the owner of the lock, otherwise the @@ -369,6 +373,8 @@ * @return 0 upon success, an error code otherwise. */ int unlock(); + int rdunlock(); + int wrunlock(); /** converts any of the error codes returned by the methods of this class * into a textual description, which is written into the string object. @@ -459,6 +465,8 @@ * @return 0 upon success, an error code otherwise. */ int unlock(); + int rdunlock(); + int wrunlock(); /** converts any of the error codes returned by the methods of this class * into a textual description, which is written into the string object. diff -Nur dcmtk-for-dcmjp2k-3.6.2-unix/ofstd/libsrc/ofthread.cc dcmtk-for-dcmjp2k-3.6.2-unix.patched/ofstd/libsrc/ofthread.cc --- dcmtk-for-dcmjp2k-3.6.2-unix/ofstd/libsrc/ofthread.cc 2017-07-14 17:41:11.000000000 +0200 +++ dcmtk-for-dcmjp2k-3.6.2-unix.patched/ofstd/libsrc/ofthread.cc 2018-01-23 15:17:43.191052100 +0100 @@ -595,9 +595,12 @@ #ifdef USE_WIN32_CREATE_MUTEX theMutex = OFstatic_cast(void *, CreateMutex(NULL, FALSE, NULL)); #else - CRITICAL_SECTION *critSec = new CRITICAL_SECTION; - InitializeCriticalSection(critSec); - theMutex = OFstatic_cast(void *, critSec); + //CRITICAL_SECTION *critSec = new CRITICAL_SECTION; + //InitializeCriticalSection(critSec); + //theMutex = OFstatic_cast(void *, critSec); + SRWLOCK* srwLock = new SRWLOCK; + InitializeSRWLock(srwLock); + theMutex = OFstatic_cast(void*, srwLock); #endif #elif defined(POSIX_INTERFACE) pthread_mutex_t *mtx = new pthread_mutex_t; @@ -624,9 +627,11 @@ #ifdef USE_WIN32_CREATE_MUTEX CloseHandle(OFthread_cast(HANDLE, theMutex)); #else - CRITICAL_SECTION *critSec = OFthread_cast(CRITICAL_SECTION *, theMutex); - DeleteCriticalSection(critSec); - delete critSec; +// CRITICAL_SECTION *critSec = OFthread_cast(CRITICAL_SECTION *, theMutex); +// DeleteCriticalSection(critSec); +// delete critSec; + SRWLOCK* srwLock = OFthread_cast(SRWLOCK*, theMutex); // no explicit destruction is necessary + delete srwLock; #endif #elif defined(POSIX_INTERFACE) if (theMutex) pthread_mutex_destroy(OFthread_cast(pthread_mutex_t *, theMutex)); @@ -657,7 +662,48 @@ if (WaitForSingleObject(OFthread_cast(HANDLE, theMutex), INFINITE) == WAIT_OBJECT_0) return 0; else return OFstatic_cast(int, GetLastError()); #else - EnterCriticalSection(OFthread_cast(CRITICAL_SECTION *, theMutex)); + //EnterCriticalSection(OFthread_cast(CRITICAL_SECTION *, theMutex)); + AcquireSRWLockExclusive(OFthread_cast(SRWLOCK*, theMutex)); + return 0; +#endif +#elif defined(POSIX_INTERFACE) + if (theMutex) return pthread_mutex_lock(OFthread_cast(pthread_mutex_t *, theMutex)); else return EINVAL; +#elif defined(SOLARIS_INTERFACE) + if (theMutex) return mutex_lock(OFthread_cast(mutex_t *, theMutex)); else return EINVAL; +#else + return -1; +#endif +} + +int OFMutex::rdlock() +{ +#ifdef WINDOWS_INTERFACE +#ifdef USE_WIN32_CREATE_MUTEX + if (WaitForSingleObject(OFthread_cast(HANDLE, theMutex), INFINITE) == WAIT_OBJECT_0) return 0; + else return OFstatic_cast(int, GetLastError()); +#else + //EnterCriticalSection(OFthread_cast(CRITICAL_SECTION *, theMutex)); + AcquireSRWLockShared(OFthread_cast(SRWLOCK*, theMutex)); + return 0; +#endif +#elif defined(POSIX_INTERFACE) + if (theMutex) return pthread_mutex_lock(OFthread_cast(pthread_mutex_t *, theMutex)); else return EINVAL; +#elif defined(SOLARIS_INTERFACE) + if (theMutex) return mutex_lock(OFthread_cast(mutex_t *, theMutex)); else return EINVAL; +#else + return -1; +#endif +} + +int OFMutex::wrlock() +{ +#ifdef WINDOWS_INTERFACE +#ifdef USE_WIN32_CREATE_MUTEX + if (WaitForSingleObject(OFthread_cast(HANDLE, theMutex), INFINITE) == WAIT_OBJECT_0) return 0; + else return OFstatic_cast(int, GetLastError()); +#else + //EnterCriticalSection(OFthread_cast(CRITICAL_SECTION *, theMutex)); + AcquireSRWLockExclusive(OFthread_cast(SRWLOCK*, theMutex)); return 0; #endif #elif defined(POSIX_INTERFACE) @@ -678,7 +724,52 @@ else if (result == WAIT_TIMEOUT) return OFMutex::busy; else return OFstatic_cast(int, GetLastError()); #else - if (TryEnterCriticalSection(OFthread_cast(CRITICAL_SECTION *, theMutex))) return 0; + //if (TryEnterCriticalSection(OFthread_cast(CRITICAL_SECTION *, theMutex))) return 0; + if (TryAcquireSRWLockExclusive(OFthread_cast(SRWLOCK*, theMutex))) return 0; + else return OFMutex::busy; +#endif +#elif defined(POSIX_INTERFACE) + if (theMutex) return pthread_mutex_trylock(OFthread_cast(pthread_mutex_t *, theMutex)); else return EINVAL; // may return EBUSY. +#elif defined(SOLARIS_INTERFACE) + if (theMutex) return mutex_trylock(OFthread_cast(mutex_t *, theMutex)); else return EINVAL; // may return EBUSY. +#else + return -1; +#endif +} + +int OFMutex::tryrdlock() +{ +#ifdef WINDOWS_INTERFACE +#ifdef USE_WIN32_CREATE_MUTEX + DWORD result = WaitForSingleObject(OFthread_cast(HANDLE, theMutex), 0); + if (result == WAIT_OBJECT_0) return 0; + else if (result == WAIT_TIMEOUT) return OFMutex::busy; + else return OFstatic_cast(int, GetLastError()); +#else + //if (TryEnterCriticalSection(OFthread_cast(CRITICAL_SECTION *, theMutex))) return 0; + if (TryAcquireSRWLockShared(OFthread_cast(SRWLOCK*, theMutex))) return 0; + else return OFMutex::busy; +#endif +#elif defined(POSIX_INTERFACE) + if (theMutex) return pthread_mutex_trylock(OFthread_cast(pthread_mutex_t *, theMutex)); else return EINVAL; // may return EBUSY. +#elif defined(SOLARIS_INTERFACE) + if (theMutex) return mutex_trylock(OFthread_cast(mutex_t *, theMutex)); else return EINVAL; // may return EBUSY. +#else + return -1; +#endif +} + +int OFMutex::trywrlock() +{ +#ifdef WINDOWS_INTERFACE +#ifdef USE_WIN32_CREATE_MUTEX + DWORD result = WaitForSingleObject(OFthread_cast(HANDLE, theMutex), 0); + if (result == WAIT_OBJECT_0) return 0; + else if (result == WAIT_TIMEOUT) return OFMutex::busy; + else return OFstatic_cast(int, GetLastError()); +#else + //if (TryEnterCriticalSection(OFthread_cast(CRITICAL_SECTION *, theMutex))) return 0; + if (TryAcquireSRWLockExclusive(OFthread_cast(SRWLOCK*, theMutex))) return 0; else return OFMutex::busy; #endif #elif defined(POSIX_INTERFACE) @@ -696,7 +787,46 @@ #ifdef USE_WIN32_CREATE_MUTEX if (ReleaseMutex(OFthread_cast(HANDLE, theMutex))) return 0; else return OFstatic_cast(int, GetLastError()); #else - LeaveCriticalSection(OFthread_cast(CRITICAL_SECTION *, theMutex)); + //LeaveCriticalSection(OFthread_cast(CRITICAL_SECTION *, theMutex)); + ReleaseSRWLockExclusive(OFthread_cast(SRWLOCK*, theMutex)); + return 0; +#endif +#elif defined(POSIX_INTERFACE) + if (theMutex) return pthread_mutex_unlock(OFthread_cast(pthread_mutex_t *, theMutex)); else return EINVAL; +#elif defined(SOLARIS_INTERFACE) + if (theMutex) return mutex_unlock(OFthread_cast(mutex_t *, theMutex)); else return EINVAL; +#else + return -1; +#endif +} + +int OFMutex::rdunlock() +{ +#ifdef WINDOWS_INTERFACE +#ifdef USE_WIN32_CREATE_MUTEX + if (ReleaseMutex(OFthread_cast(HANDLE, theMutex))) return 0; else return OFstatic_cast(int, GetLastError()); +#else + //LeaveCriticalSection(OFthread_cast(CRITICAL_SECTION *, theMutex)); + ReleaseSRWLockShared(OFthread_cast(SRWLOCK*, theMutex)); + return 0; +#endif +#elif defined(POSIX_INTERFACE) + if (theMutex) return pthread_mutex_unlock(OFthread_cast(pthread_mutex_t *, theMutex)); else return EINVAL; +#elif defined(SOLARIS_INTERFACE) + if (theMutex) return mutex_unlock(OFthread_cast(mutex_t *, theMutex)); else return EINVAL; +#else + return -1; +#endif +} + +int OFMutex::wrunlock() +{ +#ifdef WINDOWS_INTERFACE +#ifdef USE_WIN32_CREATE_MUTEX + if (ReleaseMutex(OFthread_cast(HANDLE, theMutex))) return 0; else return OFstatic_cast(int, GetLastError()); +#else + //LeaveCriticalSection(OFthread_cast(CRITICAL_SECTION *, theMutex)); + ReleaseSRWLockExclusive(OFthread_cast(SRWLOCK*, theMutex)); return 0; #endif #elif defined(POSIX_INTERFACE) @@ -822,28 +952,7 @@ if (theLock) { OFReadWriteLockHelper *rwl = OFthread_cast(OFReadWriteLockHelper *, theLock); - int result =0; - while (1) - { - if (0 != (result = rwl->accessMutex.lock())) return result; // lock mutex - if (rwl->numReaders >= 0) // we can grant the read lock - { - if (rwl->numReaders == 0) - { - if (0 != (result = rwl->usageSemaphore.wait())) - { - rwl->accessMutex.unlock(); - return result; - } - } - (rwl->numReaders)++; - return rwl->accessMutex.unlock(); - } - // we cannot grant the read lock, block thread. - if (0 != (result = rwl->accessMutex.unlock())) return result; - if (0 != (result = rwl->usageSemaphore.wait())) return result; - if (0 != (result = rwl->usageSemaphore.post())) return result; - } + return rwl->accessMutex.rdlock(); } else return EINVAL; #elif defined(POSIX_INTERFACE) if (theLock) return pthread_rwlock_rdlock(OFthread_cast(pthread_rwlock_t *, theLock)); else return EINVAL; @@ -860,26 +969,7 @@ if (theLock) { OFReadWriteLockHelper *rwl = OFthread_cast(OFReadWriteLockHelper *, theLock); - int result =0; - while (1) - { - if (0 != (result = rwl->accessMutex.lock())) return result; // lock mutex - if (rwl->numReaders == 0) // we can grant the write lock - { - if (0 != (result = rwl->usageSemaphore.wait())) - { - rwl->accessMutex.unlock(); - return result; - } - rwl->numReaders = -1; - return rwl->accessMutex.unlock(); - } - - // we cannot grant the write lock, block thread. - if (0 != (result = rwl->accessMutex.unlock())) return result; - if (0 != (result = rwl->usageSemaphore.wait())) return result; - if (0 != (result = rwl->usageSemaphore.post())) return result; - } + return rwl->accessMutex.wrlock(); } else return EINVAL; #elif defined(POSIX_INTERFACE) if (theLock) return pthread_rwlock_wrlock(OFthread_cast(pthread_rwlock_t *, theLock)); else return EINVAL; @@ -897,23 +987,7 @@ if (theLock) { OFReadWriteLockHelper *rwl = OFthread_cast(OFReadWriteLockHelper *, theLock); - int result =0; - if (0 != (result = rwl->accessMutex.lock())) return result; // lock mutex - if (rwl->numReaders >= 0) // we can grant the read lock - { - if (rwl->numReaders == 0) - { - if (0 != (result = rwl->usageSemaphore.wait())) - { - rwl->accessMutex.unlock(); - return result; - } - } - (rwl->numReaders)++; - return rwl->accessMutex.unlock(); - } - result = rwl->accessMutex.unlock(); - if (result) return result; else return OFReadWriteLock::busy; + return rwl->accessMutex.tryrdlock(); } else return EINVAL; #elif defined(POSIX_INTERFACE) if (theLock) return pthread_rwlock_tryrdlock(OFthread_cast(pthread_rwlock_t *, theLock)); else return EINVAL; // may return EBUSY. @@ -930,20 +1004,7 @@ if (theLock) { OFReadWriteLockHelper *rwl = OFthread_cast(OFReadWriteLockHelper *, theLock); - int result =0; - if (0 != (result = rwl->accessMutex.lock())) return result; // lock mutex - if (rwl->numReaders == 0) // we can grant the write lock - { - if (0 != (result = rwl->usageSemaphore.wait())) - { - rwl->accessMutex.unlock(); - return result; - } - rwl->numReaders = -1; - return rwl->accessMutex.unlock(); - } - result = rwl->accessMutex.unlock(); - if (result) return result; else return OFReadWriteLock::busy; + return rwl->accessMutex.trywrlock(); } else return EINVAL; #elif defined(POSIX_INTERFACE) if (theLock) return pthread_rwlock_trywrlock(OFthread_cast(pthread_rwlock_t *, theLock)); else return EINVAL; // may return EBUSY. @@ -961,18 +1022,44 @@ if (theLock) { OFReadWriteLockHelper *rwl = OFthread_cast(OFReadWriteLockHelper *, theLock); - int result =0; - if (0 != (result = rwl->accessMutex.lock())) return result; // lock mutex - if (rwl->numReaders == -1) rwl->numReaders = 0; else (rwl->numReaders)--; - if ((rwl->numReaders == 0) && (0 != (result = rwl->usageSemaphore.post()))) - { - rwl->accessMutex.unlock(); - return result; - } return rwl->accessMutex.unlock(); } else return EINVAL; #elif defined(POSIX_INTERFACE) if (theLock) return pthread_rwlock_unlock(OFthread_cast(pthread_rwlock_t *, theLock)); else return EINVAL; +#elif defined(SOLARIS_INTERFACE) + if (theLock) return rw_unlock(OFthread_cast(rwlock_t *, theLock)); else return EINVAL; +#else + return -1; +#endif +} + +int OFReadWriteLock::rdunlock() +{ +#if defined(WINDOWS_INTERFACE) || defined(POSIX_INTERFACE_WITHOUT_RWLOCK) + if (theLock) + { + OFReadWriteLockHelper *rwl = OFthread_cast(OFReadWriteLockHelper *, theLock); + return rwl->accessMutex.rdunlock(); + } else return EINVAL; +#elif defined(POSIX_INTERFACE) + if (theLock) return pthread_rwlock_unlock(OFthread_cast(pthread_rwlock_t *, theLock)); else return EINVAL; +#elif defined(SOLARIS_INTERFACE) + if (theLock) return rw_unlock(OFthread_cast(rwlock_t *, theLock)); else return EINVAL; +#else + return -1; +#endif +} + +int OFReadWriteLock::wrunlock() +{ +#if defined(WINDOWS_INTERFACE) || defined(POSIX_INTERFACE_WITHOUT_RWLOCK) + if (theLock) + { + OFReadWriteLockHelper *rwl = OFthread_cast(OFReadWriteLockHelper *, theLock); + return rwl->accessMutex.wrunlock(); + } else return EINVAL; +#elif defined(POSIX_INTERFACE) + if (theLock) return pthread_rwlock_unlock(OFthread_cast(pthread_rwlock_t *, theLock)); else return EINVAL; #elif defined(SOLARIS_INTERFACE) if (theLock) return rw_unlock(OFthread_cast(rwlock_t *, theLock)); else return EINVAL; #else