mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 10:37:03 +00:00
1561 lines
59 KiB
C++
1561 lines
59 KiB
C++
/* -*- C++ -*- */
|
|
|
|
//=============================================================================
|
|
/**
|
|
* @file Message_Queue_T.h
|
|
*
|
|
* $Id: Message_Queue_T.h 91626 2010-09-07 10:59:20Z johnnyw $
|
|
*
|
|
* @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
|
|
*/
|
|
//=============================================================================
|
|
|
|
#ifndef ACE_MESSAGE_QUEUE_T_H
|
|
#define ACE_MESSAGE_QUEUE_T_H
|
|
|
|
#include /**/ "ace/pre.h"
|
|
|
|
#include "ace/Message_Queue.h"
|
|
#include "ace/Dynamic_Message_Strategy.h"
|
|
#include "ace/Synch_Traits.h"
|
|
#include "ace/Guard_T.h"
|
|
|
|
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
|
# pragma once
|
|
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
|
|
|
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
|
|
|
#if defined (ACE_VXWORKS)
|
|
class ACE_Message_Queue_Vx;
|
|
#endif /* defined (ACE_VXWORKS) */
|
|
|
|
#if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
|
|
class ACE_Message_Queue_NT;
|
|
#endif /* ACE_HAS_WIN32_OVERLAPPED_IO*/
|
|
|
|
#if defined (ACE_HAS_MONITOR_POINTS) && ACE_HAS_MONITOR_POINTS == 1
|
|
namespace ACE
|
|
{
|
|
namespace Monitor_Control
|
|
{
|
|
class Size_Monitor;
|
|
}
|
|
}
|
|
#endif /* ACE_HAS_MONITOR_POINTS==1 */
|
|
|
|
/**
|
|
* @class ACE_Message_Queue
|
|
*
|
|
* @brief A message queueing facility with parameterized synchronization
|
|
* capability. ACE_Message_Queue is modeled after the queueing facilities
|
|
* in System V STREAMs.
|
|
*
|
|
* ACE_Message_Queue is the primary queueing facility for
|
|
* messages in the ACE framework. It's one template argument parameterizes
|
|
* the queue's synchronization. The argument specifies a synchronization
|
|
* strategy. The two main strategies available for ACE_SYNCH_DECL are:
|
|
* -# ACE_MT_SYNCH: all operations are thread-safe
|
|
* -# ACE_NULL_SYNCH: no synchronization and no locking overhead
|
|
*
|
|
* All data passing through ACE_Message_Queue is in the form of
|
|
* ACE_Message_Block objects. @sa ACE_Message_Block.
|
|
*/
|
|
template <ACE_SYNCH_DECL>
|
|
class ACE_Message_Queue : public ACE_Message_Queue_Base
|
|
{
|
|
public:
|
|
friend class ACE_Message_Queue_Iterator<ACE_SYNCH_USE>;
|
|
friend class ACE_Message_Queue_Reverse_Iterator<ACE_SYNCH_USE>;
|
|
|
|
// = Traits
|
|
typedef ACE_Message_Queue_Iterator<ACE_SYNCH_USE>
|
|
ITERATOR;
|
|
typedef ACE_Message_Queue_Reverse_Iterator<ACE_SYNCH_USE>
|
|
REVERSE_ITERATOR;
|
|
|
|
/**
|
|
* @name Initialization methods
|
|
*/
|
|
//@{
|
|
/**
|
|
* Initialize an ACE_Message_Queue.
|
|
*
|
|
* @param hwm High water mark. Determines how many bytes can be stored in a
|
|
* queue before it's considered full. Supplier threads must block
|
|
* until the queue is no longer full.
|
|
* @param lwm Low water mark. Determines how many bytes must be in the queue
|
|
* before supplier threads are allowed to enqueue additional
|
|
* data. By default, the @a hwm equals @a lwm, which means
|
|
* that suppliers will be able to enqueue new messages as soon as
|
|
* a consumer removes any message from the queue. Making the low
|
|
* water mark smaller than the high water mark forces consumers to
|
|
* drain more messages from the queue before suppliers can enqueue
|
|
* new messages, which can minimize the "silly window syndrome."
|
|
* @param ns Notification strategy. Pointer to an object conforming to the
|
|
* ACE_Notification_Strategy interface. If set, the object's
|
|
* notify(void) method will be called each time data is added to
|
|
* this ACE_Message_Queue. @see ACE_Reactor_Notification_Strategy.
|
|
*/
|
|
ACE_Message_Queue (size_t hwm = ACE_Message_Queue_Base::DEFAULT_HWM,
|
|
size_t lwm = ACE_Message_Queue_Base::DEFAULT_LWM,
|
|
ACE_Notification_Strategy *ns = 0);
|
|
virtual int open (size_t hwm = ACE_Message_Queue_Base::DEFAULT_HWM,
|
|
size_t lwm = ACE_Message_Queue_Base::DEFAULT_LWM,
|
|
ACE_Notification_Strategy *ns = 0);
|
|
//@}
|
|
|
|
/// Releases all resources from the message queue and marks it deactivated.
|
|
/// @sa flush().
|
|
///
|
|
/// @retval The number of messages released from the queue; -1 on error.
|
|
virtual int close (void);
|
|
|
|
/// Releases all resources from the message queue and marks it deactivated.
|
|
virtual ~ACE_Message_Queue (void);
|
|
|
|
/**
|
|
* Releases all resources from the message queue but does not mark it
|
|
* deactivated. This method holds the queue lock during this operation.
|
|
* @sa close().
|
|
*
|
|
* @return The number of messages flushed; -1 on error.
|
|
*/
|
|
virtual int flush (void);
|
|
|
|
/**
|
|
* Release all resources from the message queue but do not mark it
|
|
* as deactivated.
|
|
*
|
|
* @pre The caller must be holding the queue lock before calling this
|
|
* method.
|
|
*
|
|
* @return The number of messages flushed.
|
|
*/
|
|
virtual int flush_i (void);
|
|
|
|
/** @name Enqueue and dequeue methods
|
|
*
|
|
* The enqueue and dequeue methods accept a timeout value passed as
|
|
* an ACE_Time_Value *. In all cases, if the timeout pointer is 0,
|
|
* the caller will block until action is possible. If the timeout pointer
|
|
* is non-zero, the call will wait (if needed, subject to water mark
|
|
* settings) until the absolute time specified in the referenced
|
|
* ACE_Time_Value object is reached. If the time is reached before the
|
|
* desired action is possible, the method will return -1 with errno set
|
|
* to @c EWOULDBLOCK. Regardless of the timeout setting, however,
|
|
* these methods will also fail and return -1 when the queue is closed,
|
|
* deactivated, pulsed, or when a signal occurs.
|
|
*
|
|
* See C++NPv2 Section 6.2 and APG Section 12.3 for a fuller treatment of
|
|
* ACE_Message_Queue, enqueueing, dequeueing, and how these operations are
|
|
* affected by queue state transitions.
|
|
*/
|
|
//@{
|
|
/**
|
|
* Retrieve a pointer to the first ACE_Message_Block in the queue
|
|
* without removing it.
|
|
*
|
|
* @note Because the block whose pointer is returned is still on the queue,
|
|
* another thread may dequeue the referenced block at any time,
|
|
* including before the calling thread examines the peeked-at block.
|
|
* Be very careful with this method in multithreaded queueing
|
|
* situations.
|
|
*
|
|
* @param first_item Reference to an ACE_Message_Block * that will
|
|
* point to the first block on the queue. The block
|
|
* remains on the queue until this or another thread
|
|
* dequeues it.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for a block to be queued.
|
|
*
|
|
* @retval >0 The number of ACE_Message_Blocks on the queue.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int peek_dequeue_head (ACE_Message_Block *&first_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Enqueue an ACE_Message_Block into the queue in accordance with
|
|
* the ACE_Message_Block's priority (0 is lowest priority). FIFO
|
|
* order is maintained when messages of the same priority are
|
|
* inserted consecutively.
|
|
*
|
|
* @param new_item Pointer to an ACE_Message_Block that will be
|
|
* added to the queue. The block's @c msg_priority()
|
|
* method will be called to obtain the queueing priority.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for the block to be queued.
|
|
*
|
|
* @retval >0 The number of ACE_Message_Blocks on the queue after adding
|
|
* the specified block.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int enqueue_prio (ACE_Message_Block *new_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Enqueue an ACE_Message_Block into the queue in accordance with the
|
|
* block's deadline time. FIFO order is maintained when messages of
|
|
* the same deadline time are inserted consecutively.
|
|
*
|
|
* @param new_item Pointer to an ACE_Message_Block that will be
|
|
* added to the queue. The block's @c msg_deadline_time()
|
|
* method will be called to obtain the relative queueing
|
|
* position.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for the block to be queued.
|
|
*
|
|
* @retval >0 The number of ACE_Message_Blocks on the queue after adding
|
|
* the specified block.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int enqueue_deadline (ACE_Message_Block *new_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* @deprecated This is an alias for enqueue_prio(). It's only here for
|
|
* backwards compatibility and will go away in a subsequent release.
|
|
* Please use enqueue_prio() instead.
|
|
*/
|
|
virtual int enqueue (ACE_Message_Block *new_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Enqueue one or more ACE_Message_Block objects at the tail of the queue.
|
|
* If the @a new_item @c next() pointer is non-zero, it is assumed to be the
|
|
* start of a series of ACE_Message_Block objects connected via their
|
|
* @c next() pointers. The series of blocks will be added to the queue in
|
|
* the same order they are passed in as.
|
|
*
|
|
* @param new_item Pointer to an ACE_Message_Block that will be
|
|
* added to the queue. If the block's @c next() pointer
|
|
* is non-zero, all blocks chained from the @c next()
|
|
* pointer are enqueued as well.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for the block to be queued.
|
|
*
|
|
* @retval >0 The number of ACE_Message_Blocks on the queue after adding
|
|
* the specified block(s).
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int enqueue_tail (ACE_Message_Block *new_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Enqueue one or more ACE_Message_Block objects at the head of the queue.
|
|
* If the @a new_item @c next() pointer is non-zero, it is assumed to be the
|
|
* start of a series of ACE_Message_Block objects connected via their
|
|
* @c next() pointers. The series of blocks will be added to the queue in
|
|
* the same order they are passed in as.
|
|
*
|
|
* @param new_item Pointer to an ACE_Message_Block that will be
|
|
* added to the queue. If the block's @c next() pointer
|
|
* is non-zero, all blocks chained from the @c next()
|
|
* pointer are enqueued as well.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for the block to be queued.
|
|
*
|
|
* @retval >0 The number of ACE_Message_Blocks on the queue after adding
|
|
* the specified block(s).
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int enqueue_head (ACE_Message_Block *new_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/// This method is an alias for the dequeue_head() method.
|
|
virtual int dequeue (ACE_Message_Block *&first_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Dequeue the ACE_Message_Block at the head of the queue and return
|
|
* a pointer to the dequeued block.
|
|
*
|
|
* @param first_item Reference to an ACE_Message_Block * that will
|
|
* be set to the address of the dequeued block.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for a block to be dequeued.
|
|
*
|
|
* @retval >=0 The number of ACE_Message_Blocks remaining in the queue.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int dequeue_head (ACE_Message_Block *&first_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Dequeue the ACE_Message_Block that has the lowest priority (preserves
|
|
* FIFO order for messages with the same priority) and return a pointer
|
|
* to the dequeued block.
|
|
*
|
|
* @param first_item Reference to an ACE_Message_Block * that will
|
|
* be set to the address of the dequeued block.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for a block to be dequeued.
|
|
*
|
|
* @retval >=0 The number of ACE_Message_Blocks remaining in the queue.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int dequeue_prio (ACE_Message_Block *&first_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Dequeue the ACE_Message_Block at the tail of the queue and return
|
|
* a pointer to the dequeued block.
|
|
*
|
|
* @param dequeued Reference to an ACE_Message_Block * that will
|
|
* be set to the address of the dequeued block.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for a block to be dequeued.
|
|
*
|
|
* @retval >=0 The number of ACE_Message_Blocks remaining in the queue.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int dequeue_tail (ACE_Message_Block *&dequeued,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Dequeue the ACE_Message_Block with the earliest deadline time and return
|
|
* a pointer to the dequeued block.
|
|
*
|
|
* @param dequeued Reference to an ACE_Message_Block * that will
|
|
* be set to the address of the dequeued block.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for a block to be dequeued.
|
|
*
|
|
* @retval >=0 The number of ACE_Message_Blocks remaining in the queue.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int dequeue_deadline (ACE_Message_Block *&dequeued,
|
|
ACE_Time_Value *timeout = 0);
|
|
//@}
|
|
|
|
/** @name Queue statistics methods
|
|
*/
|
|
//@{
|
|
|
|
/// True if queue is full, else false.
|
|
virtual bool is_full (void);
|
|
/// True if queue is empty, else false.
|
|
virtual bool is_empty (void);
|
|
|
|
/**
|
|
* Number of total bytes on the queue, i.e., sum of the message
|
|
* block sizes.
|
|
*/
|
|
virtual size_t message_bytes (void);
|
|
|
|
/**
|
|
* Number of total length on the queue, i.e., sum of the message
|
|
* block lengths.
|
|
*/
|
|
virtual size_t message_length (void);
|
|
|
|
/**
|
|
* Number of total messages on the queue.
|
|
*/
|
|
virtual size_t message_count (void);
|
|
|
|
// = Manual changes to these stats (used when queued message blocks
|
|
// change size or lengths).
|
|
/**
|
|
* New value of the number of total bytes on the queue, i.e., sum of
|
|
* the message block sizes.
|
|
*/
|
|
virtual void message_bytes (size_t new_size);
|
|
/**
|
|
* New value of the number of total length on the queue, i.e., sum
|
|
* of the message block lengths.
|
|
*/
|
|
virtual void message_length (size_t new_length);
|
|
|
|
//@}
|
|
|
|
|
|
/** @name Water mark (flow control) methods
|
|
*/
|
|
//@{
|
|
|
|
/**
|
|
* Get high watermark.
|
|
*/
|
|
virtual size_t high_water_mark (void);
|
|
/**
|
|
* Set the high watermark, which determines how many bytes can be
|
|
* stored in a queue before it's considered "full."
|
|
*/
|
|
virtual void high_water_mark (size_t hwm);
|
|
|
|
/**
|
|
* Get low watermark.
|
|
*/
|
|
virtual size_t low_water_mark (void);
|
|
/**
|
|
* Set the low watermark, which determines how many bytes must be in
|
|
* the queue before supplier threads are allowed to enqueue
|
|
* additional ACE_Message_Blocks.
|
|
*/
|
|
virtual void low_water_mark (size_t lwm);
|
|
//@}
|
|
|
|
/** @name Activation and queue state methods
|
|
* See C++NPv2 Section 6.2 and APG Section 12.3 for a fuller treatment of
|
|
* queue states and transitions and how the transitions affect message
|
|
* enqueueing and dequeueing operations.
|
|
*/
|
|
//@{
|
|
|
|
/**
|
|
* Deactivate the queue and wakeup all threads waiting on the queue
|
|
* so they can continue. No messages are removed from the queue,
|
|
* however. Any other operations called until the queue is
|
|
* activated again will immediately return -1 with @c errno ==
|
|
* ESHUTDOWN. Returns WAS_INACTIVE if queue was inactive before the
|
|
* call and WAS_ACTIVE if queue was active before the call.
|
|
*/
|
|
virtual int deactivate (void);
|
|
|
|
/**
|
|
* Reactivate the queue so that threads can enqueue and dequeue
|
|
* messages again. Returns the state of the queue before the call.
|
|
*/
|
|
virtual int activate (void);
|
|
|
|
/**
|
|
* Pulse the queue to wake up any waiting threads. Changes the
|
|
* queue state to PULSED; future enqueue/dequeue operations proceed
|
|
* as in ACTIVATED state.
|
|
*
|
|
* @return The queue's state before this call.
|
|
*/
|
|
virtual int pulse (void);
|
|
|
|
/// Returns the current state of the queue, which can be one of
|
|
/// ACTIVATED, DEACTIVATED, or PULSED.
|
|
virtual int state (void);
|
|
|
|
/// Returns true if the state of the queue is <DEACTIVATED>,
|
|
/// but false if the queue's is <ACTIVATED> or <PULSED>.
|
|
virtual int deactivated (void);
|
|
//@}
|
|
|
|
/** @name Notification strategy methods
|
|
*/
|
|
//@{
|
|
|
|
/**
|
|
* This hook is automatically invoked by <enqueue_head>,
|
|
* <enqueue_tail>, and <enqueue_prio> when a new item is inserted
|
|
* into the queue. Subclasses can override this method to perform
|
|
* specific notification strategies (e.g., signaling events for a
|
|
* <WFMO_Reactor>, notifying a <Reactor>, etc.). In a
|
|
* multi-threaded application with concurrent consumers, there is no
|
|
* guarantee that the queue will be still be non-empty by the time
|
|
* the notification occurs.
|
|
*/
|
|
virtual int notify (void);
|
|
|
|
/// Get the notification strategy for the <Message_Queue>
|
|
virtual ACE_Notification_Strategy *notification_strategy (void);
|
|
|
|
/// Set the notification strategy for the <Message_Queue>
|
|
virtual void notification_strategy (ACE_Notification_Strategy *s);
|
|
//@}
|
|
|
|
/// Returns a reference to the lock used by the ACE_Message_Queue.
|
|
virtual ACE_SYNCH_MUTEX_T &lock (void);
|
|
|
|
/// Dump the state of an object.
|
|
virtual void dump (void) const;
|
|
|
|
/// Declare the dynamic allocation hooks.
|
|
ACE_ALLOC_HOOK_DECLARE;
|
|
|
|
protected:
|
|
// = Routines that actually do the enqueueing and dequeueing.
|
|
|
|
// These routines assume that locks are held by the corresponding
|
|
// public methods. Since they are virtual, you can change the
|
|
// queueing mechanism by subclassing from ACE_Message_Queue.
|
|
|
|
/// Enqueue an <ACE_Message_Block *> in accordance with its priority.
|
|
virtual int enqueue_i (ACE_Message_Block *new_item);
|
|
|
|
/// Enqueue an <ACE_Message_Block *> in accordance with its deadline time.
|
|
virtual int enqueue_deadline_i (ACE_Message_Block *new_item);
|
|
|
|
/// Enqueue an <ACE_Message_Block *> at the end of the queue.
|
|
virtual int enqueue_tail_i (ACE_Message_Block *new_item);
|
|
|
|
/// Enqueue an <ACE_Message_Block *> at the head of the queue.
|
|
virtual int enqueue_head_i (ACE_Message_Block *new_item);
|
|
|
|
/// Dequeue and return the <ACE_Message_Block *> at the head of the
|
|
/// queue.
|
|
virtual int dequeue_head_i (ACE_Message_Block *&first_item);
|
|
|
|
/// Dequeue and return the <ACE_Message_Block *> with the lowest
|
|
/// priority.
|
|
virtual int dequeue_prio_i (ACE_Message_Block *&dequeued);
|
|
|
|
/// Dequeue and return the <ACE_Message_Block *> at the tail of the
|
|
/// queue.
|
|
virtual int dequeue_tail_i (ACE_Message_Block *&first_item);
|
|
|
|
/// Dequeue and return the <ACE_Message_Block *> with the lowest
|
|
/// deadline time.
|
|
virtual int dequeue_deadline_i (ACE_Message_Block *&first_item);
|
|
|
|
// = Check the boundary conditions (assumes locks are held).
|
|
|
|
/// True if queue is full, else false.
|
|
virtual bool is_full_i (void);
|
|
|
|
/// True if queue is empty, else false.
|
|
virtual bool is_empty_i (void);
|
|
|
|
// = Implementation of the public <activate> and <deactivate> methods.
|
|
|
|
// These methods assume locks are held.
|
|
|
|
/**
|
|
* Notifies all waiting threads that the queue has been deactivated
|
|
* so they can wakeup and continue other processing.
|
|
* No messages are removed from the queue.
|
|
*
|
|
* @param pulse If 0, the queue's state is changed to DEACTIVATED
|
|
* and any other operations called until the queue is
|
|
* reactivated will immediately return -1 with
|
|
* errno == ESHUTDOWN.
|
|
* If not zero, only the waiting threads are notified and
|
|
* the queue's state changes to PULSED.
|
|
*
|
|
* @return The state of the queue before the call.
|
|
*/
|
|
virtual int deactivate_i (int pulse = 0);
|
|
|
|
/// Activate the queue.
|
|
virtual int activate_i (void);
|
|
|
|
// = Helper methods to factor out common #ifdef code.
|
|
|
|
/// Wait for the queue to become non-full.
|
|
virtual int wait_not_full_cond (ACE_Time_Value *timeout);
|
|
|
|
/// Wait for the queue to become non-empty.
|
|
virtual int wait_not_empty_cond (ACE_Time_Value *timeout);
|
|
|
|
/// Inform any threads waiting to enqueue that they can procede.
|
|
virtual int signal_enqueue_waiters (void);
|
|
|
|
/// Inform any threads waiting to dequeue that they can procede.
|
|
virtual int signal_dequeue_waiters (void);
|
|
|
|
/// Pointer to head of ACE_Message_Block list.
|
|
ACE_Message_Block *head_;
|
|
|
|
/// Pointer to tail of ACE_Message_Block list.
|
|
ACE_Message_Block *tail_;
|
|
|
|
/// Lowest number before unblocking occurs.
|
|
size_t low_water_mark_;
|
|
|
|
/// Greatest number of bytes before blocking.
|
|
size_t high_water_mark_;
|
|
|
|
/// Current number of bytes in the queue.
|
|
size_t cur_bytes_;
|
|
|
|
/// Current length of messages in the queue.
|
|
size_t cur_length_;
|
|
|
|
/// Current number of messages in the queue.
|
|
size_t cur_count_;
|
|
|
|
/// The notification strategy used when a new message is enqueued.
|
|
ACE_Notification_Strategy *notification_strategy_;
|
|
|
|
// = Synchronization primitives for controlling concurrent access.
|
|
/// Protect queue from concurrent access.
|
|
ACE_SYNCH_MUTEX_T lock_;
|
|
|
|
/// Used to make threads sleep until the queue is no longer empty.
|
|
ACE_SYNCH_CONDITION_T not_empty_cond_;
|
|
|
|
/// Used to make threads sleep until the queue is no longer full.
|
|
ACE_SYNCH_CONDITION_T not_full_cond_;
|
|
|
|
/// Sends the size of the queue whenever it changes.
|
|
#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1)
|
|
ACE::Monitor_Control::Size_Monitor *monitor_;
|
|
#endif
|
|
|
|
private:
|
|
|
|
// = Disallow these operations.
|
|
ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Message_Queue<ACE_SYNCH_USE> &))
|
|
ACE_UNIMPLEMENTED_FUNC (ACE_Message_Queue (const ACE_Message_Queue<ACE_SYNCH_USE> &))
|
|
};
|
|
|
|
// This typedef is used to get around a compiler bug in g++/vxworks.
|
|
typedef ACE_Message_Queue<ACE_SYNCH> ACE_DEFAULT_MESSAGE_QUEUE_TYPE;
|
|
|
|
|
|
/**
|
|
* @class ACE_Message_Queue_Iterator
|
|
*
|
|
* @brief Iterator for the ACE_Message_Queue.
|
|
*/
|
|
template <ACE_SYNCH_DECL>
|
|
class ACE_Message_Queue_Iterator
|
|
{
|
|
public:
|
|
// = Initialization method.
|
|
ACE_Message_Queue_Iterator (ACE_Message_Queue <ACE_SYNCH_USE> &queue);
|
|
|
|
// = Iteration methods.
|
|
/// Pass back the @a entry that hasn't been seen in the queue.
|
|
/// Returns 0 when all items have been seen, else 1.
|
|
int next (ACE_Message_Block *&entry);
|
|
|
|
/// Returns 1 when all items have been seen, else 0.
|
|
int done (void) const;
|
|
|
|
/// Move forward by one element in the queue. Returns 0 when all the
|
|
/// items in the set have been seen, else 1.
|
|
int advance (void);
|
|
|
|
/// Dump the state of an object.
|
|
void dump (void) const;
|
|
|
|
/// Declare the dynamic allocation hooks.
|
|
ACE_ALLOC_HOOK_DECLARE;
|
|
|
|
private:
|
|
/// Message_Queue we are iterating over.
|
|
ACE_Message_Queue <ACE_SYNCH_USE> &queue_;
|
|
|
|
/// Keeps track of how far we've advanced...
|
|
ACE_Message_Block *curr_;
|
|
};
|
|
|
|
/**
|
|
* @class ACE_Message_Queue_Reverse_Iterator
|
|
*
|
|
* @brief Reverse Iterator for the ACE_Message_Queue.
|
|
*/
|
|
template <ACE_SYNCH_DECL>
|
|
class ACE_Message_Queue_Reverse_Iterator
|
|
{
|
|
public:
|
|
// = Initialization method.
|
|
ACE_Message_Queue_Reverse_Iterator (ACE_Message_Queue <ACE_SYNCH_USE> &queue);
|
|
|
|
// = Iteration methods.
|
|
/// Pass back the @a entry that hasn't been seen in the queue.
|
|
/// Returns 0 when all items have been seen, else 1.
|
|
int next (ACE_Message_Block *&entry);
|
|
|
|
/// Returns 1 when all items have been seen, else 0.
|
|
int done (void) const;
|
|
|
|
/// Move forward by one element in the queue. Returns 0 when all the
|
|
/// items in the set have been seen, else 1.
|
|
int advance (void);
|
|
|
|
/// Dump the state of an object.
|
|
void dump (void) const;
|
|
|
|
/// Declare the dynamic allocation hooks.
|
|
ACE_ALLOC_HOOK_DECLARE;
|
|
|
|
private:
|
|
/// Message_Queue we are iterating over.
|
|
ACE_Message_Queue <ACE_SYNCH_USE> &queue_;
|
|
|
|
/// Keeps track of how far we've advanced...
|
|
ACE_Message_Block *curr_;
|
|
};
|
|
|
|
/**
|
|
* @class ACE_Dynamic_Message_Queue
|
|
*
|
|
* @brief A derived class which adapts the ACE_Message_Queue
|
|
* class in order to maintain dynamic priorities for enqueued
|
|
* <ACE_Message_Blocks> and manage the queue order according
|
|
* to these dynamic priorities.
|
|
*
|
|
* The messages in the queue are managed so as to preserve
|
|
* a logical ordering with minimal overhead per enqueue and
|
|
* dequeue operation. For this reason, the actual order of
|
|
* messages in the linked list of the queue may differ from
|
|
* their priority order. As time passes, a message may change
|
|
* from pending status to late status, and eventually to beyond
|
|
* late status. To minimize reordering overhead under this
|
|
* design force, three separate boundaries are maintained
|
|
* within the linked list of messages. Messages are dequeued
|
|
* preferentially from the head of the pending portion, then
|
|
* the head of the late portion, and finally from the head
|
|
* of the beyond late portion. In this way, only the boundaries
|
|
* need to be maintained (which can be done efficiently, as
|
|
* aging messages maintain the same linked list order as they
|
|
* progress from one status to the next), with no reordering
|
|
* of the messages themselves, while providing correct priority
|
|
* ordered dequeueing semantics.
|
|
* Head and tail enqueue methods inherited from ACE_Message_Queue
|
|
* are made private to prevent out-of-order messages from confusing
|
|
* management of the various portions of the queue. Messages in
|
|
* the pending portion of the queue whose priority becomes late
|
|
* (according to the specific dynamic strategy) advance into
|
|
* the late portion of the queue. Messages in the late portion
|
|
* of the queue whose priority becomes later than can be represented
|
|
* advance to the beyond_late portion of the queue. These behaviors
|
|
* support a limited schedule overrun, with pending messages prioritized
|
|
* ahead of late messages, and late messages ahead of beyond late
|
|
* messages. These behaviors can be modified in derived classes by
|
|
* providing alternative definitions for the appropriate virtual methods.
|
|
* When filled with messages, the queue's linked list should look like:
|
|
* H T
|
|
* | |
|
|
* B - B - B - B - L - L - L - P - P - P - P - P
|
|
* | | | | | |
|
|
* BH BT LH LT PH PT
|
|
* Where the symbols are as follows:
|
|
* H = Head of the entire list
|
|
* T = Tail of the entire list
|
|
* B = Beyond late message
|
|
* BH = Beyond late messages Head
|
|
* BT = Beyond late messages Tail
|
|
* L = Late message
|
|
* LH = Late messages Head
|
|
* LT = Late messages Tail
|
|
* P = Pending message
|
|
* PH = Pending messages Head
|
|
* PT = Pending messages Tail
|
|
* Caveat: the virtual methods enqueue_tail, enqueue_head,
|
|
* and peek_dequeue_head have semantics for the static
|
|
* message queues that cannot be guaranteed for dynamic
|
|
* message queues. The peek_dequeue_head method just
|
|
* calls the base class method, while the two enqueue
|
|
* methods call the priority enqueue method. The
|
|
* order of messages in the dynamic queue is a function
|
|
* of message deadlines and how long they are in the
|
|
* queues. You can manipulate these in some cases to
|
|
* ensure the correct semantics, but that is not a
|
|
* very stable or portable approach (discouraged).
|
|
*/
|
|
template <ACE_SYNCH_DECL>
|
|
class ACE_Dynamic_Message_Queue : public ACE_Message_Queue<ACE_SYNCH_USE>
|
|
{
|
|
public:
|
|
// = Initialization and termination methods.
|
|
ACE_Dynamic_Message_Queue (ACE_Dynamic_Message_Strategy & message_strategy,
|
|
size_t hwm = ACE_Message_Queue_Base::DEFAULT_HWM,
|
|
size_t lwm = ACE_Message_Queue_Base::DEFAULT_LWM,
|
|
ACE_Notification_Strategy * = 0);
|
|
|
|
/// Close down the message queue and release all resources.
|
|
virtual ~ACE_Dynamic_Message_Queue (void);
|
|
|
|
/**
|
|
* Detach all messages with status given in the passed flags from
|
|
* the queue and return them by setting passed head and tail pointers
|
|
* to the linked list they comprise. This method is intended primarily
|
|
* as a means of periodically harvesting messages that have missed
|
|
* their deadlines, but is available in its most general form. All
|
|
* messages are returned in priority order, from head to tail, as of
|
|
* the time this method was called.
|
|
*/
|
|
virtual int remove_messages (ACE_Message_Block *&list_head,
|
|
ACE_Message_Block *&list_tail,
|
|
u_int status_flags);
|
|
|
|
/**
|
|
* Dequeue and return the <ACE_Message_Block *> at the head of the
|
|
* queue. Returns -1 on failure, else the number of items still on
|
|
* the queue.
|
|
*/
|
|
virtual int dequeue_head (ACE_Message_Block *&first_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/// Dump the state of the queue.
|
|
virtual void dump (void) const;
|
|
|
|
/**
|
|
* Just call priority enqueue method: tail enqueue semantics for dynamic
|
|
* message queues are unstable: the message may or may not be where
|
|
* it was placed after the queue is refreshed prior to the next
|
|
* enqueue or dequeue operation.
|
|
*/
|
|
virtual int enqueue_tail (ACE_Message_Block *new_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Just call priority enqueue method: head enqueue semantics for dynamic
|
|
* message queues are unstable: the message may or may not be where
|
|
* it was placed after the queue is refreshed prior to the next
|
|
* enqueue or dequeue operation.
|
|
*/
|
|
virtual int enqueue_head (ACE_Message_Block *new_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
|
|
/// Declare the dynamic allocation hooks.
|
|
ACE_ALLOC_HOOK_DECLARE;
|
|
|
|
protected:
|
|
|
|
/**
|
|
* Enqueue an <ACE_Message_Block *> in accordance with its priority.
|
|
* priority may be *dynamic* or *static* or a combination or *both*
|
|
* It calls the priority evaluation function passed into the Dynamic
|
|
* Message Queue constructor to update the priorities of all
|
|
* enqueued messages.
|
|
*/
|
|
virtual int enqueue_i (ACE_Message_Block *new_item);
|
|
|
|
/// Enqueue a message in priority order within a given priority status sublist
|
|
virtual int sublist_enqueue_i (ACE_Message_Block *new_item,
|
|
const ACE_Time_Value ¤t_time,
|
|
ACE_Message_Block *&sublist_head,
|
|
ACE_Message_Block *&sublist_tail,
|
|
ACE_Dynamic_Message_Strategy::Priority_Status status);
|
|
|
|
/**
|
|
* Dequeue and return the <ACE_Message_Block *> at the head of the
|
|
* logical queue. Attempts first to dequeue from the pending
|
|
* portion of the queue, or if that is empty from the late portion,
|
|
* or if that is empty from the beyond late portion, or if that is
|
|
* empty just sets the passed pointer to zero and returns -1.
|
|
*/
|
|
virtual int dequeue_head_i (ACE_Message_Block *&first_item);
|
|
|
|
/// Refresh the queue using the strategy
|
|
/// specific priority status function.
|
|
virtual int refresh_queue (const ACE_Time_Value & current_time);
|
|
|
|
/// Refresh the pending queue using the strategy
|
|
/// specific priority status function.
|
|
virtual int refresh_pending_queue (const ACE_Time_Value & current_time);
|
|
|
|
/// Refresh the late queue using the strategy
|
|
/// specific priority status function.
|
|
virtual int refresh_late_queue (const ACE_Time_Value & current_time);
|
|
|
|
/// Pointer to head of the pending messages
|
|
ACE_Message_Block *pending_head_;
|
|
|
|
/// Pointer to tail of the pending messages
|
|
ACE_Message_Block *pending_tail_;
|
|
|
|
/// Pointer to head of the late messages
|
|
ACE_Message_Block *late_head_;
|
|
|
|
/// Pointer to tail of the late messages
|
|
ACE_Message_Block *late_tail_;
|
|
|
|
/// Pointer to head of the beyond late messages
|
|
ACE_Message_Block *beyond_late_head_;
|
|
|
|
/// Pointer to tail of the beyond late messages
|
|
ACE_Message_Block *beyond_late_tail_;
|
|
|
|
/// Pointer to a dynamic priority evaluation function.
|
|
ACE_Dynamic_Message_Strategy &message_strategy_;
|
|
|
|
private:
|
|
// = Disallow public access to these operations.
|
|
|
|
ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Dynamic_Message_Queue<ACE_SYNCH_USE> &))
|
|
ACE_UNIMPLEMENTED_FUNC (ACE_Dynamic_Message_Queue (const ACE_Dynamic_Message_Queue<ACE_SYNCH_USE> &))
|
|
|
|
// provide definitions for these (just call base class method),
|
|
// but make them private so they're not accessible outside the class
|
|
|
|
/// Private method to hide public base class method: just calls base class method
|
|
virtual int peek_dequeue_head (ACE_Message_Block *&first_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
};
|
|
|
|
/**
|
|
* @class ACE_Message_Queue_Factory
|
|
*
|
|
* @brief ACE_Message_Queue_Factory is a static factory class template which
|
|
* provides a separate factory method for each of the major kinds of
|
|
* priority based message dispatching: static, earliest deadline first
|
|
* (EDF), and minimum laxity first (MLF).
|
|
*
|
|
* The ACE_Dynamic_Message_Queue class assumes responsibility for
|
|
* releasing the resources of the strategy with which it was
|
|
* constructed: the user of a message queue constructed by
|
|
* any of these factory methods is only responsible for
|
|
* ensuring destruction of the message queue itself.
|
|
*/
|
|
template <ACE_SYNCH_DECL>
|
|
class ACE_Message_Queue_Factory
|
|
{
|
|
public:
|
|
/// Factory method for a statically prioritized ACE_Message_Queue
|
|
static ACE_Message_Queue<ACE_SYNCH_USE> *
|
|
create_static_message_queue (size_t hwm = ACE_Message_Queue_Base::DEFAULT_HWM,
|
|
size_t lwm = ACE_Message_Queue_Base::DEFAULT_LWM,
|
|
ACE_Notification_Strategy * = 0);
|
|
|
|
/// Factory method for a dynamically prioritized (by time to deadline) ACE_Dynamic_Message_Queue
|
|
static ACE_Dynamic_Message_Queue<ACE_SYNCH_USE> *
|
|
create_deadline_message_queue (size_t hwm = ACE_Message_Queue_Base::DEFAULT_HWM,
|
|
size_t lwm = ACE_Message_Queue_Base::DEFAULT_LWM,
|
|
ACE_Notification_Strategy * = 0,
|
|
u_long static_bit_field_mask = 0x3FFUL, // 2^(10) - 1
|
|
u_long static_bit_field_shift = 10, // 10 low order bits
|
|
u_long dynamic_priority_max = 0x3FFFFFUL, // 2^(22)-1
|
|
u_long dynamic_priority_offset = 0x200000UL); // 2^(22-1)
|
|
|
|
/// Factory method for a dynamically prioritized (by laxity) ACE_Dynamic_Message_Queue
|
|
static ACE_Dynamic_Message_Queue<ACE_SYNCH_USE> *
|
|
create_laxity_message_queue (size_t hwm = ACE_Message_Queue_Base::DEFAULT_HWM,
|
|
size_t lwm = ACE_Message_Queue_Base::DEFAULT_LWM,
|
|
ACE_Notification_Strategy * = 0,
|
|
u_long static_bit_field_mask = 0x3FFUL, // 2^(10) - 1
|
|
u_long static_bit_field_shift = 10, // 10 low order bits
|
|
u_long dynamic_priority_max = 0x3FFFFFUL, // 2^(22)-1
|
|
u_long dynamic_priority_offset = 0x200000UL); // 2^(22-1)
|
|
|
|
|
|
#if defined (ACE_VXWORKS)
|
|
|
|
/// Factory method for a wrapped VxWorks message queue
|
|
static ACE_Message_Queue_Vx *
|
|
create_Vx_message_queue (size_t max_messages, size_t max_message_length,
|
|
ACE_Notification_Strategy *ns = 0);
|
|
|
|
#endif /* defined (ACE_VXWORKS) */
|
|
|
|
#if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
|
|
|
|
/// Factory method for a NT message queue.
|
|
static ACE_Message_Queue_NT *
|
|
create_NT_message_queue (size_t max_threads);
|
|
|
|
#endif /* ACE_HAS_WIN32_OVERLAPPED_IO */
|
|
};
|
|
|
|
// Forward decls.
|
|
template <class ACE_MESSAGE_TYPE, ACE_SYNCH_DECL> class ACE_Message_Queue_Ex_Iterator;
|
|
template <class ACE_MESSAGE_TYPE, ACE_SYNCH_DECL> class ACE_Message_Queue_Ex_Reverse_Iterator;
|
|
|
|
/**
|
|
* @class ACE_Message_Queue_Ex
|
|
*
|
|
* @brief A threaded message queueing facility, modeled after the
|
|
* queueing facilities in System V STREAMs.
|
|
*
|
|
* ACE_Message_Queue_Ex is a strongly-typed version of the
|
|
* ACE_Message_Queue class. Rather than queueing in terms of ACE_Message_Block
|
|
* objects, ACE_Message_Queue_Ex has a template argument to specify the
|
|
* type of objects that are queued.
|
|
*
|
|
* The second template argument parameterizes the queue's synchronization.
|
|
* The argument specifies a synchronization strategy. The two main
|
|
* strategies available for ACE_SYNCH_DECL are:
|
|
* -# ACE_MT_SYNCH: all operations are thread-safe
|
|
* -# ACE_NULL_SYNCH: no synchronization and no locking overhead
|
|
*/
|
|
template <class ACE_MESSAGE_TYPE, ACE_SYNCH_DECL>
|
|
class ACE_Message_Queue_Ex
|
|
{
|
|
public:
|
|
|
|
enum
|
|
{
|
|
/// Default priority value. This is the lowest priority.
|
|
DEFAULT_PRIORITY = 0
|
|
};
|
|
|
|
friend class ACE_Message_Queue_Ex_Iterator <ACE_MESSAGE_TYPE, ACE_SYNCH_USE>;
|
|
friend class ACE_Message_Queue_Ex_Reverse_Iterator<ACE_MESSAGE_TYPE, ACE_SYNCH_USE>;
|
|
|
|
// = Traits
|
|
typedef ACE_Message_Queue_Ex_Iterator<ACE_MESSAGE_TYPE, ACE_SYNCH_USE>
|
|
ITERATOR;
|
|
typedef ACE_Message_Queue_Ex_Reverse_Iterator<ACE_MESSAGE_TYPE, ACE_SYNCH_USE>
|
|
REVERSE_ITERATOR;
|
|
|
|
/**
|
|
* @name Initialization methods
|
|
*/
|
|
//@{
|
|
/**
|
|
* Initialize an ACE_Message_Queue_Ex.
|
|
*
|
|
* @param high_water_mark High water mark. Determines how many bytes can be
|
|
* stored in a queue before it's considered full. Supplier threads
|
|
* must block until the queue is no longer full.
|
|
* @param low_water_mark Low water mark. Determines how many bytes must be in
|
|
* the queue before supplier threads are allowed to enqueue additional
|
|
* data. By default, the @a hwm equals @a lwm, which means
|
|
* that suppliers will be able to enqueue new messages as soon as
|
|
* a consumer removes any message from the queue. Making the low
|
|
* water mark smaller than the high water mark forces consumers to
|
|
* drain more messages from the queue before suppliers can enqueue
|
|
* new messages, which can minimize the "silly window syndrome."
|
|
* @param ns Notification strategy. Pointer to an object conforming to the
|
|
* ACE_Notification_Strategy interface. If set, the object's
|
|
* notify(void) method will be called each time data is added to
|
|
* this ACE_Message_Queue. @see ACE_Reactor_Notification_Strategy.
|
|
*/
|
|
ACE_Message_Queue_Ex (size_t high_water_mark = ACE_Message_Queue_Base::DEFAULT_HWM,
|
|
size_t low_water_mark = ACE_Message_Queue_Base::DEFAULT_LWM,
|
|
ACE_Notification_Strategy * ns = 0);
|
|
virtual int open (size_t hwm = ACE_Message_Queue_Base::DEFAULT_HWM,
|
|
size_t lwm = ACE_Message_Queue_Base::DEFAULT_LWM,
|
|
ACE_Notification_Strategy * = 0);
|
|
//@}
|
|
|
|
/// Releases all resources from the message queue and marks it deactivated.
|
|
/// @sa flush().
|
|
///
|
|
/// @retval The number of messages released from the queue; -1 on error.
|
|
virtual int close (void);
|
|
|
|
/// Releases all resources from the message queue and marks it deactivated.
|
|
virtual ~ACE_Message_Queue_Ex (void);
|
|
|
|
/**
|
|
* Releases all resources from the message queue but does not mark it
|
|
* deactivated. This method holds the queue lock during this operation.
|
|
* @sa close().
|
|
*
|
|
* @return The number of messages flushed; -1 on error.
|
|
*/
|
|
virtual int flush (void);
|
|
|
|
/**
|
|
* Release all resources from the message queue but do not mark it
|
|
* as deactivated.
|
|
*
|
|
* @pre The caller must be holding the queue lock before calling this
|
|
* method.
|
|
*
|
|
* @return The number of messages flushed.
|
|
*/
|
|
virtual int flush_i (void);
|
|
|
|
/** @name Enqueue and dequeue methods
|
|
*
|
|
* The enqueue and dequeue methods accept a timeout value passed as
|
|
* an ACE_Time_Value *. In all cases, if the timeout pointer is 0,
|
|
* the caller will block until action is possible. If the timeout pointer
|
|
* is non-zero, the call will wait (if needed, subject to water mark
|
|
* settings) until the absolute time specified in the referenced
|
|
* ACE_Time_Value object is reached. If the time is reached before the
|
|
* desired action is possible, the method will return -1 with errno set
|
|
* to @c EWOULDBLOCK. Regardless of the timeout setting, however,
|
|
* these methods will also fail and return -1 when the queue is closed,
|
|
* deactivated, pulsed, or when a signal occurs.
|
|
*
|
|
* The time parameters are handled the same as in ACE_Message_Queue, so
|
|
* you can see C++NPv2 Section 6.2 and APG Section 12.3 for a fuller
|
|
* treatment of ACE_Message_Queue, enqueueing, dequeueing, and how these
|
|
* operations are affected by queue state transitions.
|
|
*/
|
|
//@{
|
|
/**
|
|
* Retrieve a pointer to the first item in the queue without removing it.
|
|
*
|
|
* @note Because the item whose pointer is returned is still on the queue,
|
|
* another thread may dequeue that item at any time,
|
|
* including before the calling thread examines the peeked-at item.
|
|
* Be very careful with this method in multithreaded queueing
|
|
* situations.
|
|
*
|
|
* @param first_item Reference to an ACE_MESSAGE_TYPE * that will
|
|
* point to the first item on the queue. The item
|
|
* remains on the queue until this or another thread
|
|
* dequeues it.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for an item to be queued.
|
|
*
|
|
* @retval >0 The number of items on the queue.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int peek_dequeue_head (ACE_MESSAGE_TYPE *&first_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Enqueue an ACE_MESSAGE TYPE into the queue in accordance with
|
|
* the specified priority (0 is lowest priority). FIFO
|
|
* order is maintained when items of the same priority are
|
|
* inserted consecutively.
|
|
*
|
|
* @param new_item Pointer to an item that will be added to the queue.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for the block to be queued.
|
|
* @param priority The priority to use when enqueueing the item.
|
|
*
|
|
* @retval >0 The number of items on the queue after adding
|
|
* the specified item.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int enqueue_prio (ACE_MESSAGE_TYPE *new_item,
|
|
ACE_Time_Value *timeout = 0,
|
|
unsigned long priority = DEFAULT_PRIORITY);
|
|
|
|
/**
|
|
* This method acts just like enqueue_tail(). There's no deadline
|
|
* time associated with items.
|
|
*/
|
|
virtual int enqueue_deadline (ACE_MESSAGE_TYPE *new_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* @deprecated This is an alias for enqueue_prio(). It's only here for
|
|
* backwards compatibility and will go away in a subsequent release.
|
|
* Please use enqueue_prio() instead.
|
|
*/
|
|
virtual int enqueue (ACE_MESSAGE_TYPE *new_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Enqueue an item at the tail of the queue.
|
|
*
|
|
* @param new_item Pointer to an item that will be added to the queue.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for the item to be queued.
|
|
*
|
|
* @retval >0 The number of items on the queue after adding
|
|
* the specified item.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int enqueue_tail (ACE_MESSAGE_TYPE *new_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Enqueue an item at the head of the queue.
|
|
*
|
|
* @param new_item Pointer to an item that will be added to the queue.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for the item to be queued.
|
|
*
|
|
* @retval >0 The number of items on the queue after adding
|
|
* the specified item.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int enqueue_head (ACE_MESSAGE_TYPE *new_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/// This method is an alias for the following <dequeue_head> method.
|
|
virtual int dequeue (ACE_MESSAGE_TYPE *&first_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Dequeue the item at the head of the queue and return a pointer to it.
|
|
*
|
|
* @param first_item Reference to an ACE_MESSAGE_TYPE * that will
|
|
* be set to the address of the dequeued item.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for an item to be dequeued.
|
|
*
|
|
* @retval >=0 The number of items remaining in the queue.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int dequeue_head (ACE_MESSAGE_TYPE *&first_item,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Dequeue the item that has the lowest priority (preserves
|
|
* FIFO order for items with the same priority) and return a pointer
|
|
* to it.
|
|
*
|
|
* @param dequeued Reference to an ACE_MESSAGE_TYPE * that will
|
|
* be set to the address of the dequeued item.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for an item to be dequeued.
|
|
*
|
|
* @retval >=0 The number of items remaining in the queue.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int dequeue_prio (ACE_MESSAGE_TYPE *&dequeued,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Dequeue the item at the tail of the queue and return a pointer to it.
|
|
*
|
|
* @param dequeued Reference to an ACE_MESSAGE_TYPE * that will
|
|
* be set to the address of the dequeued item.
|
|
* @param timeout The absolute time the caller will wait until
|
|
* for an item to be dequeued.
|
|
*
|
|
* @retval >=0 The number of items remaining in the queue.
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int dequeue_tail (ACE_MESSAGE_TYPE *&dequeued,
|
|
ACE_Time_Value *timeout = 0);
|
|
|
|
/**
|
|
* Because there's deadline associated with enqueue_deadline(), this
|
|
* method will behave just as dequeue_head().
|
|
*/
|
|
virtual int dequeue_deadline (ACE_MESSAGE_TYPE *&dequeued,
|
|
ACE_Time_Value *timeout = 0);
|
|
//@}
|
|
|
|
/** @name Queue statistics methods
|
|
*/
|
|
//@{
|
|
|
|
/// True if queue is full, else false.
|
|
virtual bool is_full (void);
|
|
|
|
/// True if queue is empty, else false.
|
|
virtual bool is_empty (void);
|
|
|
|
/**
|
|
* Number of total bytes on the queue, i.e., sum of the message
|
|
* block sizes.
|
|
*/
|
|
virtual size_t message_bytes (void);
|
|
/**
|
|
* Number of total length on the queue, i.e., sum of the message
|
|
* block lengths.
|
|
*/
|
|
virtual size_t message_length (void);
|
|
/**
|
|
* Number of total messages on the queue.
|
|
*/
|
|
virtual size_t message_count (void);
|
|
|
|
// = Manual changes to these stats (used when queued message blocks
|
|
// change size or lengths).
|
|
/**
|
|
* New value of the number of total bytes on the queue, i.e., sum of
|
|
* the message block sizes.
|
|
*/
|
|
virtual void message_bytes (size_t new_size);
|
|
/**
|
|
* New value of the number of total length on the queue, i.e., sum
|
|
* of the message block lengths.
|
|
*/
|
|
virtual void message_length (size_t new_length);
|
|
|
|
//@}
|
|
|
|
/** @name Water mark (flow control) methods
|
|
*/
|
|
//@{
|
|
|
|
/**
|
|
* Get high watermark.
|
|
*/
|
|
virtual size_t high_water_mark (void);
|
|
/**
|
|
* Set the high watermark, which determines how many bytes can be
|
|
* stored in a queue before it's considered "full."
|
|
*/
|
|
virtual void high_water_mark (size_t hwm);
|
|
|
|
/**
|
|
* Get low watermark.
|
|
*/
|
|
virtual size_t low_water_mark (void);
|
|
/**
|
|
* Set the low watermark, which determines how many bytes must be in
|
|
* the queue before supplier threads are allowed to enqueue
|
|
* additional <ACE_MESSAGE_TYPE>s.
|
|
*/
|
|
virtual void low_water_mark (size_t lwm);
|
|
//@}
|
|
|
|
/** @name Activation and queue state methods
|
|
* See C++NPv2 Section 6.2 and APG Section 12.3 for a fuller treatment of
|
|
* queue states and transitions and how the transitions affect message
|
|
* enqueueing and dequeueing operations.
|
|
*/
|
|
//@{
|
|
|
|
/**
|
|
* Deactivate the queue and wakeup all threads waiting on the queue
|
|
* so they can continue. No messages are removed from the queue,
|
|
* however. Any other operations called until the queue is
|
|
* activated again will immediately return -1 with @c errno ==
|
|
* ESHUTDOWN. Returns WAS_INACTIVE if queue was inactive before the
|
|
* call and WAS_ACTIVE if queue was active before the call.
|
|
*/
|
|
virtual int deactivate (void);
|
|
|
|
/**
|
|
* Reactivate the queue so that threads can enqueue and dequeue
|
|
* messages again. Returns the state of the queue before the call.
|
|
*/
|
|
virtual int activate (void);
|
|
|
|
/**
|
|
* Pulse the queue to wake up any waiting threads. Changes the
|
|
* queue state to PULSED; future enqueue/dequeue operations proceed
|
|
* as in ACTIVATED state.
|
|
*
|
|
* @retval The queue's state before this call.
|
|
*/
|
|
virtual int pulse (void);
|
|
|
|
/// Returns the current state of the queue, which can be one of
|
|
/// ACTIVATED, DEACTIVATED, or PULSED.
|
|
virtual int state (void);
|
|
|
|
/// Returns true if the state of the queue is DEACTIVATED,
|
|
/// but false if the queue's state is ACTIVATED or PULSED.
|
|
virtual int deactivated (void);
|
|
//@}
|
|
|
|
/** @name Notification strategy methods
|
|
*/
|
|
//@{
|
|
|
|
/**
|
|
* This hook is automatically invoked by <enqueue_head>,
|
|
* <enqueue_tail>, and <enqueue_prio> when a new item is inserted
|
|
* into the queue. Subclasses can override this method to perform
|
|
* specific notification strategies (e.g., signaling events for a
|
|
* <WFMO_Reactor>, notifying a <Reactor>, etc.). In a
|
|
* multi-threaded application with concurrent consumers, there is no
|
|
* guarantee that the queue will be still be non-empty by the time
|
|
* the notification occurs.
|
|
*/
|
|
virtual int notify (void);
|
|
|
|
/// Get the notification strategy for the <Message_Queue>
|
|
virtual ACE_Notification_Strategy *notification_strategy (void);
|
|
|
|
/// Set the notification strategy for the <Message_Queue>
|
|
virtual void notification_strategy (ACE_Notification_Strategy *s);
|
|
//@}
|
|
|
|
/// Returns a reference to the lock used by the ACE_Message_Queue_Ex.
|
|
virtual ACE_SYNCH_MUTEX_T &lock (void);
|
|
|
|
/// Dump the state of an object.
|
|
virtual void dump (void) const;
|
|
|
|
/// Declare the dynamic allocation hooks.
|
|
ACE_ALLOC_HOOK_DECLARE;
|
|
|
|
protected:
|
|
/// Implement this via an ACE_Message_Queue.
|
|
ACE_Message_Queue<ACE_SYNCH_USE> queue_;
|
|
};
|
|
|
|
/**
|
|
* @class ACE_Message_Queue_Ex_Iterator
|
|
*
|
|
* @brief Iterator for the ACE_Message_Queue_Ex.
|
|
*/
|
|
template <class ACE_MESSAGE_TYPE, ACE_SYNCH_DECL>
|
|
class ACE_Message_Queue_Ex_Iterator
|
|
{
|
|
public:
|
|
// = Initialization method.
|
|
ACE_Message_Queue_Ex_Iterator (ACE_Message_Queue_Ex<ACE_MESSAGE_TYPE, ACE_SYNCH_USE> & queue);
|
|
|
|
// = Iteration methods.
|
|
/// Pass back the @a entry that hasn't been seen in the queue.
|
|
/// Returns 0 when all items have been seen, else 1.
|
|
int next (ACE_MESSAGE_TYPE *&entry);
|
|
|
|
/// Returns 1 when all items have been seen, else 0.
|
|
int done (void) const;
|
|
|
|
/// Move forward by one element in the queue. Returns 0 when all the
|
|
/// items in the set have been seen, else 1.
|
|
int advance (void);
|
|
|
|
/// Dump the state of an object.
|
|
void dump (void) const;
|
|
|
|
/// Declare the dynamic allocation hooks.
|
|
ACE_ALLOC_HOOK_DECLARE;
|
|
|
|
private:
|
|
/// Implement this via the ACE_Message_Queue_Iterator
|
|
ACE_Message_Queue_Iterator<ACE_SYNCH_USE> iter_;
|
|
};
|
|
|
|
/**
|
|
* @class ACE_Message_Queue_Ex_Iterator
|
|
*
|
|
* @brief Reverse iterator for the ACE_Message_Queue_Ex.
|
|
*/
|
|
template <class ACE_MESSAGE_TYPE, ACE_SYNCH_DECL>
|
|
class ACE_Message_Queue_Ex_Reverse_Iterator
|
|
{
|
|
public:
|
|
// = Initialization method.
|
|
ACE_Message_Queue_Ex_Reverse_Iterator (ACE_Message_Queue_Ex<ACE_MESSAGE_TYPE, ACE_SYNCH_USE> & queue);
|
|
|
|
// = Iteration methods.
|
|
/// Pass back the @a entry that hasn't been seen in the queue.
|
|
/// Returns 0 when all items have been seen, else 1.
|
|
int next (ACE_MESSAGE_TYPE *&entry);
|
|
|
|
/// Returns 1 when all items have been seen, else 0.
|
|
int done (void) const;
|
|
|
|
/// Move forward by one element in the queue. Returns 0 when all the
|
|
/// items in the set have been seen, else 1.
|
|
int advance (void);
|
|
|
|
/// Dump the state of an object.
|
|
void dump (void) const;
|
|
|
|
/// Declare the dynamic allocation hooks.
|
|
ACE_ALLOC_HOOK_DECLARE;
|
|
|
|
private:
|
|
/// Implement this via the ACE_Message_Queue_Reverse_Iterator
|
|
ACE_Message_Queue_Reverse_Iterator<ACE_SYNCH_USE> iter_;
|
|
};
|
|
|
|
/**
|
|
* @class ACE_Message_Queue_Ex_N
|
|
*
|
|
* @brief A threaded message queueing facility, modeled after the
|
|
* queueing facilities in System V STREAMs which can enqueue
|
|
* multiple messages in one call.
|
|
*
|
|
* As ACE_Message_Queue_Ex, ACE_Message_Queue_Ex_N is a strongly-typed
|
|
* version of the ACE_Message_Queue. If @c ACE_SYNCH_DECL is @c ACE_MT_SYNCH
|
|
* then all operations are thread-safe. Otherwise, if it's @c ACE_NULL_SYNCH
|
|
* then there's no locking overhead.
|
|
*
|
|
* The @c ACE_MESSAGE_TYPE messages that are sent to this
|
|
* queue can be chained. Messages are expected to have a
|
|
* @c next method that returns the next message in the chain;
|
|
* ACE_Message_Queue_Ex_N uses this method to run through
|
|
* all the incoming messages and enqueue them in one call.
|
|
*/
|
|
template <class ACE_MESSAGE_TYPE, ACE_SYNCH_DECL>
|
|
class ACE_Message_Queue_Ex_N : public ACE_Message_Queue_Ex<ACE_MESSAGE_TYPE, ACE_SYNCH_USE>
|
|
{
|
|
public:
|
|
// = Initialization and termination methods.
|
|
|
|
/**
|
|
* Initialize an ACE_Message_Queue_Ex_N. The @a high_water_mark
|
|
* determines how many bytes can be stored in a queue before it's
|
|
* considered "full." Supplier threads must block until the queue
|
|
* is no longer full. The @a low_water_mark determines how many
|
|
* bytes must be in the queue before supplier threads are allowed to
|
|
* enqueue additional messages. By default, the @a high_water_mark
|
|
* equals the @a low_water_mark, which means that suppliers will be
|
|
* able to enqueue new messages as soon as a consumer removes any message
|
|
* from the queue. Making the @a low_water_mark smaller than the
|
|
* @a high_water_mark forces consumers to drain more messages from the
|
|
* queue before suppliers can enqueue new messages, which can minimize
|
|
* the "silly window syndrome."
|
|
*/
|
|
ACE_Message_Queue_Ex_N (size_t high_water_mark = ACE_Message_Queue_Base::DEFAULT_HWM,
|
|
size_t low_water_mark = ACE_Message_Queue_Base::DEFAULT_LWM,
|
|
ACE_Notification_Strategy * ns = 0);
|
|
|
|
/// Close down the message queue and release all resources.
|
|
virtual ~ACE_Message_Queue_Ex_N (void);
|
|
|
|
/**
|
|
* Enqueue one or more @c ACE_MESSAGE_TYPE objects at the head of the queue.
|
|
* If the @a new_item @c next() pointer is non-zero, it is assumed to be the
|
|
* start of a series of @c ACE_MESSAGE_TYPE objects connected via their
|
|
* @c next() pointers. The series of blocks will be added to the queue in
|
|
* the same order they are passed in as.
|
|
*
|
|
* @param new_item Pointer to an @c ACE_MESSAGE_TYPE that will be
|
|
* added to the queue. If the block's @c next() pointer
|
|
* is non-zero, all blocks chained from the @c next()
|
|
* pointer are enqueued as well.
|
|
* @param tv The absolute time the caller will wait until
|
|
* for the block to be queued.
|
|
*
|
|
* @retval >0 The number of @c ACE_MESSAGE_TYPE objects on the queue after
|
|
* adding the specified block(s).
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int enqueue_head (ACE_MESSAGE_TYPE *new_item, ACE_Time_Value *tv = 0);
|
|
|
|
/**
|
|
* Enqueue one or more @c ACE_MESSAGE_TYPE objects at the tail of the queue.
|
|
* If the @a new_item @c next() pointer is non-zero, it is assumed to be the
|
|
* start of a series of @c ACE_MESSAGE_TYPE objects connected via their
|
|
* @c next() pointers. The series of blocks will be added to the queue in
|
|
* the same order they are passed in as.
|
|
*
|
|
* @param new_item Pointer to an @c ACE_MESSAGE_TYPE that will be
|
|
* added to the queue. If the block's @c next() pointer
|
|
* is non-zero, all blocks chained from the @c next()
|
|
* pointer are enqueued as well.
|
|
* @param tv The absolute time the caller will wait until
|
|
* for the block to be queued.
|
|
*
|
|
* @retval >0 The number of @c ACE_MESSAGE_TYPE objects on the queue after
|
|
* adding the specified block(s).
|
|
* @retval -1 On failure. errno holds the reason. Common errno values are:
|
|
* - EWOULDBLOCK: the timeout elapsed
|
|
* - ESHUTDOWN: the queue was deactivated or pulsed
|
|
*/
|
|
virtual int enqueue_tail (ACE_MESSAGE_TYPE *new_item, ACE_Time_Value *tv = 0);
|
|
|
|
/// Declare the dynamic allocation hooks.
|
|
ACE_ALLOC_HOOK_DECLARE;
|
|
|
|
protected:
|
|
/**
|
|
* An helper method that wraps the incoming chain messages
|
|
* with ACE_Message_Blocks.
|
|
*/
|
|
ACE_Message_Block *wrap_with_mbs_i (ACE_MESSAGE_TYPE *new_item);
|
|
};
|
|
|
|
ACE_END_VERSIONED_NAMESPACE_DECL
|
|
|
|
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
|
|
#include "ace/Message_Queue_T.cpp"
|
|
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
|
|
|
|
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
|
|
#pragma implementation ("Message_Queue_T.cpp")
|
|
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
|
|
|
|
#include /**/ "ace/post.h"
|
|
|
|
#endif /* ACE_MESSAGE_QUEUE_T_H */
|