00001 // **************************************************************************** 00002 // This file is part of the Integrating Vision Toolkit (IVT). 00003 // 00004 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT) 00005 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de). 00006 // 00007 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT). 00008 // All rights reserved. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are met: 00012 // 00013 // 1. Redistributions of source code must retain the above copyright 00014 // notice, this list of conditions and the following disclaimer. 00015 // 00016 // 2. Redistributions in binary form must reproduce the above copyright 00017 // notice, this list of conditions and the following disclaimer in the 00018 // documentation and/or other materials provided with the distribution. 00019 // 00020 // 3. Neither the name of the KIT nor the names of its contributors may be 00021 // used to endorse or promote products derived from this software 00022 // without specific prior written permission. 00023 // 00024 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY 00025 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00026 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY 00028 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00029 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00031 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00032 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00033 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 // **************************************************************************** 00035 // **************************************************************************** 00036 // Filename: Event.cpp 00037 // Author: Kai Welke 00038 // Date: 13.01.2006 00039 // **************************************************************************** 00040 00041 00042 // **************************************************************************** 00043 // Includes 00044 // **************************************************************************** 00045 00046 #include <new> // for explicitly using correct new/delete operators on VC DSPs 00047 00048 #include "Event.h" 00049 00050 #include "Threading.h" 00051 00052 #include <stdio.h> 00053 00054 00055 00056 // **************************************************************************** 00057 // Constructor / Destructor 00058 // **************************************************************************** 00059 00060 CEvent::CEvent() 00061 { 00062 #ifdef WIN32 00063 InitializeCriticalSection(&m_CSWindowsMutex); 00064 m_SignalEvent = CreateEvent(NULL,false,false,NULL); 00065 #else 00066 pthread_mutexattr_init(&m_MutexAttr); 00067 pthread_mutex_init(&m_PosixMutex ,&m_MutexAttr); 00068 pthread_condattr_init(&m_ConditionalAttr); 00069 pthread_cond_init(&m_PosixConditional,&m_ConditionalAttr); 00070 00071 m_bSignaled = false; 00072 #endif 00073 } 00074 00075 CEvent::~CEvent() 00076 { 00077 #ifdef WIN32 00078 DeleteCriticalSection(&m_CSWindowsMutex); 00079 CloseHandle(m_SignalEvent); 00080 #else 00081 pthread_mutex_destroy(&m_PosixMutex); 00082 pthread_mutexattr_destroy(&m_MutexAttr); 00083 pthread_cond_destroy(&m_PosixConditional); 00084 pthread_condattr_destroy(&m_ConditionalAttr); 00085 #endif 00086 } 00087 00088 00089 // **************************************************************************** 00090 // Methods 00091 // **************************************************************************** 00092 void CEvent::Reset() 00093 { 00094 #ifdef WIN32 00095 ResetEvent(m_SignalEvent); 00096 #else 00097 pthread_mutex_lock(&m_PosixMutex); 00098 m_bSignaled = false; 00099 pthread_mutex_unlock(&m_PosixMutex); 00100 00101 pthread_cond_signal(&m_PosixConditional); 00102 #endif 00103 } 00104 00105 Threading::EEventStatus CEvent::Wait(int nMS) 00106 { 00107 #ifdef WIN32 00108 int nWaitMS; 00109 if (nMS == Threading::WAIT_INFINITE) 00110 nWaitMS = INFINITE; 00111 else 00112 nWaitMS = nMS; 00113 00114 if (WaitForSingleObject(m_SignalEvent, nWaitMS) == WAIT_OBJECT_0) 00115 return Threading::eEventSuccess; 00116 else 00117 return Threading::eEventTimeout; 00118 #else 00119 // lock mutex for signal 00120 pthread_mutex_lock(&m_PosixMutex); 00121 00122 // when we are not signalled, we wait for signal 00123 if (!m_bSignaled) 00124 { 00125 if (nMS == Threading::WAIT_INFINITE) // wait infinite 00126 { 00127 // have to do a loop, because linux sometimes messes other signals to this one 00128 while (!m_bSignaled) 00129 { 00130 pthread_cond_wait(&m_PosixConditional, &m_PosixMutex); 00131 } 00132 00133 // we consumed the signal 00134 m_bSignaled = false; 00135 00136 // mutex can be unlocked 00137 pthread_mutex_unlock(&m_PosixMutex); 00138 00139 // return with success 00140 return Threading::eEventSuccess; 00141 } 00142 else // wait with timeout 00143 { 00144 // set timer structure 00145 time_t current = time(NULL); 00146 timespec uni_ts; 00147 int nSeconds = nMS / 1000; 00148 if (nSeconds == 0) 00149 { 00150 nSeconds = 1; 00151 nMS = 0; 00152 } 00153 else 00154 { 00155 nMS -= nSeconds * 1000; 00156 } 00157 00158 uni_ts.tv_sec = current + nSeconds; 00159 uni_ts.tv_nsec = nMS * 1000; 00160 00161 00162 if (pthread_cond_timedwait(&m_PosixConditional, &m_PosixMutex, &uni_ts) == 0) 00163 { 00164 if (m_bSignaled) 00165 { 00166 m_bSignaled = false; 00167 pthread_mutex_unlock(&m_PosixMutex); 00168 return Threading::eEventSuccess; 00169 } 00170 else 00171 { 00172 pthread_mutex_unlock(&m_PosixMutex); 00173 return Threading::eEventTimeout; 00174 } 00175 } 00176 else 00177 { 00178 m_bSignaled = false; 00179 pthread_mutex_unlock(&m_PosixMutex); 00180 00181 // perhaps we didnt enter idle so yield 00182 Threading::YieldThread(); 00183 00184 return Threading::eEventTimeout; 00185 } 00186 } 00187 00188 00189 } 00190 else 00191 { 00192 // consume signal 00193 m_bSignaled = false; 00194 00195 // unlock signal mutex 00196 pthread_mutex_unlock(&m_PosixMutex); 00197 00198 // we didnt enter idle so yield 00199 Threading::YieldThread(); 00200 } 00201 00202 return Threading::eEventSuccess; 00203 #endif 00204 } 00205 00206 void CEvent::Signal() 00207 { 00208 #ifdef WIN32 00209 SetEvent(m_SignalEvent); 00210 #else 00211 pthread_mutex_lock(&m_PosixMutex); 00212 m_bSignaled = true; 00213 pthread_mutex_unlock(&m_PosixMutex); 00214 00215 pthread_cond_signal(&m_PosixConditional); 00216 #endif 00217 }