Use override/default for RTPortableServer
[ACE_TAO.git] / ACE / ace / Select_Reactor_Base.h
blob4ffa1d80640ce0191f1bda90858161706a45b50e
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Select_Reactor_Base.h
7 * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
8 */
9 //=============================================================================
11 #ifndef ACE_SELECT_REACTOR_BASE_H
12 #define ACE_SELECT_REACTOR_BASE_H
14 #include /**/ "ace/pre.h"
16 #include "ace/Timer_Queuefwd.h"
18 #if !defined (ACE_LACKS_PRAGMA_ONCE)
19 # pragma once
20 #endif /* ACE_LACKS_PRAGMA_ONCE */
22 #include "ace/Event_Handler.h"
23 #include "ace/Handle_Set.h"
24 #include "ace/Pipe.h"
25 #include "ace/Reactor_Impl.h"
27 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
28 # include "ace/Notification_Queue.h"
29 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
31 #if defined (ACE_WIN32) || defined (ACE_MQX)
32 # ifndef ACE_SELECT_REACTOR_BASE_USES_HASH_MAP
33 # define ACE_SELECT_REACTOR_BASE_USES_HASH_MAP
34 # endif
35 #endif
37 #ifdef ACE_SELECT_REACTOR_BASE_USES_HASH_MAP
38 # include "ace/Null_Mutex.h"
39 # include "ace/Hash_Map_Manager_T.h"
40 # include "ace/Functor.h" /* For ACE_Hash<void *> */
41 # include <functional> /* For std::equal_to<> */
42 #else
43 # include "ace/Array_Base.h"
44 #endif /* ACE_SELECT_REACTOR_BASE_USES_HASH_MAP */
46 #if !defined (ACE_DISABLE_NOTIFY_PIPE_DEFAULT)
47 # define ACE_DISABLE_NOTIFY_PIPE_DEFAULT 0
48 #endif /* ACE_DISABLE_NOTIFY_PIPE_DEFAULT */
50 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
52 // Add useful typedefs to simplify the following code.
53 typedef void (ACE_Handle_Set::*ACE_FDS_PTMF) (ACE_HANDLE);
54 typedef int (ACE_Event_Handler::*ACE_EH_PTMF) (ACE_HANDLE);
56 // Forward declaration.
57 class ACE_Select_Reactor_Impl;
58 class ACE_Sig_Handler;
60 /**
61 * @class ACE_Select_Reactor_Handle_Set
63 * @brief Track handles we are interested for various events.
65 class ACE_Export ACE_Select_Reactor_Handle_Set
67 public:
68 /// Read events (e.g., input pending, accept pending).
69 ACE_Handle_Set rd_mask_;
71 /// Write events (e.g., flow control abated, non-blocking connection
72 /// complete).
73 ACE_Handle_Set wr_mask_;
75 /// Exception events (e.g., SIG_URG).
76 ACE_Handle_Set ex_mask_;
79 /**
80 * @class ACE_Event_Tuple
82 * @brief An ACE_Event_Handler and its associated ACE_HANDLE.
84 * One ACE_Event_Handler is registered for one or more
85 * ACE_HANDLE. At various points, this information must be
86 * stored explicitly. This class provides a lightweight
87 * mechanism to do so.
89 class ACE_Event_Tuple
91 public:
92 /// Default constructor.
93 ACE_Event_Tuple ();
95 /// Constructor.
96 ACE_Event_Tuple (ACE_Event_Handler *eh, ACE_HANDLE h);
98 /// Equality operator.
99 bool operator== (const ACE_Event_Tuple &rhs) const;
101 /// Inequality operator.
102 bool operator!= (const ACE_Event_Tuple &rhs) const;
104 public:
105 /// Handle.
106 ACE_HANDLE handle_;
108 /// ACE_Event_Handler associated with the ACE_HANDLE.
109 ACE_Event_Handler *event_handler_;
113 * @class ACE_Select_Reactor_Notify
115 * @brief Unblock the ACE_Select_Reactor from its event loop.
117 * This implementation is necessary for cases where the
118 * ACE_Select_Reactor is run in a multi-threaded program. In
119 * this case, we need to be able to unblock @c select or @c poll
120 * when updates occur other than in the main
121 * ACE_Select_Reactor thread. To do this, we signal an
122 * auto-reset event the ACE_Select_Reactor is listening on.
123 * If an ACE_Event_Handler and ACE_Select_Reactor_Mask is
124 * passed to @c notify, the appropriate @c handle_* method is
125 * dispatched in the context of the ACE_Select_Reactor thread.
127 class ACE_Export ACE_Select_Reactor_Notify : public ACE_Reactor_Notify
129 public:
130 /// Constructor.
131 ACE_Select_Reactor_Notify ();
133 /// Destructor.
134 virtual ~ACE_Select_Reactor_Notify ();
136 /// Initialize.
137 virtual int open (ACE_Reactor_Impl *,
138 ACE_Timer_Queue * = 0,
139 int disable_notify_pipe = ACE_DISABLE_NOTIFY_PIPE_DEFAULT);
141 /// Destroy.
142 virtual int close ();
145 * Called by a thread when it wants to unblock the
146 * ACE_Select_Reactor. This wakeups the ACE_Select_Reactor if
147 * currently blocked in @c select/poll. Pass over both the
148 * @c Event_Handler *and* the @c mask to allow the caller to dictate
149 * which @c Event_Handler method the ACE_Select_Reactor will
150 * invoke. The ACE_Time_Value indicates how long to blocking
151 * trying to notify the ACE_Select_Reactor. If @a timeout == 0,
152 * the caller will block until action is possible, else will wait
153 * until the relative time specified in @c *timeout elapses).
155 virtual int notify (ACE_Event_Handler * = 0,
156 ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
157 ACE_Time_Value * timeout = 0);
159 /// Handles pending threads (if any) that are waiting to unblock the
160 /// ACE_Select_Reactor.
161 virtual int dispatch_notifications (int &number_of_active_handles,
162 ACE_Handle_Set &rd_mask);
164 /// Returns the ACE_HANDLE of the notify pipe on which the reactor
165 /// is listening for notifications so that other threads can unblock
166 /// the Select_Reactor
167 virtual ACE_HANDLE notify_handle ();
169 /// Handle one of the notify call on the @c handle. This could be
170 /// because of a thread trying to unblock the Reactor_Impl
171 virtual int dispatch_notify (ACE_Notification_Buffer &buffer);
173 /// Read one of the notify call on the @a handle into the
174 /// @a buffer. This could be because of a thread trying to unblock
175 /// the Reactor_Impl
177 /// Return value semantics for this are:
178 /// -1: nothing read, fatal, unrecoverable error
179 /// 0: nothing read at all
180 /// 1: complete buffer read
181 virtual int read_notify_pipe (ACE_HANDLE handle,
182 ACE_Notification_Buffer &buffer);
184 /// Verify whether the buffer has dispatchable info or not.
185 virtual int is_dispatchable (ACE_Notification_Buffer &buffer);
187 /// Called back by the ACE_Select_Reactor when a thread wants to
188 /// unblock us.
189 virtual int handle_input (ACE_HANDLE handle);
192 * Set the maximum number of times that the
193 * ACE_Select_Reactor_Notify::handle_input() method will iterate and
194 * dispatch the ACE_Event_Handlers that are passed in via the
195 * notify pipe before breaking out of its @c recv loop. By default,
196 * this is set to -1, which means "iterate until the pipe is empty."
197 * Setting this to a value like "1 or 2" will increase "fairness"
198 * (and thus prevent starvation) at the expense of slightly higher
199 * dispatching overhead.
201 virtual void max_notify_iterations (int);
204 * Get the maximum number of times that the
205 * ACE_Select_Reactor_Notify::handle_input() method will iterate and
206 * dispatch the ACE_Event_Handlers that are passed in via the
207 * notify pipe before breaking out of its recv loop.
209 virtual int max_notify_iterations ();
212 * Purge any notifications pending in this reactor for the specified
213 * ACE_Event_Handler object. If @a eh == 0, all notifications for all
214 * handlers are removed (but not any notifications posted just to wake up
215 * the reactor itself). Returns the number of notifications purged.
216 * Returns -1 on error.
218 virtual int purge_pending_notifications (
219 ACE_Event_Handler *sh,
220 ACE_Reactor_Mask mask = ACE_Event_Handler::ALL_EVENTS_MASK);
222 /// Dump the state of an object.
223 virtual void dump () const;
225 /// Declare the dynamic allocation hooks.
226 ACE_ALLOC_HOOK_DECLARE;
228 protected:
230 * Keep a back pointer to the ACE_Select_Reactor. If this value
231 * if NULL then the ACE_Select_Reactor has been initialized with
232 * disable_notify_pipe.
234 ACE_Select_Reactor_Impl *select_reactor_;
237 * Contains the ACE_HANDLE the ACE_Select_Reactor is listening
238 * on, as well as the ACE_HANDLE that threads wanting the
239 * attention of the ACE_Select_Reactor will write to.
241 ACE_Pipe notification_pipe_;
244 * Keeps track of the maximum number of times that the
245 * ACE_Select_Reactor_Notify::handle_input() method will iterate and
246 * dispatch the ACE_Event_Handlers that are passed in via the
247 * notify pipe before breaking out of its recv loop. By default,
248 * this is set to -1, which means "iterate until the pipe is empty."
250 int max_notify_iterations_;
252 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
254 * @brief A user-space queue to store the notifications.
256 * The notification pipe has OS-specific size restrictions. That
257 * is, no more than a certain number of bytes may be stored in the
258 * pipe without blocking. This limit may be too small for certain
259 * applications. In this case, ACE can be configured to store all
260 * the events in user-space. The pipe is still needed to wake up
261 * the reactor thread, but only one event is sent through the pipe
262 * at a time.
264 ACE_Notification_Queue notification_queue_;
265 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
269 * @class ACE_Select_Reactor_Handler_Repository
271 * @brief Used to map ACE_HANDLEs onto the appropriate
272 * ACE_Event_Handler *.
274 * This class is necessary to shield differences between UNIX
275 * and Win32. In UNIX, ACE_HANDLE is an int, whereas in Win32
276 * it's a void *. This class hides all these details from the
277 * bulk of the ACE_Select_Reactor code. All of these methods
278 * are called with the main <Select_Reactor> token lock held.
280 class ACE_Export ACE_Select_Reactor_Handler_Repository
282 public:
283 friend class ACE_Select_Reactor_Handler_Repository_Iterator;
285 typedef ACE_HANDLE key_type;
286 typedef ACE_Event_Handler * value_type;
288 // = The mapping from <HANDLES> to <Event_Handlers>.
289 #ifdef ACE_SELECT_REACTOR_BASE_USES_HASH_MAP
291 * The NT version implements this via a hash map
292 * @c ACE_Event_Handler*. Since NT implements @c ACE_HANDLE
293 * as a void * we can't directly index into this array. Therefore,
294 * we must explicitly map @c ACE_HANDLE to @c ACE_Event_Handler.
296 typedef ACE_Hash_Map_Manager_Ex<key_type,
297 value_type,
298 ACE_Hash<key_type>,
299 std::equal_to<key_type>,
300 ACE_Null_Mutex> map_type;
302 typedef map_type::size_type max_handlep1_type;
303 #else
305 * The UNIX version implements this via a dynamically allocated
306 * array of @c ACE_Event_Handler* that is indexed directly using
307 * the @c ACE_HANDLE value.
309 typedef ACE_Array_Base<value_type> map_type;
310 typedef ACE_HANDLE max_handlep1_type;
311 #endif /* ACE_SELECT_REACTOR_BASE_USES_HASH_MAP */
313 typedef map_type::size_type size_type;
315 /// Default "do-nothing" constructor.
316 ACE_Select_Reactor_Handler_Repository (ACE_Select_Reactor_Impl &);
318 /// Initialize a repository of the appropriate @a size.
320 * On Unix platforms, the size parameter should be as large as the
321 * maximum number of file descriptors allowed for a given process.
322 * This is necessary since a file descriptor is used to directly
323 * index the array of event handlers maintained by the Reactor's
324 * handler repository. Direct indexing is used for efficiency
325 * reasons.
327 int open (size_type size);
329 /// Close down the repository.
330 int close ();
332 // = Search structure operations.
335 * Return the @c ACE_Event_Handler* associated with @c ACE_HANDLE.
337 ACE_Event_Handler * find (ACE_HANDLE handle);
339 /// Bind the ACE_Event_Handler * to the ACE_HANDLE with the
340 /// appropriate ACE_Reactor_Mask settings.
341 int bind (ACE_HANDLE,
342 ACE_Event_Handler *,
343 ACE_Reactor_Mask);
345 /// Remove the binding of ACE_HANDLE in accordance with the @a mask.
346 int unbind (ACE_HANDLE,
347 ACE_Reactor_Mask mask);
349 /// Remove all the <ACE_HANDLE, ACE_Event_Handler> tuples.
350 int unbind_all ();
352 // = Sanity checking.
354 // Check the @a handle to make sure it's a valid @c ACE_HANDLE that
355 // is within the range of legal handles (i.e., >= 0 && < max_size_).
356 bool invalid_handle (ACE_HANDLE handle);
358 // Check the @a handle to make sure it's a valid @c ACE_HANDLE that
359 // within the range of currently registered handles (i.e., >= 0 && <
360 // @c max_handlep1_).
361 bool handle_in_range (ACE_HANDLE handle);
363 // = Accessors.
364 /// Returns the current table size.
365 size_type size () const;
367 /// Maximum ACE_HANDLE value, plus 1.
368 max_handlep1_type max_handlep1 () const;
370 /// Dump the state of an object.
371 void dump () const;
373 /// Declare the dynamic allocation hooks.
374 ACE_ALLOC_HOOK_DECLARE;
376 private:
377 /// Remove the binding of @a handle corresponding to position @a pos
378 /// in accordance with the @a mask.
379 int unbind (ACE_HANDLE handle,
380 map_type::iterator pos,
381 ACE_Reactor_Mask mask);
384 * @return @c iterator corresponding @c ACE_Event_Handler*
385 * associated with @c ACE_HANDLE.
387 map_type::iterator find_eh (ACE_HANDLE handle);
389 private:
390 /// Reference to our @c Select_Reactor.
391 ACE_Select_Reactor_Impl &select_reactor_;
393 #ifndef ACE_SELECT_REACTOR_BASE_USES_HASH_MAP
394 /// The highest currently active handle, plus 1 (ranges between 0 and
395 /// @c max_size_.
396 max_handlep1_type max_handlep1_;
397 #endif /* !ACE_SELECT_REACTOR_BASE_USES_HASH_MAP */
399 /// Underlying table of event handlers.
400 map_type event_handlers_;
404 * @class ACE_Select_Reactor_Handler_Repository_Iterator
406 * @brief Iterate through the ACE_Select_Reactor_Handler_Repository.
408 class ACE_Export ACE_Select_Reactor_Handler_Repository_Iterator
410 public:
411 typedef
412 ACE_Select_Reactor_Handler_Repository::map_type::const_iterator const_base_iterator;
414 explicit ACE_Select_Reactor_Handler_Repository_Iterator (
415 ACE_Select_Reactor_Handler_Repository const * s);
417 // = Iteration methods.
419 /// Pass back the @a next_item that hasn't been seen in the Set.
420 /// Returns @c false when all items have been seen, else @c true.
421 bool next (ACE_Event_Handler* & next_item);
423 /// Returns @c true when all items have been seen, else @c false.
424 bool done () const;
426 /// Move forward by one element in the set. Returns @c false when
427 /// all the items in the set have been seen, else @c true.
428 bool advance ();
430 /// Dump the state of an object.
431 void dump () const;
433 /// Declare the dynamic allocation hooks.
434 ACE_ALLOC_HOOK_DECLARE;
436 private:
437 /// Reference to the Handler_Repository we are iterating over.
438 ACE_Select_Reactor_Handler_Repository const * const rep_;
440 /// Pointer to the current iteration level.
441 const_base_iterator current_;
445 * @class ACE_Select_Reactor_Impl
447 * @brief This class simply defines how Select_Reactor's basic interface
448 * functions should look like and provides a common base class for
449 * @c Select_Reactor using various locking mechanism.
451 class ACE_Export ACE_Select_Reactor_Impl : public ACE_Reactor_Impl
453 public:
454 enum
456 /// Default size of the Select_Reactor's handle table.
457 DEFAULT_SIZE = ACE_DEFAULT_SELECT_REACTOR_SIZE
460 /// Constructor.
461 ACE_Select_Reactor_Impl (bool mask_signals = true);
463 friend class ACE_Select_Reactor_Notify;
464 friend class ACE_Select_Reactor_Handler_Repository;
467 * Purge any notifications pending in this reactor for the specified
468 * ACE_Event_Handler object. Returns the number of notifications
469 * purged. Returns -1 on error.
471 virtual int purge_pending_notifications (ACE_Event_Handler * = 0,
472 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
474 /// Does the reactor allow the application to resume the handle on
475 /// its own ie. can it pass on the control of handle resumption to
476 /// the application. The select reactor has no handlers that can be
477 /// resumed by the application. So return 0;
478 virtual int resumable_handler ();
480 protected:
481 /// Allow manipulation of the <wait_set_> mask and <ready_set_> mask.
482 virtual int bit_ops (ACE_HANDLE handle,
483 ACE_Reactor_Mask mask,
484 ACE_Select_Reactor_Handle_Set &handle_set,
485 int ops);
487 /// Enqueue ourselves into the list of waiting threads at the
488 /// appropriate point specified by <requeue_position_>.
489 virtual void renew () = 0;
491 /// Check to see if the Event_Handler associated with @a handle is
492 /// suspended. Returns 0 if not, 1 if so.
493 virtual int is_suspended_i (ACE_HANDLE handle) = 0;
495 /// When register/unregister occur, then we need to re-eval our
496 /// wait/suspend/dispatch set.
497 virtual void clear_dispatch_mask (ACE_HANDLE handle,
498 ACE_Reactor_Mask mask);
500 /// Table that maps <ACE_HANDLEs> to <ACE_Event_Handler *>'s.
501 ACE_Select_Reactor_Handler_Repository handler_rep_;
503 /// Tracks handles that are ready for dispatch from <select>
504 ACE_Select_Reactor_Handle_Set dispatch_set_;
506 /// Tracks handles that are waited for by <select>.
507 ACE_Select_Reactor_Handle_Set wait_set_;
509 /// Tracks handles that are currently suspended.
510 ACE_Select_Reactor_Handle_Set suspend_set_;
512 /// Track HANDLES we are interested in for various events that must
513 /// be dispatched *without* going through <select>.
514 ACE_Select_Reactor_Handle_Set ready_set_;
516 /// Defined as a pointer to allow overriding by derived classes...
517 ACE_Timer_Queue *timer_queue_;
519 /// Handle signals without requiring global/static variables.
520 ACE_Sig_Handler *signal_handler_;
522 /// Callback object that unblocks the ACE_Select_Reactor if it's
523 /// sleeping.
524 ACE_Reactor_Notify *notify_handler_;
526 /// Keeps track of whether we should delete the timer queue (if we
527 /// didn't create it, then we don't delete it).
528 bool delete_timer_queue_;
530 /// Keeps track of whether we should delete the signal handler (if we
531 /// didn't create it, then we don't delete it).
532 bool delete_signal_handler_;
534 /// Keeps track of whether we need to delete the notify handler (if
535 /// we didn't create it, then we don't delete it).
536 bool delete_notify_handler_;
538 /// True if we've been initialized yet...
539 bool initialized_;
541 /// Restart the <handle_events> event-loop method automatically when
542 /// <select> is interrupted via <EINTR>.
543 bool restart_;
546 * Position that the main ACE_Select_Reactor thread is requeued in
547 * the list of waiters during a <notify> callback. If this value ==
548 * -1 we are requeued at the end of the list. Else if it's 0 then
549 * we are requeued at the front of the list. Else if it's > 1 then
550 * that indicates the number of waiters to skip over.
552 int requeue_position_;
554 /// The original thread that created this Select_Reactor.
555 ACE_thread_t owner_;
558 * True if state has changed during dispatching of
559 * ACE_Event_Handlers, else false. This is used to determine
560 * whether we need to make another trip through the
561 * <Select_Reactor>'s <wait_for_multiple_events> loop.
563 bool state_changed_;
566 * If false then the Reactor will not mask the signals during the event
567 * dispatching. This is useful for applications that do not
568 * register any signal handlers and want to reduce the overhead
569 * introduce by the kernel level locks required to change the mask.
571 bool mask_signals_;
573 /// Controls/access whether the notify handler should renew the
574 /// Select_Reactor's token or not.
575 bool supress_notify_renew ();
576 void supress_notify_renew (bool sr);
578 private:
579 /// Determine whether we should renew Select_Reactor's token after handling
580 /// the notification message.
581 bool supress_renew_;
583 ACE_Select_Reactor_Impl (const ACE_Select_Reactor_Impl &) = delete;
584 ACE_Select_Reactor_Impl &operator = (const ACE_Select_Reactor_Impl &) = delete;
587 ACE_END_VERSIONED_NAMESPACE_DECL
589 #if defined (__ACE_INLINE__)
590 #include "ace/Select_Reactor_Base.inl"
591 #endif /* __ACE_INLINE__ */
593 #include /**/ "ace/post.h"
595 #endif /* ACE_SELECT_REACTOR_BASE_H */