Pol  Rev 533
clib/hbmutex.cpp
Go to the documentation of this file.
00001 /*
00002  * With permission to reuse:
00003  * Author:  Thomas Volkert
00004  * Libary:  Homerbase http://www.homer-conferencing.com/
00005  * Since:   2010-09-20
00006  */
00007 
00008 #include "hbmutex.h"
00009 #include "logfile.h"
00010 
00012 
00013 Mutex::Mutex()
00014 {
00015         bool tResult = false;
00016 #ifdef _WIN32
00017         mPThreadMutex = CreateMutex(NULL, false, NULL);
00018         tResult = (mPThreadMutex != NULL);
00019 #else
00020         mPThreadMutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
00021         tResult = (pthread_mutex_init(mPThreadMutex, NULL) == 0);
00022 #endif
00023         if (!tResult)
00024         Log("Initiation of mutex failed");
00025 }
00026 
00027 Mutex::~Mutex()
00028 {
00029     bool tResult = false;
00030 #ifdef _WIN32
00031         tResult = (CloseHandle(mPThreadMutex) != 0);
00032 #else
00033         tResult = (pthread_mutex_destroy(mPThreadMutex) == 0);
00034         free(mPThreadMutex);
00035 #endif
00036     if (!tResult)
00037                 Log("Destruction of mutex failed");
00038 }
00039 
00041 
00042 bool Mutex::lock()
00043 {
00044 #ifdef _WIN32
00045         return (WaitForSingleObject(mPThreadMutex, INFINITE) != WAIT_FAILED);
00046 #else
00047         return !pthread_mutex_lock(mPThreadMutex);
00048 #endif
00049 }
00050 
00051 bool Mutex::unlock()
00052 {
00053 #ifdef _WIN32
00054         return (ReleaseMutex(mPThreadMutex) != 0);
00055 #else
00056         return !pthread_mutex_unlock(mPThreadMutex);
00057 #endif
00058 }
00059 
00060 bool Mutex::tryLock()
00061 {
00062         bool tResult = false;
00063 #ifdef _WIN32
00064         switch(WaitForSingleObject(mPThreadMutex, (DWORD)0))
00065         {
00066         case WAIT_ABANDONED:
00067         case WAIT_TIMEOUT:
00068         case WAIT_FAILED:
00069                 break;
00070         case WAIT_OBJECT_0:
00071                 tResult = true;
00072                 break;
00073         }
00074 #else
00075         switch(pthread_mutex_trylock(mPThreadMutex))
00076         {
00077                 case EDEADLK:
00078                         Log("Lock already held by calling thread");
00079                         break;
00080                 case EBUSY: // lock can't be obtained because it is busy
00081                         break;
00082                 case EINVAL:
00083                         Log("Lock was found in uninitialized state");
00084                         break;
00085                 case EFAULT:
00086                         Log("Invalid lock pointer was given");
00087                         break;
00088                 case 0: // lock was free and is obtained now
00089                         tResult = true;
00090                         break;
00091                 default:
00092                         Log("Error occurred while trying to get lock: code %d", tResult);
00093                         break;
00094         }
00095 #endif
00096         return tResult;
00097 }
00098 
00099 
00100 bool Mutex::tryLock(int pMSecs)
00101 {
00102         bool tResult = false;
00103 #ifdef _WIN32
00104         switch(WaitForSingleObject(mPThreadMutex, (DWORD)pMSecs))
00105         {
00106         case WAIT_ABANDONED:
00107         case WAIT_TIMEOUT:
00108         case WAIT_FAILED:
00109                 break;
00110         case WAIT_OBJECT_0:
00111                 tResult = true;
00112                 break;
00113         }
00114 #else
00115         struct timespec tTimeout;
00116 
00117         if (clock_gettime(CLOCK_REALTIME, &tTimeout) == -1)
00118                 Log("Failed to get time from clock");
00119 
00120         // add msecs to current time stamp
00121         tTimeout.tv_nsec += pMSecs * 1000 * 1000;
00122 
00123         switch(pthread_mutex_timedlock(mPThreadMutex, &tTimeout))
00124         {
00125                 case EDEADLK:
00126                         Log("Lock already held by calling thread");
00127                         break;
00128                 case EBUSY: // lock can't be obtained because it is busy
00129                         break;
00130                 case EINVAL:
00131                         Log("Lock was found in uninitialized state");
00132                         break;
00133                 case EFAULT:
00134                         Log("Invalid lock pointer was given");
00135                         break;
00136                 case ETIMEDOUT:
00137                         Log("Lock couldn't be obtained in given time");
00138                         break;
00139                 case 0: // lock was free and is obtained now
00140                         tResult = true;
00141                         break;
00142                 default:
00143                         Log("Error occurred while trying to get lock: code %d", tResult);
00144                         break;
00145         }
00146 #endif
00147         return tResult;
00148 }
00149 
00151