RWLock_WIN32.cpp
Go to the documentation of this file.
00001 //
00002 // RWLock_WIN32.cpp
00003 //
00004 // $Id: //poco/1.3/Foundation/src/RWLock_WIN32.cpp#3 $
00005 //
00006 // Library: Foundation
00007 // Package: Threading
00008 // Module:  RWLock
00009 //
00010 // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
00011 // and Contributors.
00012 //
00013 // Permission is hereby granted, free of charge, to any person or organization
00014 // obtaining a copy of the software and accompanying documentation covered by
00015 // this license (the "Software") to use, reproduce, display, distribute,
00016 // execute, and transmit the Software, and to prepare derivative works of the
00017 // Software, and to permit third-parties to whom the Software is furnished to
00018 // do so, all subject to the following:
00019 // 
00020 // The copyright notices in the Software and this entire statement, including
00021 // the above license grant, this restriction and the following disclaimer,
00022 // must be included in all copies of the Software, in whole or in part, and
00023 // all derivative works of the Software, unless such copies or derivative
00024 // works are solely in the form of machine-executable object code generated by
00025 // a source language processor.
00026 // 
00027 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00028 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00029 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
00030 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
00031 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
00032 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00033 // DEALINGS IN THE SOFTWARE.
00034 //
00035 
00036 
00037 #include "Poco/RWLock_WIN32.h"
00038 
00039 
00040 namespace Poco {
00041 
00042 
00043 RWLockImpl::RWLockImpl(): _readers(0), _writersWaiting(0), _writers(0)
00044 {
00045         _mutex = CreateMutexW(NULL, FALSE, NULL);
00046         if (_mutex == NULL)
00047                 throw SystemException("cannot create reader/writer lock");
00048 
00049         _readEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
00050         if (_readEvent == NULL)
00051                 throw SystemException("cannot create reader/writer lock");
00052 
00053         _writeEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
00054         if (_writeEvent == NULL)
00055                 throw SystemException("cannot create reader/writer lock");
00056 }
00057 
00058 
00059 RWLockImpl::~RWLockImpl()
00060 {
00061         CloseHandle(_mutex);
00062         CloseHandle(_readEvent);
00063         CloseHandle(_writeEvent);
00064 }
00065 
00066 
00067 inline void RWLockImpl::addWriter()
00068 {
00069         switch (WaitForSingleObject(_mutex, INFINITE))
00070         {
00071         case WAIT_OBJECT_0:
00072                 if (++_writersWaiting == 1) ResetEvent(_readEvent);
00073                 ReleaseMutex(_mutex);
00074                 break;
00075         default:
00076                 throw SystemException("cannot lock reader/writer lock");
00077         }
00078 }
00079 
00080 
00081 inline void RWLockImpl::removeWriter()
00082 {
00083         switch (WaitForSingleObject(_mutex, INFINITE))
00084         {
00085         case WAIT_OBJECT_0:
00086                 if (--_writersWaiting == 0 && _writers == 0) SetEvent(_readEvent);
00087                 ReleaseMutex(_mutex);
00088                 break;
00089         default:
00090                 throw SystemException("cannot lock reader/writer lock");
00091         }
00092 }
00093 
00094 
00095 void RWLockImpl::readLockImpl()
00096 {
00097         HANDLE h[2];
00098         h[0] = _mutex;
00099         h[1] = _readEvent;
00100         switch (WaitForMultipleObjects(2, h, TRUE, INFINITE))
00101         {
00102         case WAIT_OBJECT_0:
00103         case WAIT_OBJECT_0 + 1:
00104                 ++_readers;
00105                 ResetEvent(_writeEvent);
00106                 ReleaseMutex(_mutex);
00107                 poco_assert_dbg(_writers == 0);
00108                 break;
00109         default:
00110                 throw SystemException("cannot lock reader/writer lock");
00111         }
00112 }
00113 
00114 
00115 bool RWLockImpl::tryReadLockImpl()
00116 {
00117         HANDLE h[2];
00118         h[0] = _mutex;
00119         h[1] = _readEvent;
00120         switch (WaitForMultipleObjects(2, h, TRUE, 1))
00121         {
00122         case WAIT_OBJECT_0:
00123         case WAIT_OBJECT_0 + 1:
00124                 ++_readers;
00125                 ResetEvent(_writeEvent);
00126                 ReleaseMutex(_mutex);
00127                 poco_assert_dbg(_writers == 0);
00128                 return true;
00129         case WAIT_TIMEOUT:
00130                 return false;
00131         default:
00132                 throw SystemException("cannot lock reader/writer lock");
00133         }
00134 }
00135 
00136 
00137 void RWLockImpl::writeLockImpl()
00138 {
00139         addWriter();
00140         HANDLE h[2];
00141         h[0] = _mutex;
00142         h[1] = _writeEvent;
00143         switch (WaitForMultipleObjects(2, h, TRUE, INFINITE))
00144         {
00145         case WAIT_OBJECT_0:
00146         case WAIT_OBJECT_0 + 1:
00147                 --_writersWaiting;
00148                 ++_readers;
00149                 ++_writers;
00150                 ResetEvent(_readEvent);
00151                 ResetEvent(_writeEvent);
00152                 ReleaseMutex(_mutex);
00153                 poco_assert_dbg(_writers == 1);
00154                 break;
00155         default:
00156                 removeWriter();
00157                 throw SystemException("cannot lock reader/writer lock");
00158         }
00159 }
00160 
00161 
00162 bool RWLockImpl::tryWriteLockImpl()
00163 {
00164         addWriter();
00165         HANDLE h[2];
00166         h[0] = _mutex;
00167         h[1] = _writeEvent;
00168         switch (WaitForMultipleObjects(2, h, TRUE, 1))
00169         {
00170         case WAIT_OBJECT_0:
00171         case WAIT_OBJECT_0 + 1:
00172                 --_writersWaiting;
00173                 ++_readers;
00174                 ++_writers;
00175                 ResetEvent(_readEvent);
00176                 ResetEvent(_writeEvent);
00177                 ReleaseMutex(_mutex);
00178                 poco_assert_dbg(_writers == 1);
00179                 return true;
00180         case WAIT_TIMEOUT:
00181                 removeWriter();
00182                 return false;
00183         default:
00184                 removeWriter();
00185                 throw SystemException("cannot lock reader/writer lock");
00186         }
00187 }
00188 
00189 
00190 void RWLockImpl::unlockImpl()
00191 {
00192         switch (WaitForSingleObject(_mutex, INFINITE))
00193         {
00194         case WAIT_OBJECT_0:
00195                 _writers = 0;
00196                 if (_writersWaiting == 0) SetEvent(_readEvent);
00197                 if (--_readers == 0) SetEvent(_writeEvent);
00198                 ReleaseMutex(_mutex);
00199                 break;
00200         default:
00201                 throw SystemException("cannot unlock reader/writer lock");
00202         }
00203 }
00204 
00205 
00206 } // namespace Poco


pluginlib
Author(s): Tully Foote and Eitan Marder-Eppstein
autogenerated on Sat Dec 28 2013 17:20:19