00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #pragma once
00012
00013 #include "TestToolBox/CommonSources/CommonDefinitions.h"
00014 #include "TestToolBox/Synchronizer.h"
00015 #include "TestToolBox/IEventReceiver.h"
00016 #include <assert.h>
00017
00018
00019
00020
00021
00022 #ifdef TTB_NOT_INLINE
00023 #define TTB_INLINE
00024 #else
00025 #define TTB_INLINE inline
00026 #endif
00027
00028 namespace TestToolBox
00029 {
00030
00031
00032
00033
00034
00035
00036
00037
00038 TTB_INLINE void Synchronizer::ConnectWithEventReceiver(
00039 IEventReceiver* in_pIEventReceiver)
00040 {
00041 m_pIEventReceiver = in_pIEventReceiver;
00042
00043 }
00044
00045
00046
00047
00048
00049
00050 TTB_INLINE void Synchronizer::SetSyncTimeout(
00051 long in_timeoutMs)
00052 {
00053 InterlockedExchange(&m_syncTimeoutMs, in_timeoutMs);
00054
00055 }
00056
00057
00058
00059
00060
00061
00062 TTB_INLINE void Synchronizer::InitSync(
00063 long in_numSyncEventsToWaitFor)
00064 {
00065 AutoLock o (this);
00066
00067 m_curSyncCount = 0;
00068 m_numSyncEventsToWaitFor = in_numSyncEventsToWaitFor;
00069 ResetEvent(m_hSyncEvent);
00070
00071 }
00072
00073
00074
00075
00076
00077
00078 TTB_INLINE void Synchronizer::WaitSync(
00079 const char* in_fileName,
00080 const long in_lineNum)
00081 {
00082
00083
00084
00085
00086
00087
00088 long in_numSyncEvents = 0;
00089
00090 TRCF("Synchronizer::WaitSync");
00091 TRC(TL_DEBUG,"Begin");
00092 long oldMaxCount = 0;
00093 bool waitForEvent = true;
00094 bool restoreMaxCount = false;
00095
00096
00097
00098 {
00099 AutoLock o (this);
00100 TRC(TL_DEBUG, "after lock: "
00101 "m_numSyncEventsToWaitFor = %d, m_curSyncCount = %d",
00102 m_numSyncEventsToWaitFor, m_curSyncCount);
00103
00104 if ((m_numSyncEventsToWaitFor == 0) && (in_numSyncEvents == 0))
00105 {
00106 waitForEvent = false;
00107 }
00108 else
00109 {
00110 if (in_numSyncEvents != 0)
00111 {
00112 if (m_curSyncCount >= in_numSyncEvents)
00113 {
00114 waitForEvent = false;
00115 if (m_curSyncCount > in_numSyncEvents)
00116 {
00117 std::ostringstream tmpStr;
00118 AddFileNameAndLineNumber (tmpStr, in_fileName, in_lineNum);
00119 tmpStr
00120 << "WaitSync-Warning: "
00121 << m_curSyncCount
00122 << " events already arrived, but expected only "
00123 << in_numSyncEvents
00124 << " events";
00125
00126 TRC(TL_ERROR, tmpStr. str().c_str());
00127 assert (m_pIEventReceiver);
00128 m_pIEventReceiver->Event (TestToolBox::CTX_TOO_MANY_EVENTS, tmpStr. str());
00129 }
00130 }
00131 else
00132 {
00133 oldMaxCount = m_numSyncEventsToWaitFor;
00134 m_numSyncEventsToWaitFor = in_numSyncEvents;
00135 restoreMaxCount = true;
00136
00137 TRC(TL_DEBUG, "Temporary setting: m_numSyncEventsToWaitFor = %d",
00138 m_numSyncEventsToWaitFor);
00139 }
00140 }
00141 else
00142 {
00143 if (m_curSyncCount >= m_numSyncEventsToWaitFor)
00144 {
00145 waitForEvent = false;
00146 if (m_curSyncCount > m_numSyncEventsToWaitFor)
00147 {
00148 std::ostringstream tmpStr;
00149 AddFileNameAndLineNumber (tmpStr, in_fileName, in_lineNum);
00150 tmpStr
00151 << "WaitSync-Warning: "
00152 << m_curSyncCount
00153 << " events already arrived, but expected only "
00154 << m_numSyncEventsToWaitFor
00155 << " events";
00156
00157 TRC(TL_ERROR, tmpStr. str().c_str());
00158 assert (m_pIEventReceiver);
00159 m_pIEventReceiver->Event (TestToolBox::CTX_TOO_MANY_EVENTS, tmpStr. str());
00160 }
00161 }
00162 }
00163 }
00164
00165 if (waitForEvent)
00166 {
00167
00168
00169
00170
00171 ResetEvent(m_hSyncEvent);
00172 }
00173
00174 }
00175
00176
00177
00178
00179 DWORD waitStatus;
00180 if (waitForEvent)
00181 {
00182 TRC(TL_DEBUG, "WaitForSingleObject");
00183 waitStatus = WaitForSingleObject(m_hSyncEvent, m_syncTimeoutMs);
00184 }
00185 else
00186 {
00187 TRC(TL_DEBUG, "No WaitForSingleObject necessary, m_curSyncCount = %d", m_curSyncCount);
00188 waitStatus = WAIT_OBJECT_0;
00189 }
00190
00191
00192
00193
00194 {
00195 AutoLock o (this);
00196
00197 if (waitStatus == WAIT_OBJECT_0)
00198 {
00199
00200 m_curSyncCount = 0;
00201 ResetEvent(m_hSyncEvent);
00202 }
00203 else if (waitStatus == WAIT_TIMEOUT)
00204 {
00205 std::ostringstream tmpStr;
00206 AddFileNameAndLineNumber (tmpStr, in_fileName, in_lineNum);
00207 tmpStr
00208 << "WaitSync-Warning: Timeout of "
00209 << m_syncTimeoutMs
00210 << " ms reached! Only "
00211 << m_curSyncCount
00212 << " events of "
00213 << m_numSyncEventsToWaitFor
00214 << " received!";
00215
00216 TRC(TL_ERROR, tmpStr. str().c_str());
00217 assert (m_pIEventReceiver);
00218 m_pIEventReceiver->Event (TestToolBox::CTX_TIMEOUT_ELAPSED, tmpStr. str());
00219
00220 m_curSyncCount = 0;
00221 }
00222 else
00223 {
00224 std::ostringstream tmpStr;
00225 AddFileNameAndLineNumber (tmpStr, in_fileName, in_lineNum);
00226 tmpStr
00227 << "Sync-Error: Wait failed, last error "
00228 << GetLastError();
00229
00230 TRC(TL_ERROR, tmpStr. str().c_str());
00231
00232 assert (m_pIEventReceiver);
00233 m_pIEventReceiver->Event (TestToolBox::CTX_FATAL_ERROR, tmpStr. str());
00234
00235 m_curSyncCount = 0;
00236 }
00237
00238 if (restoreMaxCount)
00239 {
00240 m_numSyncEventsToWaitFor = oldMaxCount;
00241 }
00242
00243 }
00244
00245 TRC(TL_DEBUG, "End");
00246
00247 }
00248
00249
00250
00251
00252
00253
00254 TTB_INLINE void Synchronizer::Sync(
00255 const char* in_fileName,
00256 const long in_lineNum)
00257 {
00258 TRCF("Synchronizer::Sync");
00259 TRC(TL_DEBUG, "Synchronizer::Sync", "Begin");
00260
00261 AutoLock o (this);
00262
00263 m_curSyncCount++;
00264
00265 TRC(TL_DEBUG, "(after lock): m_curSyncCount incremented to %d "
00266 "m_numSyncEventsToWaitFor = %d", m_curSyncCount, m_numSyncEventsToWaitFor);
00267
00268 if (m_curSyncCount == m_numSyncEventsToWaitFor)
00269 {
00270 SetEvent (m_hSyncEvent);
00271 }
00272
00273 if ( (m_curSyncCount > m_numSyncEventsToWaitFor)
00274 && (m_numSyncEventsToWaitFor > 0))
00275 {
00276 std::ostringstream tmpStr;
00277 AddFileNameAndLineNumber (tmpStr, in_fileName, in_lineNum);
00278 tmpStr
00279 << "Sync-Warning: SyncEvent "
00280 << m_curSyncCount
00281 << " generated, but expected a maximum of only "
00282 << m_numSyncEventsToWaitFor
00283 << " events";
00284 TRC(TL_ERROR, tmpStr. str().c_str());
00285 assert (m_pIEventReceiver);
00286 m_pIEventReceiver->Event (TestToolBox::CTX_TOO_MANY_EVENTS, tmpStr. str());
00287 }
00288
00289 TRC(TL_DEBUG, "End");
00290
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 TTB_INLINE Synchronizer::Synchronizer():
00302 m_curSyncCount (0),
00303 m_numSyncEventsToWaitFor (1),
00304 m_syncTimeoutMs (10000),
00305 m_hSyncEvent (0),
00306 m_pIEventReceiver (0)
00307
00308 {
00309 TRCF("Synchronizer::Synchronizer");
00310 TRC(TL_DEBUG, "Synchronizer::Synchronizer", "Constructor");
00311
00312 m_hSyncEvent = ::CreateEvent(
00313 NULL,
00314 TRUE,
00315 FALSE,
00316 NULL);
00317
00318 }
00319
00320
00321
00322
00323
00324
00325 TTB_INLINE Synchronizer::~Synchronizer()
00326 {
00327 TRCF("Synchronizer::~Synchronizer");
00328 TRC(TL_DEBUG, "Destructor");
00329 m_pIEventReceiver = 0;
00330 CloseHandle(m_hSyncEvent);
00331
00332 }
00333
00334
00335
00336
00337
00338 };
00339
00340
00341
00342