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


rplidar_ros
Author(s):
autogenerated on Fri Aug 28 2015 12:46:43