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