template<class SYNCH = MT_Synch> class Message_Queue { public: // Default high and low water marks. enum { // 0 is the low water mark. DEFAULT_LWM = 0, // 1 K is the high water mark. DEFAULT_HWM = 4096, // Message queue was active before activate() or deactivate(). WAS_ACTIVE = 1, // Message queue was inactive before activate() or deactivate(). WAS_INACTIVE = 2 };
// Initialize a Message_Queue.(构造函数) Message_Queue (size_t hwm = DEFAULT_HWM,size_t lwm = DEFAULT_LWM); // Destroy a Message_Queue. ~Message_Queue (void);(析构函数)
/* Checks if queue is full/empty. */ int is_full (void)const; int is_empty (void)const;
// Enqueue and dequeue a Message_Block *. int enqueue_tail (Message_Block *new_item,Time_Value *tv = 0); int enqueue_head (Message_Block *new_item,Time_Value *tv = 0); int dequeue_head (Message_Block *&first_item, Time_Value *tv = 0);
// Deactivate the queue and wakeup all threads waiting on the queue so they can continue. int deactivate (void); // Reactivate the queue so that threads can enqueue and dequeue messages again. int activate (void);
private: // Routines that actually do the enqueueing and dequeueing (assumes locks are held). int enqueue_tail_i (Message_Block *); int enqueue_head_i (Message_Block *); int enqueue_head_i (Message_Block *&);
// Check the boundary conditions. int is_empty_i (void)const; int is_full_i (void)const;
// Implement activate() and deactivate() methods (assumes locks are held). int deactivate_i (void); int activate_i (void);
//数据成员
// Pointer to head of Message_Block list. Message_Block *head_;
// Pointer to tail of Message_Block list. Message_Block *tail_;
// Lowest number before unblocking occurs. int low_water_mark_;
// Greatest number of bytes before blocking. int high_water_mark_;
// Current number of bytes in the queue. int cur_bytes_;
// Current number of messages in the queue. int cur_count_;
// Indicates that the queue is inactive. int deactivated_;
// C++ wrapper synchronization primitives for controlling concurrent access.
template<class SYNCH>int Message_Queue<SYNCH>::enqueue_head (Message_Block *new_item, Time_Value *tv) { Guard<SYNCH::MUTEX> monitor(lock_); if(deactivated_)//消息队列处在没有激活的状态 { errno= ESHUTDOWN; return-1; } // Wait while the queue is full. while (is_full_i ()) { // Release the lock_ and wait for timeout, signal, or space becoming available in the list.
if(notfull_.wait (tv) == -1) { if(errno== ETIME) errno= EWOULDBLOCK; return-1; } if(deactivated_) { errno= ESHUTDOWN; return-1; } } // Actually enqueue the message at the head of the list. enqueue_head_i (new_item); // Tell any blocked threads that the queue has a new item! notempty_.signal (); return 0; }
enqueue_tail方法在队列的末尾插入新条目。它返回的是队列中条目的数量。
template<class SYNCH>int Message_Queue<SYNCH>::enqueue_tail (Message_Block *new_item, Time_Value *tv) { Guard<SYNCH::MUTEX> monitor (lock_); if(deactivated_) { errno= ESHUTDOWN; return-1; } // Wait while the queue is full. while(is_full_i ()) { // Release the lock_ and wait for timeout, signal, or space becoming available in the list. if(notfull_.wait (tv) == -1) { if(errno== ETIME) errno= EWOULDBLOCK; return-1; } if(deactivated_) { errno= ESHUTDOWN; return-1; } } // Actually enqueue the message at the end of the list.
enqueue_tail_i (new_item); // Tell any blocked threads that the queue has a new item! notempty_.signal (); return 0; }
template<class SYNCH>int Message_Queue<SYNCH>::dequeue_head (Message_Block *&first_item, Time_Value *tv) { Guard<SYNCH::MUTEX> monitor (lock); // Wait while the queue is empty. while(is_empty_i ()) { // Release the lock_ and wait for timeout, signal, or a new message being placed in the list. if(notempty_.wait (tv) == -1) { if(errno== ETIME) errno= EWOULDBLOCK; return-1; } if(deactivated_) { errno= ESHUTDOWN; return-1; } } // Actually dequeue the first message. dequeue_head_i (first_item); // Tell any blocked threads that the queue is no longer full. notfull_.signal (); return 0; }