00001 /*************************************************************************** 00002 ulxr_mutex.cpp - mutex handling 00003 ------------------- 00004 begin : Thu Dec 03 2002 00005 copyright : (C) 2002-2007 by Ewald Arnold 00006 email : ulxmlrpcpp@ewald-arnold.de 00007 00008 $Id: ulxr_mutex.cpp 940 2006-12-30 18:22:05Z ewald-arnold $ 00009 00010 ***************************************************************************/ 00011 00012 /************************************************************************** 00013 * 00014 * This program is free software; you can redistribute it and/or modify 00015 * it under the terms of the GNU Lesser General Public License as 00016 * published by the Free Software Foundation; either version 2 of the License, 00017 * or (at your option) any later version. 00018 * 00019 * This program is distributed in the hope that it will be useful, 00020 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 * GNU General Public License for more details. 00023 * 00024 * You should have received a copy of the GNU Lesser General Public License 00025 * along with this program; if not, write to the Free Software 00026 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00027 * 00028 ***************************************************************************/ 00029 00030 #define ULXR_NEED_EXPORTS 00031 #include <ulxmlrpcpp/ulxmlrpcpp.h> // always first header 00032 00033 #include <cerrno> 00034 00035 #ifdef __unix__ 00036 #include <pthread.h> 00037 #endif 00038 00039 #include "ulxr_mutex.h" 00040 #include "ulxr_except.h" 00041 00042 00043 namespace ulxr { 00044 00045 00046 ULXR_API_IMPL0 Mutex::Mutex() 00047 { 00048 #if defined __WIN32__ 00049 if ((handle = CreateMutex(0, false, 0)) < 0) 00050 #else 00051 if (pthread_mutex_init(&handle, 0) != 0) 00052 #endif 00053 throw Exception(SystemError, ulxr_i18n(ULXR_PCHAR("Could not create mutex"))); 00054 } 00055 00056 00057 ULXR_API_IMPL0 Mutex::~Mutex() throw() 00058 { 00059 #if defined __WIN32__ 00060 CloseHandle(handle); 00061 #elif _THREAD 00062 pthread_mutex_destroy(&handle); 00063 #endif 00064 } 00065 00066 00067 ULXR_API_IMPL(void) Mutex::lock() 00068 { 00069 #if defined __WIN32__ 00070 if (WaitForSingleObject(handle, INFINITE) == WAIT_TIMEOUT) 00071 #else 00072 if (pthread_mutex_lock(&handle) != 0) 00073 #endif 00074 throw Exception(SystemError, ulxr_i18n(ULXR_PCHAR("Could not lock mutex"))); 00075 } 00076 00077 00078 ULXR_API_IMPL(void) Mutex::unlock() 00079 { 00080 #if defined __WIN32__ 00081 if (!ReleaseMutex(handle)) 00082 #else 00083 if (pthread_mutex_unlock(&handle)!=0) 00084 #endif 00085 throw Exception(SystemError, ulxr_i18n(ULXR_PCHAR("Could not unlock mutex"))); 00086 } 00087 00088 00089 ULXR_API_IMPL(bool) Mutex::tryLock() 00090 { 00091 #if defined __WIN32__ 00092 00093 DWORD ret = WaitForSingleObject(handle, 1); 00094 00095 if (ret == WAIT_FAILED) 00096 return false; 00097 00098 if (ret == WAIT_TIMEOUT) 00099 return false; 00100 00101 if (ret == WAIT_ABANDONED) 00102 return false; 00103 00104 if (ret != WAIT_OBJECT_0) 00105 return false; 00106 00107 #else 00108 00109 int ret = pthread_mutex_trylock(&handle); 00110 if (ret == EBUSY) 00111 return false; 00112 00113 if (ret != 0) 00114 return false; 00115 00116 #endif 00117 00118 return true; 00119 } 00120 00121 00123 // 00124 00125 00126 ULXR_API_IMPL0 Mutex::Locker::Locker(Mutex &mtx) 00127 : mutex(&mtx) 00128 { 00129 mutex->lock(); 00130 } 00131 00132 00133 ULXR_API_IMPL0 Mutex::Locker::~Locker() throw() 00134 { 00135 try 00136 { 00137 mutex->unlock(); // might throw, forget it 00138 } 00139 catch(...) 00140 { 00141 } 00142 } 00143 00144 00146 // 00147 00148 00149 ULXR_API_IMPL0 Mutex::TryLocker::TryLocker(Mutex &mtx) 00150 : mutex(&mtx) 00151 { 00152 locked = mutex->tryLock(); 00153 } 00154 00155 00156 ULXR_API_IMPL0 Mutex::TryLocker::~TryLocker() throw() 00157 { 00158 try 00159 { 00160 if (isLocked()) 00161 mutex->unlock(); // might throw, forget it 00162 } 00163 catch(...) 00164 { 00165 } 00166 } 00167 00168 00169 ULXR_API_IMPL(bool) Mutex::TryLocker::isLocked() 00170 { 00171 return locked; 00172 } 00173 00174 00175 } // namespace ulxr 00176