00001 /* --------------------------------------------------------------------------- 00002 Phission : 00003 Realtime Vision Processing System 00004 00005 Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu) 00006 University of Massachusetts at Lowell, 00007 Laboratory for Artificial Intelligence and Robotics 00008 00009 This file is part of Phission. 00010 00011 Phission is free software; you can redistribute it and/or modify 00012 it under the terms of the GNU Lesser General Public License as published by 00013 the Free Software Foundation; either version 2 of the License, or 00014 (at your option) any later version. 00015 00016 Phission is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 GNU Lesser General Public License for more details. 00020 00021 You should have received a copy of the GNU Lesser General Public License 00022 along with Phission; if not, write to the Free Software 00023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00024 00025 ---------------------------------------------------------------------------*/ 00026 #ifndef _PHMUTEX_H 00027 #define _PHMUTEX_H 00028 00029 #include <phStdint.h> 00030 #include <phObject.h> 00031 00038 /* ---------------------------------------------------------------------- */ 00039 /* phMutex macros for 'this' */ 00040 /* ---------------------------------------------------------------------- */ 00041 /* These are used to clean up the code involved in locking the methods 00042 * of an object. These will likely be replaced with something even better 00043 * at some point */ 00044 /* ---------------------------------------------------------------------- */ 00048 #define phTHIS_LOOSE_LOCK(l) \ 00049 rc = this->lock(); \ 00050 phPRINT_RC(rc,NULL,"this->lock()"); \ 00051 if (rc == phSUCCESS) ++l; 00052 00056 #define phTHIS_LOCK(l) \ 00057 rc = this->lock(); \ 00058 phCHECK_RC(rc,NULL,"this->lock()"); \ 00059 ++l; 00060 00064 #define phTHIS_TRYLOCK(l,gotlock) \ 00065 rc = this->trylock(); \ 00066 phCHECK_RC(rc,NULL,"this->trylock()"); \ 00067 if (rc == phSUCCESS) { ++l; gotlock = 1; } \ 00068 else { gotlock = 0; } \ 00069 00070 00073 #define phTHIS_LOOSE_TRYLOCK(l,gotlock) \ 00074 rc = this->trylock(); \ 00075 phPRINT_RC(rc,NULL,"this->trylock()"); \ 00076 if (rc == phSUCCESS) { ++l; gotlock = 1; } \ 00077 else { gotlock = 0; } \ 00078 00079 00082 #define phTHIS_LOOSE_UNLOCK(l) \ 00083 if (l > 0) \ 00084 { \ 00085 rc = this->unlock(); \ 00086 phPRINT_RC(rc,NULL,"this->unlock()"); \ 00087 if (rc == phSUCCESS) --l; \ 00088 } 00089 00093 #define phTHIS_UNLOCK(l) \ 00094 if (l > 0) \ 00095 { \ 00096 rc = this->unlock(); \ 00097 --l; \ 00098 phCHECK_RC(rc,NULL,"this->unlock()"); \ 00099 } 00100 00104 #define phTHIS_ERROR_UNLOCK(l) \ 00105 if (l > 0) \ 00106 { \ 00107 do { \ 00108 rc = this->unlock(); \ 00109 phPRINT_RC(rc,NULL,"this->unlock()"); \ 00110 if (rc == phSUCCESS) --l; \ 00111 } while ((l > 0) && (rc == phSUCCESS)); \ 00112 } 00113 00117 #define phTHIS_UNLOCK_RET(l,success_value,error_value) \ 00118 phTHIS_UNLOCK(l); \ 00119 return success_value; \ 00120 error: \ 00121 phTHIS_ERROR_UNLOCK(l); \ 00122 return error_value; 00123 00124 /* ---------------------------------------------------------------------- */ 00125 /* phMutex macros */ 00126 /* ---------------------------------------------------------------------- */ 00127 /* These operate on any mutex */ 00128 /* ---------------------------------------------------------------------- */ 00132 #define phMUTEX_LOCK(m,l) \ 00133 rc = m.lock(); \ 00134 phCHECK_RC(rc,NULL,"m.lock()"); \ 00135 ++l; \ 00136 00137 00140 #define phMUTEX_TRYLOCK(m,l,gotlock) \ 00141 rc = m.trylock(); \ 00142 phCHECK_RC(rc,NULL,"m.trylock()"); \ 00143 if (rc == phSUCCESS) { ++l; gotlock = 1; } \ 00144 else { gotlock = 0; } \ 00145 00146 00149 #define phMUTEX_LOOSE_TRYLOCK(m,l,gotlock) \ 00150 rc = m.trylock(); \ 00151 phPRINT_RC(rc,NULL,"m.trylock()"); \ 00152 if (rc == phSUCCESS) { ++l; gotlock = 1; } \ 00153 else { gotlock = 0; } \ 00154 00155 00158 #define phMUTEX_LOOSE_LOCK(m,l) \ 00159 rc = m.lock(); \ 00160 phPRINT_RC(rc,NULL,"m.lock()"); \ 00161 if (rc == phSUCCESS) ++l; \ 00162 00163 00166 #define phMUTEX_UNLOCK(m,l) \ 00167 if (l > 0) \ 00168 { \ 00169 rc = m.unlock(); \ 00170 --l; \ 00171 phCHECK_RC(rc,NULL,"m.unlock()"); \ 00172 } 00173 00177 #define phMUTEX_LOOSE_UNLOCK(m,l) \ 00178 if (l > 0) \ 00179 { \ 00180 rc = m.unlock(); \ 00181 phPRINT_RC(rc,NULL,"m.unlock()"); \ 00182 if (rc == phSUCCESS) --l; \ 00183 } 00184 00188 #define phMUTEX_ERROR_UNLOCK(m,l) \ 00189 if (l > 0) \ 00190 { \ 00191 do { \ 00192 rc = m.unlock(); \ 00193 phPRINT_RC(rc,NULL,"m.unlock()"); \ 00194 if (rc == phSUCCESS) --l; \ 00195 } while ((l > 0) && (rc == phSUCCESS)); \ 00196 } 00197 00201 #define phMUTEX_UNLOCK_RET(m,l,success_value,error_value) \ 00202 phMUTEX_UNLOCK(m,l); \ 00203 return success_value; \ 00204 error: \ 00205 phMUTEX_ERROR_UNLOCK(m,l); \ 00206 return error_value; 00207 00208 /* ---------------------------------------------------------------------- */ 00212 typedef struct ph_mutex_info_t *ph_mutex_info; 00213 00214 /* ---------------------------------------------------------------------- */ 00282 PHAPI(class) phMutex : public phObject 00283 { 00284 private: 00290 ph_mutex_info m_mutex_info; 00296 uint32_t m_locked_count; 00300 uintmax_t m_owner; 00301 00302 protected: 00303 /* let phCondition have some access to phMutex settings */ 00313 void *m_private_mutex; 00331 int incLockCount(); 00347 int decLockCount(); 00354 uint32_t getLockCount(); 00355 00356 00357 public: 00358 phMutex(); 00359 virtual ~phMutex(); 00360 00361 /* The 3 possible operations to be performed on a mutex are 00362 * lock, trylock and unlock. What more is there to say ? */ 00363 00391 int lock (); 00407 int trylock (); 00426 int unlock (); 00427 00428 /* Thread safe phObject operations - see phMutex.cpp for comments */ 00429 /* 00430 void setName(const char *n); 00431 int isNamed(const char *n); 00432 */ 00433 /* getName, copy, swap can't be made thread-safe unless there is a 00434 * phMutex private variable that is allocated for every thread... which 00435 * doesn't make much sense. 00436 * 00437 * getName would get a pointer to the name of the object which could 00438 * be freed anytime after the method returns. 00439 * 00440 * copy and swap should be made thread-safe by any inheriting class 00441 * if it's required. 00442 */ 00443 }; 00444 /* end \addtogroup ThreadSync */ 00446 00447 #endif /* _PHMUTEX_H */
Copyright (C) 2002 - 2007 |
Philip D.S. Thoren ( pthoren@users.sourceforge.net ) University Of Massachusetts at Lowell Robotics Lab |