Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1417 lines
37 KiB

  1. //***************************************************************************
  2. //
  3. // File:
  4. //
  5. // Module: MS SNMP Provider
  6. //
  7. // Purpose:
  8. //
  9. // Copyright (c) 1997-2003 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. #include <provexpt.h>
  14. #include <snmptempl.h>
  15. #include <snmpmt.h>
  16. #include <typeinfo.h>
  17. #include <process.h>
  18. #include <objbase.h>
  19. #include <stdio.h>
  20. #include <snmpcont.h>
  21. #include "snmpevt.h"
  22. #include "snmpthrd.h"
  23. #include "snmplog.h"
  24. CCriticalSection SnmpThreadObject :: s_Lock ;
  25. LONG SnmpThreadObject :: s_ReferenceCount = 0 ;
  26. SnmpMap <DWORD,DWORD,SnmpThreadObject *,SnmpThreadObject *> SnmpThreadObject :: s_ThreadContainer ;
  27. typedef ProvOnDelete < CRITICAL_SECTION *, VOID ( * ) ( LPCRITICAL_SECTION ), LeaveCriticalSection > LeaveCriticalSectionScope;
  28. typedef ProvOnDelete < CRITICAL_SECTION *, VOID ( * ) ( LPCRITICAL_SECTION ), DeleteCriticalSection > DeleteCriticalSectionScope;
  29. typedef WaitException < CRITICAL_SECTION *, VOID ( * ) ( LPCRITICAL_SECTION ), EnterCriticalSection, 1000 > EnterCriticalSectionWait;
  30. class SnmpShutdownTaskObject : public SnmpTaskObject
  31. {
  32. private:
  33. SnmpThreadObject* m_ThreadToShutdown ;
  34. protected:
  35. public:
  36. SnmpShutdownTaskObject (SnmpThreadObject* threadToShutdown) ;
  37. void Process () ;
  38. } ;
  39. SnmpShutdownTaskObject :: SnmpShutdownTaskObject (SnmpThreadObject* threadToShutdown)
  40. : m_ThreadToShutdown ( threadToShutdown )
  41. {
  42. }
  43. void SnmpShutdownTaskObject ::Process()
  44. {
  45. if (m_ThreadToShutdown)
  46. {
  47. m_ThreadToShutdown->SignalThreadShutdown();
  48. }
  49. Complete();
  50. }
  51. BOOL SnmpThreadObject :: Startup ()
  52. {
  53. InterlockedIncrement ( & s_ReferenceCount ) ;
  54. return TRUE ;
  55. }
  56. void SnmpThreadObject :: Closedown()
  57. {
  58. #if DBG == 1
  59. if ( s_ReferenceCount == 0 )
  60. {
  61. DebugBreak ();
  62. }
  63. #endif
  64. if ( InterlockedDecrement ( & s_ReferenceCount ) <= 0 )
  65. ProcessDetach () ;
  66. }
  67. void SnmpThreadObject :: ProcessAttach ()
  68. {
  69. }
  70. void SnmpThreadObject :: ProcessDetach ( BOOL a_ProcessDetaching )
  71. {
  72. // delete all known thread objects
  73. EnterCriticalSectionWait ecs ( s_Lock ) ;
  74. POSITION t_Position = s_ThreadContainer.GetStartPosition () ;
  75. while ( t_Position )
  76. {
  77. DWORD t_EventId ;
  78. SnmpThreadObject *t_ThreadObject ;
  79. s_ThreadContainer.GetNextAssoc ( t_Position , t_EventId , t_ThreadObject ) ;
  80. s_Lock.Unlock () ;
  81. t_ThreadObject->SignalThreadShutdown () ;
  82. EnterCriticalSectionWait ecs ( s_Lock ) ;
  83. t_Position = s_ThreadContainer.GetStartPosition () ;
  84. }
  85. s_ThreadContainer.RemoveAll () ;
  86. s_Lock.Unlock () ;
  87. }
  88. void __cdecl SnmpThreadObject :: ThreadExecutionProcedure ( void *a_ThreadParameter )
  89. {
  90. SetStructuredExceptionHandler seh;
  91. try
  92. {
  93. SnmpThreadObject *t_ThreadObject = ( SnmpThreadObject * ) a_ThreadParameter ;
  94. BOOL bInitialised = FALSE;
  95. try
  96. {
  97. t_ThreadObject->RegisterThread () ;
  98. t_ThreadObject->Initialise () ;
  99. bInitialised = TRUE;
  100. DebugMacro8(
  101. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n [%S] Thread beginning dispatch" , t_ThreadObject->m_ThreadName ) ;
  102. )
  103. if ( t_ThreadObject->Wait () )
  104. {
  105. }
  106. else
  107. {
  108. }
  109. DebugMacro8(
  110. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n [%S] Thread completed dispatch" , t_ThreadObject->m_ThreadName ) ;
  111. )
  112. t_ThreadObject->Uninitialise () ;
  113. bInitialised = FALSE;
  114. DebugMacro8(
  115. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n Thread terminating" ) ;
  116. )
  117. }
  118. catch(Structured_Exception e_SE)
  119. {
  120. t_ThreadObject->RemoveThread () ;
  121. if ( bInitialised )
  122. {
  123. DebugMacro(
  124. SnmpDebugLog :: s_SnmpDebugLog->Write ( L"\n *** [%S] Thread terminating -> structured exception *** " , t_ThreadObject->m_ThreadName ) ;
  125. )
  126. t_ThreadObject->Uninitialise () ;
  127. }
  128. return;
  129. }
  130. catch(Heap_Exception e_HE)
  131. {
  132. t_ThreadObject->RemoveThread () ;
  133. if ( bInitialised )
  134. {
  135. DebugMacro(
  136. SnmpDebugLog :: s_SnmpDebugLog->Write ( L"\n *** [%S] Thread terminating -> heap exception *** " , t_ThreadObject->m_ThreadName ) ;
  137. )
  138. t_ThreadObject->Uninitialise () ;
  139. }
  140. return;
  141. }
  142. catch(...)
  143. {
  144. t_ThreadObject->RemoveThread () ;
  145. if ( bInitialised )
  146. {
  147. DebugMacro(
  148. SnmpDebugLog :: s_SnmpDebugLog->Write ( L"\n *** [%S] Thread terminating -> exception *** " , t_ThreadObject->m_ThreadName ) ;
  149. )
  150. t_ThreadObject->Uninitialise () ;
  151. }
  152. return;
  153. }
  154. }
  155. catch ( ... )
  156. {
  157. DebugMacro(
  158. SnmpDebugLog :: s_SnmpDebugLog->Write ( L"\n *** Thread terminating -> second chance exception *** " ) ;
  159. )
  160. }
  161. }
  162. void SnmpThreadObject :: TerminateThread ()
  163. {
  164. :: TerminateThread (m_ThreadHandle,0) ;
  165. }
  166. SnmpThreadObject :: SnmpThreadObject (
  167. const char *a_ThreadName,
  168. DWORD a_timeout
  169. ) : m_EventContainer ( NULL ) ,
  170. m_EventContainerLength ( 0 ) ,
  171. m_ThreadId ( 0 ) ,
  172. m_ThreadHandle ( 0 ) ,
  173. m_ThreadName ( NULL ) ,
  174. m_timeout ( a_timeout ),
  175. m_pShutdownTask ( NULL )
  176. {
  177. if ( a_ThreadName )
  178. {
  179. m_ThreadName = _strdup ( a_ThreadName ) ;
  180. if( NULL == m_ThreadName) throw Heap_Exception(Heap_Exception::E_ALLOCATION_ERROR);
  181. }
  182. ConstructEventContainer () ;
  183. }
  184. void SnmpThreadObject :: BeginThread()
  185. {
  186. UINT_PTR t_PseudoHandle = _beginthread (
  187. SnmpThreadObject :: ThreadExecutionProcedure ,
  188. 0 ,
  189. ( void * ) this
  190. ) ;
  191. s_Lock.Lock () ;
  192. LeaveCriticalSectionScope lcs ( s_Lock );
  193. if ( ( HANDLE ) t_PseudoHandle != INVALID_HANDLE_VALUE )
  194. {
  195. BOOL t_Status = DuplicateHandle (
  196. GetCurrentProcess () ,
  197. ( HANDLE ) t_PseudoHandle ,
  198. GetCurrentProcess () ,
  199. GetThreadHandleReference () ,
  200. 0 ,
  201. TRUE ,
  202. DUPLICATE_SAME_ACCESS
  203. ) ;
  204. if ( ! t_Status )
  205. {
  206. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  207. }
  208. }
  209. }
  210. BOOL SnmpThreadObject :: WaitForStartup ()
  211. {
  212. BOOL bResult = FALSE;
  213. SnmpTaskObject t_TaskObject ;
  214. ScheduleTask ( t_TaskObject ) ;
  215. t_TaskObject.Exec () ;
  216. if ( ( bResult = t_TaskObject.Wait () ) == TRUE )
  217. {
  218. bResult = ReapTask ( t_TaskObject ) ;
  219. }
  220. return bResult;
  221. }
  222. SnmpThreadObject :: ~SnmpThreadObject ()
  223. {
  224. DebugMacro8(
  225. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n Enter Thread destructor" ) ;
  226. )
  227. if ( ( m_ThreadId != GetCurrentThreadId () ) && ( m_ThreadId != 0 ))
  228. {
  229. SignalThreadShutdown () ;
  230. }
  231. free ( m_ThreadName ) ;
  232. POSITION t_Position = m_TaskContainer.GetHeadPosition () ;
  233. while ( t_Position )
  234. {
  235. SnmpAbstractTaskObject *t_TaskObject = m_TaskContainer.GetNext ( t_Position ) ;
  236. t_TaskObject->DetachTaskFromThread ( *this ) ;
  237. }
  238. m_TaskContainer.RemoveAll () ;
  239. free ( m_EventContainer ) ;
  240. // we should have task already deleted by SignalThreadShutdown
  241. EnterCriticalSectionWait ecs ( s_Lock );
  242. s_ThreadContainer.RemoveKey ( m_ThreadId ) ;
  243. s_Lock.Unlock () ;
  244. if (m_pShutdownTask != NULL)
  245. {
  246. delete m_pShutdownTask;
  247. }
  248. DebugMacro8(
  249. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n Exit Thread destructor" ) ;
  250. )
  251. }
  252. void SnmpThreadObject :: PostSignalThreadShutdown ()
  253. {
  254. DebugMacro8(
  255. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n Posting thread shutdown" ) ;
  256. )
  257. if (m_pShutdownTask != NULL)
  258. {
  259. DebugMacro8(
  260. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n Thread shutdown previously posted" ) ;
  261. )
  262. }
  263. else
  264. {
  265. m_pShutdownTask = new SnmpShutdownTaskObject(this);
  266. ScheduleTask(*m_pShutdownTask);
  267. m_pShutdownTask->Exec();
  268. DebugMacro8(
  269. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n Thread shutdown posted" ) ;
  270. )
  271. }
  272. }
  273. void SnmpThreadObject :: SignalThreadShutdown ()
  274. {
  275. EnterCriticalSectionWait ecs ( s_Lock ) ;
  276. LeaveCriticalSectionScope lcs ( s_Lock) ;
  277. BOOL t_bRemoved = s_ThreadContainer.RemoveKey ( m_ThreadId ) ;
  278. lcs.Exec ();
  279. if (t_bRemoved)
  280. {
  281. // this should be safe now
  282. if ( m_ThreadId == GetCurrentThreadId () )
  283. {
  284. m_ThreadTerminateEvent.Set () ;
  285. }
  286. else
  287. {
  288. HANDLE t_Handle = m_ThreadHandle ;
  289. m_ThreadTerminateEvent.Set () ;
  290. DWORD t_Event = WaitForSingleObject (
  291. t_Handle ,
  292. INFINITE
  293. ) ;
  294. if ( t_Event != WAIT_OBJECT_0 )
  295. {
  296. DWORD dwError = ERROR_SUCCESS;
  297. dwError = ::GetLastError ();
  298. if ( dwError != ERROR_NOT_ENOUGH_MEMORY )
  299. {
  300. #if DBG == 1
  301. // for testing purpose I will let process break
  302. ::DebugBreak();
  303. #endif
  304. }
  305. while ( ERROR_SUCCESS != dwError )
  306. {
  307. // resources will eventually come back
  308. ::Sleep ( 1000 );
  309. if ( WAIT_OBJECT_0 == WaitForSingleObject (
  310. t_Handle ,
  311. INFINITE
  312. ) )
  313. {
  314. // terminate loop
  315. dwError = ERROR_SUCCESS;
  316. }
  317. }
  318. }
  319. CloseHandle ( t_Handle ) ;
  320. }
  321. }
  322. }
  323. void SnmpThreadObject :: ConstructEventContainer ()
  324. {
  325. DebugMacro8(
  326. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] Constructing Container" , m_ThreadName ) ;
  327. )
  328. EnterCriticalSectionWait ecs ( s_Lock ) ;
  329. LeaveCriticalSectionScope lcs ( s_Lock ) ;
  330. BOOL bAllocated = FALSE;
  331. do
  332. {
  333. ULONG origEventContainerLength = m_EventContainerLength ;
  334. if ( ( m_TaskContainer.GetCount () + 2 ) < MAXIMUM_WAIT_OBJECTS )
  335. {
  336. m_EventContainerLength = m_TaskContainer.GetCount () + 2;
  337. }
  338. else
  339. {
  340. m_EventContainerLength = MAXIMUM_WAIT_OBJECTS - 1;
  341. }
  342. PVOID pNewMem = realloc ( m_EventContainer , sizeof ( HANDLE ) * m_EventContainerLength );
  343. if ( pNewMem == NULL )
  344. {
  345. //
  346. // revert the size back
  347. //
  348. m_EventContainerLength = origEventContainerLength ;
  349. s_Lock.Unlock () ;
  350. // system will eventually come back !
  351. Sleep (60000);
  352. EnterCriticalSectionWait ecs ( s_Lock ) ;
  353. }
  354. else
  355. {
  356. m_EventContainer = ( HANDLE * ) pNewMem;
  357. bAllocated = TRUE;
  358. }
  359. }
  360. while ( ! bAllocated );
  361. m_EventContainer [ 0 ] = GetHandle () ;
  362. m_EventContainer [ 1 ] = m_ThreadTerminateEvent.GetHandle () ;
  363. ULONG t_EventIndex = 2 ;
  364. POSITION t_Position = m_TaskContainer.GetHeadPosition () ;
  365. while ( t_Position && (t_EventIndex < m_EventContainerLength))
  366. {
  367. SnmpAbstractTaskObject *t_TaskObject = m_TaskContainer.GetNext ( t_Position ) ;
  368. m_EventContainer [ t_EventIndex ] = t_TaskObject->GetHandle () ;
  369. t_EventIndex ++ ;
  370. }
  371. }
  372. void SnmpThreadObject :: RotateTask ( SnmpAbstractTaskObject *a_TaskObject )
  373. {
  374. EnterCriticalSectionWait ecs ( s_Lock ) ;
  375. LeaveCriticalSectionScope lcs ( s_Lock );
  376. POSITION t_Position = m_TaskContainer.GetHeadPosition () ;
  377. while ( t_Position )
  378. {
  379. POSITION t_LastPosition = t_Position ;
  380. SnmpAbstractTaskObject *t_TaskObject = m_TaskContainer.GetNext ( t_Position ) ;
  381. if ( a_TaskObject->GetHandle () == t_TaskObject->GetHandle () )
  382. {
  383. m_TaskContainer.RemoveAt ( t_LastPosition ) ;
  384. m_TaskContainer.Add ( t_TaskObject ) ;
  385. break ;
  386. }
  387. }
  388. }
  389. SnmpThreadObject *SnmpThreadObject :: GetThreadObject ()
  390. {
  391. EnterCriticalSectionWait ecs ( s_Lock ) ;
  392. LeaveCriticalSectionScope lcs ( s_Lock );
  393. DWORD t_CurrentThreadId = GetCurrentThreadId () ;
  394. SnmpThreadObject *t_ThreadObject ;
  395. if ( s_ThreadContainer.Lookup ( GetCurrentThreadId () , t_ThreadObject ) )
  396. {
  397. }
  398. else
  399. {
  400. t_ThreadObject = NULL ;
  401. }
  402. return t_ThreadObject ;
  403. }
  404. SnmpAbstractTaskObject *SnmpThreadObject :: GetTaskObject ( HANDLE &a_Handle )
  405. {
  406. EnterCriticalSectionWait ecs ( s_Lock ) ;
  407. LeaveCriticalSectionScope lcs ( s_Lock );
  408. POSITION t_Position = m_TaskContainer.GetHeadPosition () ;
  409. while ( t_Position )
  410. {
  411. SnmpAbstractTaskObject *t_TaskObject = m_TaskContainer.GetNext ( t_Position ) ;
  412. if ( t_TaskObject->GetHandle () == a_Handle )
  413. {
  414. return t_TaskObject ;
  415. }
  416. }
  417. return NULL ;
  418. }
  419. BOOL SnmpThreadObject :: RegisterThread ()
  420. {
  421. EnterCriticalSectionWait ecs ( s_Lock ) ;
  422. LeaveCriticalSectionScope lcs ( s_Lock );
  423. m_ThreadId = GetCurrentThreadId () ;
  424. s_ThreadContainer [ m_ThreadId ] = this ;
  425. BOOL t_Status = TRUE;
  426. DebugMacro8(
  427. wchar_t buffer [ 1025 ] ;
  428. wsprintf ( buffer , L"\nThread [%S] = %lx, with thread id = %lx" , m_ThreadName , this , m_ThreadId ) ;
  429. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, buffer ) ;
  430. )
  431. return t_Status ;
  432. }
  433. BOOL SnmpThreadObject :: RemoveThread ()
  434. {
  435. EnterCriticalSectionWait ecs ( s_Lock ) ;
  436. LeaveCriticalSectionScope lcs ( s_Lock );
  437. BOOL t_Status = s_ThreadContainer.RemoveKey ( m_ThreadId ) ;
  438. if ( t_Status )
  439. {
  440. DebugMacro8(
  441. wchar_t buffer [ 1025 ] ;
  442. wsprintf ( buffer , L"\nThread [%S] = %lx, with thread id = %lx was removed from container" , m_ThreadName , (UINT_PTR)this , m_ThreadId ) ;
  443. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, buffer ) ;
  444. )
  445. }
  446. else
  447. {
  448. DebugMacro8(
  449. wchar_t buffer [ 1025 ] ;
  450. wsprintf ( buffer , L"\nThread [%S] = %lx, with thread id = %lx failed to remove from container" , m_ThreadName , (UINT_PTR)this , m_ThreadId ) ;
  451. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, buffer ) ;
  452. )
  453. }
  454. return t_Status ;
  455. }
  456. void SnmpThreadObject :: Process ()
  457. {
  458. EnterCriticalSectionWait ecs ( s_Lock ) ;
  459. LeaveCriticalSectionScope lcs ( s_Lock );
  460. POSITION t_Position = m_ScheduleReapEventContainer.GetStartPosition () ;
  461. while ( t_Position )
  462. {
  463. HANDLE t_EventId ;
  464. SnmpEventObject *t_Event ;
  465. m_ScheduleReapEventContainer.GetNextAssoc ( t_Position , t_EventId , t_Event) ;
  466. DebugMacro8(
  467. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] Thread Process [%lx]" , m_ThreadName , t_EventId);
  468. )
  469. t_Event->Set () ;
  470. }
  471. }
  472. BOOL SnmpThreadObject :: WaitDispatch ( ULONG t_HandleIndex , BOOL &a_Terminated )
  473. {
  474. BOOL t_Status = TRUE ;
  475. HANDLE t_Handle = m_EventContainer [ t_HandleIndex ] ;
  476. if ( t_Handle == GetHandle () )
  477. {
  478. // Task has been scheduled so we must update arrays
  479. DebugMacro8(
  480. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] Thread Wait: Refreshing handles" , m_ThreadName );
  481. )
  482. Process () ;
  483. ConstructEventContainer () ;
  484. }
  485. else if ( t_Handle == m_ThreadTerminateEvent.GetHandle () )
  486. {
  487. // thread has been told to close down
  488. a_Terminated = TRUE ;
  489. m_ThreadTerminateEvent.Process () ;
  490. DebugMacro8(
  491. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] Someone t_Terminated" , m_ThreadName ) ;
  492. )
  493. }
  494. else
  495. {
  496. DebugMacro8(
  497. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] Thread Wait: Processing Task" , m_ThreadName );
  498. )
  499. SnmpAbstractTaskObject *t_TaskObject = GetTaskObject ( t_Handle ) ;
  500. if ( t_TaskObject )
  501. {
  502. RotateTask ( t_TaskObject ) ;
  503. ConstructEventContainer () ;
  504. t_TaskObject->Process () ;
  505. }
  506. else
  507. {
  508. DebugMacro8(
  509. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] Couldn't Find Task Object" , m_ThreadName ) ;
  510. )
  511. t_Status = FALSE ;
  512. }
  513. }
  514. return t_Status ;
  515. }
  516. BOOL SnmpThreadObject :: Wait ()
  517. {
  518. BOOL t_Status = TRUE ;
  519. BOOL t_Terminated = FALSE ;
  520. while ( t_Status && ! t_Terminated )
  521. {
  522. DWORD t_Event = MsgWaitForMultipleObjects (
  523. m_EventContainerLength ,
  524. m_EventContainer ,
  525. FALSE ,
  526. m_timeout ,
  527. QS_ALLINPUT
  528. ) ;
  529. ULONG t_HandleIndex = t_Event - WAIT_OBJECT_0 ;
  530. if ( t_Event == 0xFFFFFFFF )
  531. {
  532. DWORD t_Error = GetLastError () ;
  533. DebugMacro8(
  534. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] Handle problem" , m_ThreadName ) ;
  535. )
  536. t_Status = FALSE ;
  537. }
  538. else if ( t_Event == WAIT_TIMEOUT)
  539. {
  540. TimedOut();
  541. }
  542. else if ( t_HandleIndex <= m_EventContainerLength )
  543. {
  544. // Go into dispatch loop
  545. if ( t_HandleIndex == m_EventContainerLength )
  546. {
  547. BOOL t_DispatchStatus ;
  548. MSG t_Msg ;
  549. while ( ( t_DispatchStatus = PeekMessage ( & t_Msg , NULL , 0 , 0 , PM_NOREMOVE ) ) == TRUE )
  550. {
  551. int t_Result = 0;
  552. t_Result = GetMessage ( & t_Msg , NULL , 0 , 0 );
  553. if ( t_Result != 0 && t_Result != -1 )
  554. {
  555. TranslateMessage ( & t_Msg ) ;
  556. DispatchMessage ( & t_Msg ) ;
  557. }
  558. BOOL t_Timeout = FALSE ;
  559. while ( ! t_Timeout && t_Status && ! t_Terminated )
  560. {
  561. t_Event = WaitForMultipleObjects (
  562. m_EventContainerLength ,
  563. m_EventContainer ,
  564. FALSE ,
  565. 0
  566. ) ;
  567. t_HandleIndex = t_Event - WAIT_OBJECT_0 ;
  568. if ( t_Event == 0xFFFFFFFF )
  569. {
  570. DWORD t_Error = GetLastError () ;
  571. DebugMacro8(
  572. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] Handle problem" , m_ThreadName ) ;
  573. )
  574. t_Status = FALSE ;
  575. }
  576. else if ( t_Event == WAIT_TIMEOUT)
  577. {
  578. t_Timeout = TRUE ;
  579. }
  580. else if ( t_HandleIndex < m_EventContainerLength )
  581. {
  582. t_Status = WaitDispatch ( t_HandleIndex , t_Terminated ) ;
  583. }
  584. else
  585. {
  586. DebugMacro8(
  587. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] Unknown handle index" , m_ThreadName ) ;
  588. )
  589. t_Status = FALSE ;
  590. }
  591. }
  592. }
  593. }
  594. else if ( t_HandleIndex < m_EventContainerLength )
  595. {
  596. t_Status = WaitDispatch ( t_HandleIndex , t_Terminated ) ;
  597. }
  598. else
  599. {
  600. DebugMacro8(
  601. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] Unknown handle index" , m_ThreadName ) ;
  602. )
  603. t_Status = FALSE ;
  604. }
  605. }
  606. }
  607. return t_Status ;
  608. }
  609. ULONG SnmpThreadObject :: GetEventHandlesSize ()
  610. {
  611. return m_EventContainerLength ;
  612. }
  613. HANDLE *SnmpThreadObject :: GetEventHandles ()
  614. {
  615. return m_EventContainer ;
  616. }
  617. BOOL SnmpThreadObject :: ScheduleTask ( SnmpAbstractTaskObject &a_TaskObject )
  618. {
  619. BOOL t_Result = TRUE ;
  620. EnterCriticalSectionWait ecs ( s_Lock ) ;
  621. /*
  622. * Add Synchronous object to worker thread container
  623. */
  624. a_TaskObject.m_ScheduledHandle = a_TaskObject.GetHandle ();
  625. m_TaskContainer.Add ( &a_TaskObject ) ;
  626. s_Lock.Unlock () ;
  627. a_TaskObject.AttachTaskToThread ( *this ) ;
  628. if ( GetCurrentThreadId () != m_ThreadId )
  629. {
  630. #if 0
  631. SnmpEventObject t_ScheduledEventObject ;
  632. EnterCriticalSectionWait ecs1 ( s_Lock ) ;
  633. m_ScheduleReapEventContainer [ t_ScheduledEventObject.GetHandle () ] = &t_ScheduledEventObject ;
  634. s_Lock.Unlock () ;
  635. DebugMacro8(
  636. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] ScheduleTask: Setting update" , m_ThreadName );
  637. )
  638. Set () ;
  639. DebugMacro8(
  640. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] ScheduleTask: Beginning Wait" , m_ThreadName );
  641. )
  642. if ( t_ScheduledEventObject.Wait () )
  643. {
  644. }
  645. else
  646. {
  647. t_Result = FALSE ;
  648. }
  649. DebugMacro8(
  650. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] ScheduleTask: Ended Wait" , m_ThreadName );
  651. )
  652. EnterCriticalSectionWait ecs2 ( s_Lock ) ;
  653. m_ScheduleReapEventContainer.RemoveKey ( t_ScheduledEventObject.GetHandle () ) ;
  654. s_Lock.Unlock () ;
  655. #else
  656. Set () ;
  657. #endif
  658. }
  659. else
  660. {
  661. ConstructEventContainer () ;
  662. }
  663. return t_Result ;
  664. }
  665. BOOL SnmpThreadObject :: ReapTask ( SnmpAbstractTaskObject &a_TaskObject )
  666. {
  667. DebugMacro8(
  668. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] Entering ReapTask [%lx]" , m_ThreadName , a_TaskObject.m_ScheduledHandle );
  669. )
  670. BOOL t_Result = TRUE ;
  671. EnterCriticalSectionWait ecs ( s_Lock ) ;
  672. /*
  673. * Remove worker object from worker thread container
  674. */
  675. POSITION t_Position = m_TaskContainer.GetHeadPosition () ;
  676. while ( t_Position )
  677. {
  678. POSITION t_LastPosition = t_Position ;
  679. SnmpAbstractTaskObject *t_TaskObject = m_TaskContainer.GetNext ( t_Position ) ;
  680. if ( a_TaskObject.m_ScheduledHandle == t_TaskObject->m_ScheduledHandle )
  681. {
  682. m_TaskContainer.RemoveAt ( t_LastPosition ) ;
  683. break ;
  684. }
  685. }
  686. s_Lock.Unlock () ;
  687. /*
  688. * Inform worker thread,thread container has been updated.
  689. */
  690. if ( GetCurrentThreadId () != m_ThreadId )
  691. {
  692. SnmpEventObject t_ReapedEventObject ;
  693. EnterCriticalSectionWait ecs1 ( s_Lock ) ;
  694. m_ScheduleReapEventContainer [ t_ReapedEventObject.GetHandle () ] = &t_ReapedEventObject ;
  695. s_Lock.Unlock () ;
  696. DebugMacro8(
  697. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] ReapTask: Setting update" , m_ThreadName );
  698. )
  699. Set () ;
  700. DebugMacro8(
  701. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] ReapTask: Beginning Wait on [%lx]" , m_ThreadName , t_ReapedEventObject.GetHandle () );
  702. )
  703. if ( t_ReapedEventObject.Wait () )
  704. {
  705. }
  706. else
  707. {
  708. t_Result = FALSE ;
  709. }
  710. DebugMacro8(
  711. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] ReapTask: Ended Wait" , m_ThreadName );
  712. )
  713. EnterCriticalSectionWait ecs2 ( s_Lock ) ;
  714. m_ScheduleReapEventContainer.RemoveKey ( t_ReapedEventObject.GetHandle () ) ;
  715. s_Lock.Unlock () ;
  716. }
  717. else
  718. {
  719. DebugMacro8(
  720. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] ReapTask: ConstructEventContainer" , m_ThreadName );
  721. )
  722. ConstructEventContainer () ;
  723. }
  724. DebugMacro8(
  725. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\n[%S] Returning from ReapTask [%lx]" , m_ThreadName , a_TaskObject.m_ScheduledHandle );
  726. )
  727. a_TaskObject.DetachTaskFromThread ( *this ) ;
  728. return t_Result ;
  729. }
  730. SnmpAbstractTaskObject :: SnmpAbstractTaskObject (
  731. const wchar_t *a_GlobalTaskNameComplete,
  732. const wchar_t *a_GlobalTaskNameAcknowledgement,
  733. DWORD a_timeout
  734. ) : m_CompletionEvent ( a_GlobalTaskNameComplete ) ,
  735. m_AcknowledgementEvent ( a_GlobalTaskNameAcknowledgement ) ,
  736. m_timeout ( a_timeout ),
  737. m_ScheduledHandle (NULL)
  738. {
  739. }
  740. SnmpAbstractTaskObject :: ~SnmpAbstractTaskObject ()
  741. {
  742. DebugMacro8(
  743. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nSnmpAbstractTaskObject :: ~SnmpAbstractTaskObject () [%lx]" , m_ScheduledHandle ) ;
  744. )
  745. EnterCriticalSectionWait ecs ( m_Lock ) ;
  746. LeaveCriticalSectionScope lcs ( m_Lock );
  747. if (NULL != m_ScheduledHandle)
  748. {
  749. POSITION t_Position = m_ThreadContainer.GetStartPosition () ;
  750. while ( t_Position )
  751. {
  752. DWORD t_ThreadId ;
  753. SnmpThreadObject *t_ThreadObject ;
  754. m_ThreadContainer.GetNextAssoc ( t_Position , t_ThreadId , t_ThreadObject ) ;
  755. t_ThreadObject->ReapTask ( *this ) ;
  756. }
  757. }
  758. m_ThreadContainer.RemoveAll () ;
  759. }
  760. void SnmpAbstractTaskObject :: DetachTaskFromThread ( SnmpThreadObject &a_ThreadObject )
  761. {
  762. EnterCriticalSectionWait ecs ( m_Lock ) ;
  763. LeaveCriticalSectionScope lcs ( m_Lock );
  764. m_ThreadContainer.RemoveKey ( a_ThreadObject.GetThreadId () ) ;
  765. }
  766. void SnmpAbstractTaskObject :: AttachTaskToThread ( SnmpThreadObject &a_ThreadObject )
  767. {
  768. EnterCriticalSectionWait ecs ( m_Lock ) ;
  769. LeaveCriticalSectionScope lcs ( m_Lock );
  770. m_ThreadContainer [ a_ThreadObject.GetThreadId () ] = &a_ThreadObject ;
  771. }
  772. BOOL SnmpAbstractTaskObject :: Wait ( BOOL a_Dispatch )
  773. {
  774. BOOL t_Status = TRUE ;
  775. BOOL t_Processed = FALSE ;
  776. while ( t_Status && ! t_Processed )
  777. {
  778. SnmpThreadObject *t_ThreadObject = SnmpThreadObject :: GetThreadObject () ;
  779. ULONG t_TaskEventArrayLength = 0 ;
  780. HANDLE *t_TaskEventArray = NULL ;
  781. if ( t_ThreadObject && a_Dispatch )
  782. {
  783. ULONG t_TaskArrayLength = t_ThreadObject->GetEventHandlesSize () ;
  784. t_TaskEventArrayLength = t_TaskArrayLength + 1 ;
  785. t_TaskEventArray = new HANDLE [ t_TaskEventArrayLength ] ;
  786. if ( t_TaskEventArray )
  787. {
  788. t_TaskEventArray [ 0 ] = m_CompletionEvent.GetHandle () ;
  789. memcpy (
  790. & ( t_TaskEventArray [ 1 ] ) ,
  791. t_ThreadObject->GetEventHandles () ,
  792. t_TaskArrayLength * sizeof ( HANDLE )
  793. ) ;
  794. }
  795. else
  796. {
  797. return FALSE;
  798. }
  799. }
  800. else
  801. {
  802. t_TaskEventArrayLength = 1 ;
  803. t_TaskEventArray = new HANDLE [ t_TaskEventArrayLength ] ;
  804. t_TaskEventArray [ 0 ] = m_CompletionEvent.GetHandle () ;
  805. }
  806. DWORD t_Event ;
  807. if ( a_Dispatch )
  808. {
  809. t_Event = MsgWaitForMultipleObjects (
  810. t_TaskEventArrayLength ,
  811. t_TaskEventArray ,
  812. FALSE ,
  813. m_timeout ,
  814. QS_ALLINPUT
  815. ) ;
  816. }
  817. else
  818. {
  819. t_Event = WaitForMultipleObjects (
  820. t_TaskEventArrayLength ,
  821. t_TaskEventArray ,
  822. FALSE ,
  823. m_timeout
  824. ) ;
  825. }
  826. ULONG t_HandleIndex = t_Event - WAIT_OBJECT_0 ;
  827. if ( t_Event == 0xFFFFFFFF )
  828. {
  829. DebugMacro8(
  830. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nSnmpAbstractTaskObject :: Illegal Handle" ) ;
  831. )
  832. DWORD t_Error = GetLastError () ;
  833. t_Status = FALSE ;
  834. }
  835. else if ( t_Event == WAIT_TIMEOUT)
  836. {
  837. TimedOut();
  838. }
  839. else if ( t_HandleIndex == t_TaskEventArrayLength )
  840. {
  841. BOOL t_DispatchStatus ;
  842. MSG t_Msg ;
  843. while ( ( t_DispatchStatus = PeekMessage ( & t_Msg , NULL , 0 , 0 , PM_NOREMOVE ) ) == TRUE )
  844. {
  845. int t_Result = 0;
  846. t_Result = GetMessage ( & t_Msg , NULL , 0 , 0 );
  847. if ( t_Result != 0 && t_Result != -1 )
  848. {
  849. TranslateMessage ( & t_Msg ) ;
  850. DispatchMessage ( & t_Msg ) ;
  851. }
  852. BOOL t_Timeout = FALSE ;
  853. while ( ! t_Timeout && t_Status && ! t_Processed )
  854. {
  855. t_Event = WaitForMultipleObjects (
  856. t_TaskEventArrayLength ,
  857. t_TaskEventArray ,
  858. FALSE ,
  859. 0
  860. ) ;
  861. t_HandleIndex = t_Event - WAIT_OBJECT_0 ;
  862. if ( t_Event == 0xFFFFFFFF )
  863. {
  864. DebugMacro8(
  865. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nSnmpAbstractTaskObject :: Illegal Handle" ) ;
  866. )
  867. DWORD t_Error = GetLastError () ;
  868. t_Status = FALSE ;
  869. }
  870. else if ( t_Event == WAIT_TIMEOUT)
  871. {
  872. t_Timeout = TRUE ;
  873. }
  874. else if ( t_HandleIndex < t_TaskEventArrayLength )
  875. {
  876. HANDLE t_Handle = t_TaskEventArray [ t_HandleIndex ] ;
  877. t_Status = WaitDispatch ( t_ThreadObject , t_Handle , t_Processed ) ;
  878. }
  879. else
  880. {
  881. DebugMacro8(
  882. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nSnmpAbstractTaskObject :: Illegal Handle index" ) ;
  883. )
  884. t_Status = FALSE ;
  885. }
  886. }
  887. }
  888. }
  889. else if ( t_HandleIndex < t_TaskEventArrayLength )
  890. {
  891. HANDLE t_Handle = t_TaskEventArray [ t_HandleIndex ] ;
  892. t_Status = WaitDispatch ( t_ThreadObject , t_Handle , t_Processed ) ;
  893. }
  894. else
  895. {
  896. DebugMacro8(
  897. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nSnmpAbstractTaskObject :: Illegal Handle index" ) ;
  898. )
  899. t_Status = FALSE ;
  900. }
  901. delete [] t_TaskEventArray ;
  902. }
  903. return t_Status ;
  904. }
  905. BOOL SnmpAbstractTaskObject :: WaitDispatch ( SnmpThreadObject *a_ThreadObject, HANDLE a_Handle , BOOL &a_Processed )
  906. {
  907. BOOL t_Status = TRUE ;
  908. if ( a_Handle == m_CompletionEvent.GetHandle () )
  909. {
  910. DebugMacro8(
  911. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nWait: Completed" );
  912. )
  913. m_CompletionEvent.Process () ;
  914. a_Processed = TRUE ;
  915. }
  916. else if ( a_ThreadObject && ( a_Handle == a_ThreadObject->GetHandle () ) )
  917. {
  918. DebugMacro8(
  919. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nTask Wait: Refreshing handles" );
  920. )
  921. a_ThreadObject->Process () ;
  922. a_ThreadObject->ConstructEventContainer () ;
  923. }
  924. else
  925. {
  926. SnmpAbstractTaskObject *t_TaskObject = a_ThreadObject->GetTaskObject ( a_Handle ) ;
  927. if ( t_TaskObject )
  928. {
  929. a_ThreadObject->RotateTask ( t_TaskObject ) ;
  930. a_ThreadObject->ConstructEventContainer () ;
  931. t_TaskObject->Process () ;
  932. }
  933. else
  934. {
  935. DebugMacro8(
  936. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nSnmpAbstractTaskObject :: Illegal Task" ) ;
  937. )
  938. t_Status = FALSE ;
  939. }
  940. }
  941. return t_Status ;
  942. }
  943. BOOL SnmpAbstractTaskObject :: WaitAcknowledgement ( BOOL a_Dispatch )
  944. {
  945. BOOL t_Status = TRUE ;
  946. BOOL t_Processed = FALSE ;
  947. while ( t_Status && ! t_Processed )
  948. {
  949. SnmpThreadObject *t_ThreadObject = SnmpThreadObject :: GetThreadObject () ;
  950. ULONG t_TaskEventArrayLength = 0 ;
  951. HANDLE *t_TaskEventArray = NULL ;
  952. if ( t_ThreadObject && a_Dispatch )
  953. {
  954. ULONG t_TaskArrayLength = t_ThreadObject->GetEventHandlesSize () ;
  955. t_TaskEventArrayLength = t_TaskArrayLength + 1 ;
  956. t_TaskEventArray = new HANDLE [ t_TaskEventArrayLength ] ;
  957. if ( t_TaskArrayLength )
  958. {
  959. memcpy (
  960. & ( t_TaskEventArray [ 1 ] ) ,
  961. t_ThreadObject->GetEventHandles () ,
  962. t_TaskArrayLength * sizeof ( HANDLE )
  963. ) ;
  964. }
  965. t_TaskEventArray [ 0 ] = m_AcknowledgementEvent.GetHandle () ;
  966. }
  967. else
  968. {
  969. t_TaskEventArrayLength = 1 ;
  970. t_TaskEventArray = new HANDLE [ t_TaskEventArrayLength ] ;
  971. t_TaskEventArray [ 0 ] = m_AcknowledgementEvent.GetHandle () ;
  972. }
  973. DWORD t_Event ;
  974. if ( a_Dispatch )
  975. {
  976. t_Event = MsgWaitForMultipleObjects (
  977. t_TaskEventArrayLength ,
  978. t_TaskEventArray ,
  979. FALSE ,
  980. m_timeout ,
  981. QS_ALLINPUT
  982. ) ;
  983. }
  984. else
  985. {
  986. t_Event = WaitForMultipleObjects (
  987. t_TaskEventArrayLength ,
  988. t_TaskEventArray ,
  989. FALSE ,
  990. m_timeout
  991. ) ;
  992. }
  993. ULONG t_HandleIndex = t_Event - WAIT_OBJECT_0 ;
  994. if ( t_Event == 0xFFFFFFFF )
  995. {
  996. DebugMacro8(
  997. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nSnmpAbstractTaskObject :: Illegal Handle" ) ;
  998. )
  999. DWORD t_Error = GetLastError () ;
  1000. t_Status = FALSE ;
  1001. }
  1002. else if ( t_Event == WAIT_TIMEOUT)
  1003. {
  1004. TimedOut();
  1005. }
  1006. if ( t_HandleIndex == t_TaskEventArrayLength )
  1007. {
  1008. BOOL t_DispatchStatus ;
  1009. MSG t_Msg ;
  1010. while ( ( t_DispatchStatus = PeekMessage ( & t_Msg , NULL , 0 , 0 , PM_NOREMOVE ) ) == TRUE )
  1011. {
  1012. int t_Result = 0;
  1013. t_Result = GetMessage ( & t_Msg , NULL , 0 , 0 );
  1014. if ( t_Result != 0 && t_Result != -1 )
  1015. {
  1016. TranslateMessage ( & t_Msg ) ;
  1017. DispatchMessage ( & t_Msg ) ;
  1018. }
  1019. BOOL t_Timeout = FALSE ;
  1020. while ( ! t_Timeout && t_Status && ! t_Processed )
  1021. {
  1022. t_Event = WaitForMultipleObjects (
  1023. t_TaskEventArrayLength ,
  1024. t_TaskEventArray ,
  1025. FALSE ,
  1026. 0
  1027. ) ;
  1028. ULONG t_HandleIndex = t_Event - WAIT_OBJECT_0 ;
  1029. if ( t_Event == 0xFFFFFFFF )
  1030. {
  1031. DebugMacro8(
  1032. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nSnmpAbstractTaskObject :: Illegal Handle" ) ;
  1033. )
  1034. DWORD t_Error = GetLastError () ;
  1035. t_Status = FALSE ;
  1036. }
  1037. else if ( t_Event == WAIT_TIMEOUT)
  1038. {
  1039. t_Timeout = TRUE ;
  1040. }
  1041. else if ( t_HandleIndex < t_TaskEventArrayLength )
  1042. {
  1043. HANDLE t_Handle = t_TaskEventArray [ t_HandleIndex ] ;
  1044. t_Status = WaitAcknowledgementDispatch ( t_ThreadObject , t_Handle , t_Processed ) ;
  1045. }
  1046. else
  1047. {
  1048. DebugMacro8(
  1049. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nSnmpAbstractTaskObject :: Illegal Handle index" ) ;
  1050. )
  1051. t_Status = FALSE ;
  1052. }
  1053. }
  1054. }
  1055. }
  1056. else if ( t_HandleIndex < t_TaskEventArrayLength )
  1057. {
  1058. HANDLE t_Handle = t_TaskEventArray [ t_HandleIndex ] ;
  1059. t_Status = WaitAcknowledgementDispatch ( t_ThreadObject , t_Handle , t_Processed ) ;
  1060. }
  1061. else
  1062. {
  1063. DebugMacro8(
  1064. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nSnmpAbstractTaskObject :: Illegal Handle index" ) ;
  1065. )
  1066. t_Status = FALSE ;
  1067. }
  1068. delete [] t_TaskEventArray ;
  1069. }
  1070. return t_Status ;
  1071. }
  1072. BOOL SnmpAbstractTaskObject :: WaitAcknowledgementDispatch ( SnmpThreadObject *a_ThreadObject , HANDLE a_Handle , BOOL &a_Processed )
  1073. {
  1074. BOOL t_Status = TRUE ;
  1075. if ( a_Handle == m_AcknowledgementEvent.GetHandle () )
  1076. {
  1077. DebugMacro8(
  1078. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nWait: Completed" );
  1079. )
  1080. m_AcknowledgementEvent.Process () ;
  1081. a_Processed = TRUE ;
  1082. }
  1083. else if ( a_ThreadObject && ( a_Handle == a_ThreadObject->GetHandle () ) )
  1084. {
  1085. DebugMacro8(
  1086. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nTask Wait: Refreshing handles" );
  1087. )
  1088. a_ThreadObject->Process () ;
  1089. a_ThreadObject->ConstructEventContainer () ;
  1090. }
  1091. else
  1092. {
  1093. SnmpAbstractTaskObject *t_TaskObject = a_ThreadObject->GetTaskObject ( a_Handle ) ;
  1094. if ( t_TaskObject )
  1095. {
  1096. a_ThreadObject->RotateTask ( t_TaskObject ) ;
  1097. a_ThreadObject->ConstructEventContainer () ;
  1098. t_TaskObject->Process () ;
  1099. }
  1100. else
  1101. {
  1102. DebugMacro8(
  1103. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine ( __FILE__,__LINE__, L"\nSnmpAbstractTaskObject :: Illegal Task" ) ;
  1104. )
  1105. t_Status = FALSE ;
  1106. }
  1107. }
  1108. return t_Status ;
  1109. }
  1110. SnmpTaskObject::SnmpTaskObject (
  1111. const wchar_t *a_GlobalTaskNameStart,
  1112. const wchar_t *a_GlobalTaskNameComplete ,
  1113. const wchar_t *a_GlobalTaskNameAcknowledge,
  1114. DWORD a_timeout
  1115. ): SnmpAbstractTaskObject(a_GlobalTaskNameComplete, a_GlobalTaskNameAcknowledge,a_timeout), m_Event(a_GlobalTaskNameStart)
  1116. {
  1117. }