diff options
-rw-r--r-- | ACE/ace/WFMO_Reactor.cpp | 54 | ||||
-rw-r--r-- | ACE/ace/WFMO_Reactor.h | 4 |
2 files changed, 46 insertions, 12 deletions
diff --git a/ACE/ace/WFMO_Reactor.cpp b/ACE/ace/WFMO_Reactor.cpp index 75285669489..a519c607108 100644 --- a/ACE/ace/WFMO_Reactor.cpp +++ b/ACE/ace/WFMO_Reactor.cpp @@ -1753,13 +1753,50 @@ ACE_WFMO_Reactor::ok_to_wait (ACE_Time_Value *max_wait_time, // Note: There is really no need to involve the <timer_queue_> here // because even if a timeout in the <timer_queue_> does expire we // will not be able to dispatch it - int timeout = max_wait_time == 0 ? INFINITE : max_wait_time->msec (); - // Atomically wait for both the <lock_> and <ok_to_wait_> event + // We need to wait for both the <lock_> and <ok_to_wait_> event. + // If not on WinCE, use WaitForMultipleObjects() to wait for both atomically. + // On WinCE, the waitAll arg to WFMO must be false, so wait for the + // ok_to_wait_ event first (since that's likely to take the longest) then + // grab the lock and recheck the ok_to_wait_ event. When we can get them + // both, or there's an error/timeout, return. +#if defined (ACE_HAS_WINCE) + ACE_Time_Value timeout = ACE_OS::gettimeofday (); + if (max_wait_time != 0) + timeout += *max_wait_time; + while (1) + { + int status; + if (max_wait_time == 0) + status = this->ok_to_wait_.wait (); + else + status = this->ok_to_wait_.wait (&timeout); + if (status == -1) + return -1; + // The event is signaled, so it's ok to wait; grab the lock and + // recheck the event. If something has changed, restart the wait. + if (max_wait_time == 0) + status = this->lock_.acquire (); + else + status = this->lock_.acquire (timeout); + if (status == -1) + return -1; + + // Have the lock_, now re-check the event. If it's not signaled, + // another thread changed something so go back and wait again. + ACE_Time_Value poll_it = ACE_OS::gettimeofday (); + if (this->ok_to_wait_.wait (&poll_it) == 0) + break; + this->lock_.release (); + } + return 1; + +#else + int timeout = max_wait_time == 0 ? INFINITE : max_wait_time->msec (); DWORD result = 0; while (1) { -#if defined (ACE_HAS_PHARLAP) +# if defined (ACE_HAS_PHARLAP) // PharLap doesn't implement WaitForMultipleObjectsEx, and doesn't // do async I/O, so it's not needed in this case anyway. result = ::WaitForMultipleObjects (sizeof this->atomic_wait_array_ / sizeof (ACE_HANDLE), @@ -1770,13 +1807,7 @@ ACE_WFMO_Reactor::ok_to_wait (ACE_Time_Value *max_wait_time, if (result != WAIT_IO_COMPLETION) break; -#elif defined (ACE_HAS_WINCE) - result = ::WaitForMultipleObjects (sizeof this->atomic_wait_array_ / sizeof (ACE_HANDLE), - this->atomic_wait_array_, - FALSE, // Must be FALSE on WinCE - timeout); - break; // CE does not have WAIT_IO_COMPLETION defined. -#else +# else result = ::WaitForMultipleObjectsEx (sizeof this->atomic_wait_array_ / sizeof (ACE_HANDLE), this->atomic_wait_array_, TRUE, @@ -1786,7 +1817,7 @@ ACE_WFMO_Reactor::ok_to_wait (ACE_Time_Value *max_wait_time, if (result != WAIT_IO_COMPLETION) break; -#endif /* ACE_HAS_PHARLAP */ +# endif /* ACE_HAS_PHARLAP */ } switch (result) @@ -1804,6 +1835,7 @@ ACE_WFMO_Reactor::ok_to_wait (ACE_Time_Value *max_wait_time, // It is ok to enter ::WaitForMultipleObjects return 1; +#endif /* ACE_HAS_WINCE */ } DWORD diff --git a/ACE/ace/WFMO_Reactor.h b/ACE/ace/WFMO_Reactor.h index 2c8f2bec20d..c06306cb7c1 100644 --- a/ACE/ace/WFMO_Reactor.h +++ b/ACE/ace/WFMO_Reactor.h @@ -1188,7 +1188,9 @@ protected: /// Return the ID of the "owner" thread. Does not do any locking. virtual ACE_thread_t owner_i (void); - /// Check to see if it is ok to enter <::WaitForMultipleObjects>. + /// Wait up to @a max_wait_time until it's ok to enter + /// WaitForMultipleObjects. Returns 1 (and holding lock_) if ok to wait; + /// -1 (and not holding lock_) if not. virtual int ok_to_wait (ACE_Time_Value *max_wait_time, int alertable); |