00001 #ifndef ACE_NOTIFICATION_QUEUE_H 00002 #define ACE_NOTIFICATION_QUEUE_H 00003 00004 #include /**/ "ace/pre.h" 00005 00006 /** 00007 * @file Notification_Queue.h 00008 * 00009 * $Id: Notification_Queue.h 79332 2007-08-13 20:30:44Z sowayaa $ 00010 * 00011 * @author Carlos O'Ryan <coryan@atdesk.com> 00012 */ 00013 #include "ace/Copy_Disabled.h" 00014 #include "ace/Event_Handler.h" 00015 #include "ace/Intrusive_List.h" 00016 #include "ace/Intrusive_List_Node.h" 00017 #include "ace/Unbounded_Queue.h" 00018 00019 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00020 00021 /** 00022 * @class ACE_Notification_Queue_Node 00023 * 00024 * @brief Helper class 00025 */ 00026 class ACE_Export ACE_Notification_Queue_Node 00027 : public ACE_Intrusive_List_Node<ACE_Notification_Queue_Node> 00028 { 00029 public: 00030 /** 00031 * @brief Constructor 00032 */ 00033 ACE_Notification_Queue_Node(); 00034 00035 /** 00036 * @brief Modifier change the contained buffer 00037 */ 00038 void set(ACE_Notification_Buffer const & rhs); 00039 00040 /** 00041 * @brief Accessor, fetch the contained buffer 00042 */ 00043 ACE_Notification_Buffer const & get() const; 00044 00045 /** 00046 * @brief Checks if the event handler matches the purge condition 00047 */ 00048 bool matches_for_purging(ACE_Event_Handler * eh) const; 00049 00050 /** 00051 * @brief Return true if clearing the mask would leave no 00052 * notifications to deliver. 00053 */ 00054 bool mask_disables_all_notifications(ACE_Reactor_Mask mask); 00055 00056 /** 00057 * @brief Clear the notifications specified by @c mask 00058 */ 00059 void clear_mask(ACE_Reactor_Mask mask); 00060 00061 private: 00062 ACE_Notification_Buffer contents_; 00063 }; 00064 00065 /** 00066 * @class ACE_Notification_Queue 00067 * 00068 * @brief Implements a user-space queue to send Reactor notifications. 00069 * 00070 * The ACE_Reactor uses a pipe to send wake up the thread running the 00071 * event loop from other threads. This pipe can be limited in size 00072 * under some operating systems. For some applications, this limit 00073 * presents a problem. A user-space notification queue is used to 00074 * overcome those limitations. The queue tries to use as few 00075 * resources on the pipe as possible, while keeping all the data in 00076 * user space. 00077 * 00078 * This code was refactored from Select_Reactor_Base. 00079 */ 00080 class ACE_Export ACE_Notification_Queue : private ACE_Copy_Disabled 00081 { 00082 public: 00083 ACE_Notification_Queue(); 00084 ~ACE_Notification_Queue(); 00085 00086 /** 00087 * @brief Pre-allocate resources in the queue 00088 */ 00089 int open(); 00090 00091 /** 00092 * @brief Release all resources in the queue 00093 */ 00094 void reset(); 00095 00096 /** 00097 * @brief Remove all elements in the queue matching @c eh and @c mask 00098 * 00099 * I suggest reading the documentation in ACE_Reactor to find a more 00100 * detailed description. This is just a helper function. 00101 */ 00102 int purge_pending_notifications(ACE_Event_Handler * eh, 00103 ACE_Reactor_Mask mask); 00104 00105 /** 00106 * @brief Add a new notification to the queue 00107 * 00108 * @return -1 on failure, 1 if a new message should be sent through 00109 * the pipe and 0 otherwise. 00110 */ 00111 int push_new_notification(ACE_Notification_Buffer const & buffer); 00112 00113 /** 00114 * @brief Extract the next notification from the queue 00115 * 00116 * @return -1 on failure, 1 if a message was popped, 0 otherwise 00117 */ 00118 int pop_next_notification( 00119 ACE_Notification_Buffer & current, 00120 bool & more_messages_queued, 00121 ACE_Notification_Buffer & next); 00122 00123 private: 00124 /** 00125 * @brief Allocate more memory for the queue 00126 */ 00127 int allocate_more_buffers(); 00128 00129 private: 00130 /// Keeps track of allocated arrays of type 00131 /// ACE_Notification_Buffer. The idea is to amortize allocation 00132 /// costs by allocating multiple ACE_Notification_Buffer objects at 00133 /// a time. 00134 ACE_Unbounded_Queue <ACE_Notification_Queue_Node*> alloc_queue_; 00135 00136 typedef ACE_Intrusive_List<ACE_Notification_Queue_Node> Buffer_List; 00137 00138 /// Keeps track of all pending notifications. 00139 Buffer_List notify_queue_; 00140 00141 /// Keeps track of all free buffers. 00142 Buffer_List free_queue_; 00143 00144 /// Synchronization for handling of queues. 00145 ACE_SYNCH_MUTEX notify_queue_lock_; 00146 }; 00147 00148 ACE_END_VERSIONED_NAMESPACE_DECL 00149 00150 #if defined (__ACE_INLINE__) 00151 #include "ace/Notification_Queue.inl" 00152 #endif /* __ACE_INLINE__ */ 00153 00154 #include /**/ "ace/post.h" 00155 00156 #endif /* ACE_NOTIFICATION_QUEUE_H */