Go to the documentation of this file.00001
00002
00008
00009
00010 #include "icl_core_thread/Common.h"
00011 #include "icl_core_thread/RWLockImplWin32.h"
00012
00013 namespace icl_core {
00014 namespace thread {
00015
00016 RWLockImplWin32::RWLockImplWin32()
00017 : m_number_of_writer(0),
00018 m_number_of_reader(0),
00019 m_writer_pid(0)
00020 {
00021 m_reader_mutex_event = CreateEvent(NULL, FALSE, TRUE, NULL);
00022 m_writer_mutex = CreateMutex(NULL, FALSE, NULL);
00023 }
00024
00025 RWLockImplWin32::~RWLockImplWin32()
00026 {
00027 CloseHandle(m_reader_mutex_event);
00028 CloseHandle(m_writer_mutex);
00029 }
00030
00031 bool RWLockImplWin32::readLock()
00032 {
00033 return readLock(INFINITE);
00034 }
00035
00036
00037 bool RWLockImplWin32::readLock(const TimeStamp& timeout)
00038 {
00039 return readLock(impl::getRelativeTimeout(timeout));
00040 }
00041
00042
00043 bool RWLockImplWin32::readLock(const TimeSpan& timeout)
00044 {
00045 return readLock(DWORD(timeout.toMSec()));
00046 }
00047
00048 bool RWLockImplWin32::readLock(DWORD timeout)
00049 {
00050
00051 bool ret = false;
00052 if (m_reader_access_lock.lock())
00053 {
00054 if (m_reader_pid.empty())
00055 {
00056 ret = WaitForSingleObject(m_reader_mutex_event, timeout) == WAIT_OBJECT_0;
00057 }
00058 if (ret || !m_reader_pid.empty())
00059 {
00060 ret = true;
00061 m_reader_pid.push_back(GetCurrentThreadId());
00062 }
00063 m_reader_access_lock.unlock();
00064 }
00065 return ret;
00066 }
00067
00068 bool RWLockImplWin32::tryReadLock()
00069 {
00070 return readLock(0);
00071 }
00072
00073 bool RWLockImplWin32::writeLock()
00074 {
00075 return writeLock(INFINITE);
00076 }
00077
00078
00079 bool RWLockImplWin32::writeLock(const TimeStamp& timeout)
00080 {
00081 return writeLock(impl::getRelativeTimeout(timeout));
00082 }
00083
00084
00085 bool RWLockImplWin32::writeLock(const TimeSpan& timeout)
00086 {
00087 return writeLock(DWORD(timeout.toMSec()));
00088 }
00089
00090 bool RWLockImplWin32::writeLock(DWORD timeout)
00091 {
00092 bool ret = (WaitForSingleObject(m_writer_mutex, timeout) == WAIT_OBJECT_0)
00093 && (WaitForSingleObject(m_reader_mutex_event, timeout) == WAIT_OBJECT_0);
00094 if (ret)
00095 {
00096 m_writer_pid = GetCurrentThreadId();
00097 m_number_of_writer++;
00098 }
00099 return ret;
00100 }
00101
00102 bool RWLockImplWin32::tryWriteLock()
00103 {
00104 return writeLock(0);
00105 }
00106
00107 void RWLockImplWin32::unlock()
00108 {
00109 int thread_pid = GetCurrentThreadId();
00110
00111
00112 if (thread_pid == m_writer_pid)
00113 {
00114 ReleaseMutex(m_writer_mutex);
00115 m_number_of_writer--;
00116 if (m_number_of_writer == 0)
00117 {
00118 m_writer_pid = 0;
00119 SetEvent(m_reader_mutex_event);
00120 }
00121 }
00122
00123 else
00124 {
00125 if (m_reader_access_lock.lock(TimeSpan(30000, 0)))
00126 {
00127 std::vector<int>::iterator iter;
00128 for (iter = m_reader_pid.begin(); iter != m_reader_pid.end(); iter++)
00129 {
00130 if (thread_pid == *iter)
00131 {
00132 m_reader_pid.erase(iter);
00133 if (m_reader_pid.empty())
00134 {
00135 SetEvent(m_reader_mutex_event);
00136 };
00137 break;
00138 }
00139 }
00140 m_reader_access_lock.unlock();
00141 }
00142 }
00143 }
00144
00145 }
00146 }