00001 /* 00002 Copyright (c) 2000, The JAP-Team 00003 All rights reserved. 00004 Redistribution and use in source and binary forms, with or without modification, 00005 are permitted provided that the following conditions are met: 00006 00007 - Redistributions of source code must retain the above copyright notice, 00008 this list of conditions and the following disclaimer. 00009 00010 - Redistributions in binary form must reproduce the above copyright notice, 00011 this list of conditions and the following disclaimer in the documentation and/or 00012 other materials provided with the distribution. 00013 00014 - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors 00015 may be used to endorse or promote products derived from this software without specific 00016 prior written permission. 00017 00018 00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 00027 */ 00028 #ifndef __CACONVAR__ 00029 #define __CACONVAR__ 00030 #ifndef ONLY_LOCAL_PROXY 00031 00032 #include "CAMutex.hpp" 00033 #include "CAUtil.hpp" 00034 #include "CASemaphore.hpp" 00035 00036 class CAConditionVariable:public CAMutex 00037 { 00038 public: 00039 CAConditionVariable() 00040 { 00041 #ifdef HAVE_PTHREAD_CV 00042 m_pCondVar=new pthread_cond_t; 00043 pthread_cond_init(m_pCondVar,NULL); 00044 #else 00045 m_pMutex=new CAMutex(); 00046 m_pSemaphore=new CASemaphore(0); 00047 m_iSleepers=0; 00048 #endif 00049 } 00050 00051 ~CAConditionVariable() 00052 { 00053 #ifdef HAVE_PTHREAD_CV 00054 pthread_cond_destroy(m_pCondVar); 00055 delete m_pCondVar; 00056 m_pCondVar = NULL; 00057 #else 00058 delete m_pMutex; 00059 m_pMutex = NULL; 00060 delete m_pSemaphore; 00061 m_pSemaphore = NULL; 00062 #endif 00063 } 00064 00071 SINT32 wait() 00072 { 00073 #ifdef HAVE_PTHREAD_CV 00074 if(pthread_cond_wait(m_pCondVar,m_pMutex)==0) 00075 return E_SUCCESS; 00076 return E_UNKNOWN; 00077 #else 00078 m_pMutex->lock(); 00079 unlock(); // Release the lock that is associated with our cv 00080 m_iSleepers++; 00081 m_pMutex->unlock(); 00082 m_pSemaphore->down(); 00083 return lock(); 00084 #endif 00085 } 00086 00089 SINT32 wait(CAMutex& oMutex) 00090 { 00091 #ifdef HAVE_PTHREAD_CV 00092 if(pthread_cond_wait(m_pCondVar,oMutex.m_pMutex)==0) 00093 return E_SUCCESS; 00094 return E_UNKNOWN; 00095 #else 00096 m_pMutex->lock(); 00097 oMutex.unlock(); // Release the lock that is associated with our cv 00098 m_iSleepers++; 00099 m_pMutex->unlock(); 00100 m_pSemaphore->down(); 00101 return oMutex.lock(); 00102 #endif 00103 } 00104 00107 SINT32 wait(CAMutex* pMutex) 00108 { 00109 #ifdef HAVE_PTHREAD_CV 00110 if(pthread_cond_wait(m_pCondVar,pMutex->m_pMutex)==0) 00111 return E_SUCCESS; 00112 return E_UNKNOWN; 00113 #else 00114 m_pMutex->lock(); 00115 pMutex->unlock(); // Release the lock that is associated with our cv 00116 m_iSleepers++; 00117 m_pMutex->unlock(); 00118 m_pSemaphore->down(); 00119 return pMutex->lock(); 00120 #endif 00121 } 00122 00131 SINT32 wait(UINT32 msTimeout) 00132 { 00133 #ifdef HAVE_PTHREAD_CV 00134 timespec to; 00135 getcurrentTime(to); 00136 to.tv_nsec+=(msTimeout%1000)*1000000; 00137 to.tv_sec+=msTimeout/1000; 00138 if(to.tv_nsec>999999999) 00139 { 00140 to.tv_sec++; 00141 to.tv_nsec-=1000000000; 00142 } 00143 int ret=pthread_cond_timedwait(m_pCondVar,m_pMutex,&to); 00144 if(ret==0) 00145 return E_SUCCESS; 00146 else if(ret==ETIMEDOUT) 00147 return E_TIMEDOUT; 00148 return E_UNKNOWN; 00149 #else 00151 return wait(); 00152 #endif 00153 } 00154 00159 SINT32 signal() 00160 { 00161 #ifdef HAVE_PTHREAD_CV 00162 if(pthread_cond_signal(m_pCondVar)==0) 00163 return E_SUCCESS; 00164 return E_UNKNOWN; 00165 #else 00166 m_pMutex->lock(); 00167 if( m_iSleepers > 0 ) 00168 { 00169 m_pSemaphore->up(); 00170 m_iSleepers--; 00171 } 00172 return m_pMutex->unlock(); 00173 #endif 00174 } 00175 00180 SINT32 broadcast() 00181 { 00182 #ifdef HAVE_PTHREAD_CV 00183 if(pthread_cond_broadcast(m_pCondVar)==0) 00184 return E_SUCCESS; 00185 return E_UNKNOWN; 00186 #else 00187 m_pMutex->lock(); 00188 while( m_iSleepers > 0 ) 00189 { 00190 m_pSemaphore->up(); 00191 m_iSleepers--; 00192 } 00193 return m_pMutex->unlock(); 00194 #endif 00195 } 00196 00197 private: 00198 #ifdef HAVE_PTHREAD_CV 00199 pthread_cond_t* m_pCondVar; 00200 #else 00201 CAMutex* m_pMutex; 00202 CASemaphore* m_pSemaphore; 00203 UINT32 m_iSleepers; 00204 #endif 00205 }; 00206 #endif 00207 #endif //ONLY_LOCAL_PROXY
1.5.6