| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 | 
							- ///////////////////////////////////////////////////////////////////////////////
 
- // Name:        wx/msqqueue.h
 
- // Purpose:     Message queues for inter-thread communication
 
- // Author:      Evgeniy Tarassov
 
- // Created:     2007-10-31
 
- // Copyright:   (C) 2007 TT-Solutions SARL
 
- // Licence:     wxWindows licence
 
- ///////////////////////////////////////////////////////////////////////////////
 
- #ifndef _WX_MSGQUEUE_H_
 
- #define _WX_MSGQUEUE_H_
 
- // ----------------------------------------------------------------------------
 
- // headers
 
- // ----------------------------------------------------------------------------
 
- #include "wx/thread.h"
 
- #if wxUSE_THREADS
 
- #include "wx/stopwatch.h"
 
- #include "wx/beforestd.h"
 
- #include <queue>
 
- #include "wx/afterstd.h"
 
- enum wxMessageQueueError
 
- {
 
-     wxMSGQUEUE_NO_ERROR = 0, // operation completed successfully
 
-     wxMSGQUEUE_TIMEOUT,      // no messages received before timeout expired
 
-     wxMSGQUEUE_MISC_ERROR    // some unexpected (and fatal) error has occurred
 
- };
 
- // ---------------------------------------------------------------------------
 
- // Message queue allows passing message between threads.
 
- //
 
- // This class is typically used for communicating between the main and worker
 
- // threads. The main thread calls Post() and the worker thread calls Receive().
 
- //
 
- // For this class a message is an object of arbitrary type T. Notice that
 
- // typically there must be some special message indicating that the thread
 
- // should terminate as there is no other way to gracefully shutdown a thread
 
- // waiting on the message queue.
 
- // ---------------------------------------------------------------------------
 
- template <typename T>
 
- class wxMessageQueue
 
- {
 
- public:
 
-     // The type of the messages transported by this queue
 
-     typedef T Message;
 
-     // Default ctor creates an initially empty queue
 
-     wxMessageQueue()
 
-        : m_conditionNotEmpty(m_mutex)
 
-     {
 
-     }
 
-     // Add a message to this queue and signal the threads waiting for messages.
 
-     //
 
-     // This method is safe to call from multiple threads in parallel.
 
-     wxMessageQueueError Post(const Message& msg)
 
-     {
 
-         wxMutexLocker locker(m_mutex);
 
-         wxCHECK( locker.IsOk(), wxMSGQUEUE_MISC_ERROR );
 
-         m_messages.push(msg);
 
-         m_conditionNotEmpty.Signal();
 
-         return wxMSGQUEUE_NO_ERROR;
 
-     }
 
-     // Remove all messages from the queue.
 
-     //
 
-     // This method is meant to be called from the same thread(s) that call
 
-     // Post() to discard any still pending requests if they became unnecessary.
 
-     wxMessageQueueError Clear()
 
-     {
 
-         wxCHECK( IsOk(), wxMSGQUEUE_MISC_ERROR );
 
-         wxMutexLocker locker(m_mutex);
 
-         std::queue<T> empty;
 
-         std::swap(m_messages, empty);
 
-         return wxMSGQUEUE_NO_ERROR;
 
-     }
 
-     // Wait no more than timeout milliseconds until a message becomes available.
 
-     //
 
-     // Setting timeout to 0 is equivalent to an infinite timeout. See Receive().
 
-     wxMessageQueueError ReceiveTimeout(long timeout, T& msg)
 
-     {
 
-         wxCHECK( IsOk(), wxMSGQUEUE_MISC_ERROR );
 
-         wxMutexLocker locker(m_mutex);
 
-         wxCHECK( locker.IsOk(), wxMSGQUEUE_MISC_ERROR );
 
-         const wxMilliClock_t waitUntil = wxGetLocalTimeMillis() + timeout;
 
-         while ( m_messages.empty() )
 
-         {
 
-             wxCondError result = m_conditionNotEmpty.WaitTimeout(timeout);
 
-             if ( result == wxCOND_NO_ERROR )
 
-                 continue;
 
-             wxCHECK( result == wxCOND_TIMEOUT, wxMSGQUEUE_MISC_ERROR );
 
-             const wxMilliClock_t now = wxGetLocalTimeMillis();
 
-             if ( now >= waitUntil )
 
-                 return wxMSGQUEUE_TIMEOUT;
 
-             timeout = (waitUntil - now).ToLong();
 
-             wxASSERT(timeout > 0);
 
-         }
 
-         msg = m_messages.front();
 
-         m_messages.pop();
 
-         return wxMSGQUEUE_NO_ERROR;
 
-     }
 
-     // Same as ReceiveTimeout() but waits for as long as it takes for a message
 
-     // to become available (so it can't return wxMSGQUEUE_TIMEOUT)
 
-     wxMessageQueueError Receive(T& msg)
 
-     {
 
-         wxCHECK( IsOk(), wxMSGQUEUE_MISC_ERROR );
 
-         wxMutexLocker locker(m_mutex);
 
-         wxCHECK( locker.IsOk(), wxMSGQUEUE_MISC_ERROR );
 
-         while ( m_messages.empty() )
 
-         {
 
-             wxCondError result = m_conditionNotEmpty.Wait();
 
-             wxCHECK( result == wxCOND_NO_ERROR, wxMSGQUEUE_MISC_ERROR );
 
-         }
 
-         msg = m_messages.front();
 
-         m_messages.pop();
 
-         return wxMSGQUEUE_NO_ERROR;
 
-     }
 
-     // Return false only if there was a fatal error in ctor
 
-     bool IsOk() const
 
-     {
 
-         return m_conditionNotEmpty.IsOk();
 
-     }
 
- private:
 
-     // Disable copy ctor and assignment operator
 
-     wxMessageQueue(const wxMessageQueue<T>& rhs);
 
-     wxMessageQueue<T>& operator=(const wxMessageQueue<T>& rhs);
 
-     mutable wxMutex m_mutex;
 
-     wxCondition     m_conditionNotEmpty;
 
-     std::queue<T>   m_messages;
 
- };
 
- #endif // wxUSE_THREADS
 
- #endif // _WX_MSGQUEUE_H_
 
 
  |