RWLockImplWin32.cpp
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 // This file is part of FZIs ic_workspace.
00005 //
00006 // This program is free software licensed under the LGPL
00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00008 // You can find a copy of this license in LICENSE folder in the top
00009 // directory of the source code.
00010 //
00011 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00012 //
00013 // -- END LICENSE BLOCK ------------------------------------------------
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 // ReadLock with absolute timeout
00050 bool RWLockImplWin32::readLock(const TimeStamp& timeout)
00051 {
00052   return readLock(impl::getRelativeTimeout(timeout));
00053 }
00054 
00055 // ReadLock with relative timeout
00056 bool RWLockImplWin32::readLock(const TimeSpan& timeout)
00057 {
00058   return readLock(DWORD(timeout.toMSec()));
00059 }
00060 
00061 bool RWLockImplWin32::readLock(DWORD timeout)
00062 {
00063   // get the reader access
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 // WriteLock with absolute timeout
00092 bool RWLockImplWin32::writeLock(const TimeStamp& timeout)
00093 {
00094   return writeLock(impl::getRelativeTimeout(timeout));
00095 }
00096 
00097 // WriteLock with relative timeout
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   // writer unlock
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   // search for reader
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 }


fzi_icl_core
Author(s):
autogenerated on Tue Aug 8 2017 02:28:03