locker.h
Go to the documentation of this file.
00001 /*
00002  *  RPLIDAR SDK
00003  *
00004  *  Copyright (c) 2009 - 2014 RoboPeak Team
00005  *  http://www.robopeak.com
00006  *  Copyright (c) 2014 - 2019 Shanghai Slamtec Co., Ltd.
00007  *  http://www.slamtec.com
00008  *
00009  */
00010 /*
00011  * Redistribution and use in source and binary forms, with or without 
00012  * modification, are permitted provided that the following conditions are met:
00013  *
00014  * 1. Redistributions of source code must retain the above copyright notice, 
00015  *    this list of conditions and the following disclaimer.
00016  *
00017  * 2. Redistributions in binary form must reproduce the above copyright notice, 
00018  *    this list of conditions and the following disclaimer in the documentation 
00019  *    and/or other materials provided with the distribution.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
00023  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00024  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
00025  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00026  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00027  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00028  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00029  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00030  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
00031  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  */
00034 
00035 #pragma once
00036 namespace rp{ namespace hal{ 
00037 
00038 class Locker
00039 {
00040 public:
00041     enum LOCK_STATUS
00042     {
00043         LOCK_OK = 1,
00044         LOCK_TIMEOUT = -1,
00045         LOCK_FAILED = 0
00046     };
00047 
00048     Locker(){
00049 #ifdef _WIN32
00050         _lock = NULL;
00051 #endif
00052         init();
00053     }
00054 
00055     ~Locker()
00056     {
00057         release();
00058     }
00059 
00060     Locker::LOCK_STATUS lock(unsigned long timeout = 0xFFFFFFFF)
00061     {
00062 #ifdef _WIN32
00063         switch (WaitForSingleObject(_lock, timeout==0xFFFFFFF?INFINITE:(DWORD)timeout))
00064         {
00065         case WAIT_ABANDONED:
00066             return LOCK_FAILED;
00067         case WAIT_OBJECT_0:
00068             return LOCK_OK;
00069         case WAIT_TIMEOUT:
00070             return LOCK_TIMEOUT;
00071         }
00072 
00073 #else
00074 #ifdef _MACOS
00075         if (timeout !=0 ) {
00076             if (pthread_mutex_lock(&_lock) == 0) return LOCK_OK;
00077         }
00078 #else
00079         if (timeout == 0xFFFFFFFF){
00080             if (pthread_mutex_lock(&_lock) == 0) return LOCK_OK;
00081         }
00082 #endif
00083         else if (timeout == 0)
00084         {
00085             if (pthread_mutex_trylock(&_lock) == 0) return LOCK_OK;
00086         }
00087 #ifndef _MACOS
00088         else
00089         {
00090             timespec wait_time;
00091             timeval now;
00092             gettimeofday(&now,NULL);
00093 
00094             wait_time.tv_sec = timeout/1000 + now.tv_sec;
00095             wait_time.tv_nsec = (timeout%1000)*1000000 + now.tv_usec*1000;
00096         
00097             if (wait_time.tv_nsec >= 1000000000)
00098             {
00099                ++wait_time.tv_sec;
00100                wait_time.tv_nsec -= 1000000000;
00101             }
00102             switch (pthread_mutex_timedlock(&_lock,&wait_time))
00103             {
00104             case 0:
00105                 return LOCK_OK;
00106             case ETIMEDOUT:
00107                 return LOCK_TIMEOUT;
00108             }
00109         }
00110 #endif
00111 #endif
00112 
00113         return LOCK_FAILED;
00114     }
00115 
00116 
00117     void unlock()
00118     {
00119 #ifdef _WIN32
00120         ReleaseMutex(_lock);
00121 #else
00122         pthread_mutex_unlock(&_lock);
00123 #endif
00124     }
00125 
00126 #ifdef _WIN32
00127     HANDLE getLockHandle()
00128     {
00129         return _lock;
00130     }
00131 #else
00132     pthread_mutex_t *getLockHandle()
00133     {
00134         return &_lock;
00135     }
00136 #endif
00137 
00138 
00139 
00140 protected:
00141     void    init()
00142     {
00143 #ifdef _WIN32
00144         _lock = CreateMutex(NULL,FALSE,NULL);
00145 #else
00146         pthread_mutex_init(&_lock, NULL);
00147 #endif
00148     }
00149 
00150     void    release()
00151     {
00152         unlock(); //force unlock before release
00153 #ifdef _WIN32
00154 
00155         if (_lock) CloseHandle(_lock);
00156         _lock = NULL;
00157 #else
00158         pthread_mutex_destroy(&_lock);
00159 #endif
00160     }
00161 
00162 #ifdef _WIN32
00163     HANDLE  _lock;
00164 #else
00165     pthread_mutex_t _lock;
00166 #endif
00167 };
00168 
00169 class AutoLocker
00170 {
00171 public :
00172     AutoLocker(Locker &l): _binded(l)
00173     {
00174         _binded.lock();
00175     }
00176 
00177     void forceUnlock() {
00178         _binded.unlock();
00179     }
00180     ~AutoLocker() {_binded.unlock();}
00181     Locker & _binded;
00182 };
00183 
00184 
00185 }}
00186 


rplidar_ros
Author(s):
autogenerated on Mon Mar 18 2019 02:34:23