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 //---------------------------------------------------------------------- 00022 //---------------------------------------------------------------------- 00023 #include "icl_core_thread/RWLockImplPosix.h" 00024 00025 #include <pthread.h> 00026 #include <icl_core/os_time.h> 00027 00028 #include "icl_core_thread/Common.h" 00029 00030 namespace icl_core { 00031 namespace thread { 00032 00033 RWLockImplPosix::RWLockImplPosix() 00034 : m_rwlock(NULL) 00035 { 00036 m_rwlock = new pthread_rwlock_t; 00037 pthread_rwlock_init(m_rwlock, NULL); 00038 } 00039 00040 RWLockImplPosix::~RWLockImplPosix() 00041 { 00042 if (m_rwlock) 00043 { 00044 pthread_rwlock_destroy(m_rwlock); 00045 delete m_rwlock; 00046 m_rwlock = NULL; 00047 } 00048 } 00049 00050 bool RWLockImplPosix::readLock() 00051 { 00052 return pthread_rwlock_rdlock(m_rwlock) == 0; 00053 } 00054 00055 // ReadLock with absolute timeout 00056 bool RWLockImplPosix::readLock(const ::icl_core::TimeStamp& timeout) 00057 { 00058 #ifdef _SYSTEM_DARWIN_ 00059 int ret = pthread_rwlock_tryrdlock(m_rwlock); 00060 while ((ret != 0) && ((timeout > icl_core::TimeStamp::now()))) 00061 { 00062 // one microsecond 00063 icl_core::os::usleep(1); 00064 ret = pthread_rwlock_tryrdlock(m_rwlock); 00065 } 00066 return (ret == 0); 00067 #else 00068 struct timespec timeout_timespec = timeout.timespec(); 00069 int ret = pthread_rwlock_timedrdlock(m_rwlock, &timeout_timespec); 00070 return (ret == 0); 00071 #endif 00072 } 00073 00074 // ReadLock with relative timeout 00075 bool RWLockImplPosix::readLock(const ::icl_core::TimeSpan& timeout) 00076 { 00077 return readLock(impl::getAbsoluteTimeout(timeout)); 00078 } 00079 00080 bool RWLockImplPosix::tryReadLock() 00081 { 00082 bool ret = pthread_rwlock_tryrdlock(m_rwlock); 00083 return (ret == 0); 00084 } 00085 00086 bool RWLockImplPosix::writeLock() 00087 { 00088 return pthread_rwlock_wrlock(m_rwlock) == 0; 00089 } 00090 00091 // WriteLock with absolute timeout 00092 bool RWLockImplPosix::writeLock(const ::icl_core::TimeStamp& timeout) 00093 { 00094 #ifdef _SYSTEM_DARWIN_ 00095 int ret = pthread_rwlock_trywrlock(m_rwlock); 00096 while ((ret != 0) && ((timeout > icl_core::TimeStamp::now()))) 00097 { 00098 // one microsecond 00099 icl_core::os::usleep(1); 00100 ret = pthread_rwlock_trywrlock(m_rwlock); 00101 } 00102 return (ret == 0); 00103 #else 00104 struct timespec timeout_timespec = timeout.timespec(); 00105 bool ret = pthread_rwlock_timedwrlock(m_rwlock, &timeout_timespec); 00106 return (ret == 0); 00107 #endif 00108 } 00109 00110 // WriteLock with relative timeout 00111 bool RWLockImplPosix::writeLock(const ::icl_core::TimeSpan& timeout) 00112 { 00113 return writeLock(impl::getAbsoluteTimeout(timeout)); 00114 } 00115 00116 bool RWLockImplPosix::tryWriteLock() 00117 { 00118 bool ret = pthread_rwlock_trywrlock(m_rwlock); 00119 return (ret == 0); 00120 } 00121 00122 void RWLockImplPosix::unlock() 00123 { 00124 pthread_rwlock_unlock(m_rwlock); 00125 } 00126 00127 } 00128 }