Mixe for Privacy and Anonymity in the Internet
CAConditionVariable.hpp
Go to the documentation of this file.
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
00150 
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