[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / dep / ACE_wrappers / ace / Select_Reactor_Base.h
blob085cdb13d3d597e607c9b3628385bd31494034ee
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Select_Reactor_Base.h
7 * $Id: Select_Reactor_Base.h 82393 2008-07-23 10:52:34Z johnnyw $
9 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
11 //=============================================================================
13 #ifndef ACE_SELECT_REACTOR_BASE_H
14 #define ACE_SELECT_REACTOR_BASE_H
16 #include /**/ "ace/pre.h"
18 #include "ace/Timer_Queuefwd.h"
20 #if !defined (ACE_LACKS_PRAGMA_ONCE)
21 # pragma once
22 #endif /* ACE_LACKS_PRAGMA_ONCE */
24 #include "ace/Event_Handler.h"
25 #include "ace/Handle_Set.h"
26 #include "ace/Pipe.h"
27 #include "ace/Reactor_Impl.h"
29 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
30 # include "ace/Notification_Queue.h"
31 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
33 #ifdef ACE_WIN32
34 # include "ace/Null_Mutex.h"
35 # include "ace/Hash_Map_Manager_T.h"
36 # include "ace/Functor.h" /* For ACE_Hash<void *> */
37 # include <functional> /* For std::equal_to<> */
38 #else
39 # include "ace/Array_Base.h"
40 #endif /* ACE_WIN32 */
42 #if !defined (ACE_DISABLE_NOTIFY_PIPE_DEFAULT)
43 # define ACE_DISABLE_NOTIFY_PIPE_DEFAULT 0
44 #endif /* ACE_DISABLE_NOTIFY_PIPE_DEFAULT */
46 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
48 // Add useful typedefs to simplify the following code.
49 typedef void (ACE_Handle_Set::*ACE_FDS_PTMF) (ACE_HANDLE);
50 typedef int (ACE_Event_Handler::*ACE_EH_PTMF) (ACE_HANDLE);
52 // Forward declaration.
53 class ACE_Select_Reactor_Impl;
54 class ACE_Sig_Handler;
57 * Hook to specialize the Select_Reactor_Base implementation
58 * with the concrete reactor, e.g., select or tp reactor
59 * specified at build/compilation time.
61 //@@ REACTOR_SPL_INCLUDE_FORWARD_DECL_ADD_HOOK
63 /**
64 * @class ACE_Select_Reactor_Handle_Set
66 * @brief Track handles we are interested for various events.
68 class ACE_Export ACE_Select_Reactor_Handle_Set
70 public:
71 /// Read events (e.g., input pending, accept pending).
72 ACE_Handle_Set rd_mask_;
74 /// Write events (e.g., flow control abated, non-blocking connection
75 /// complete).
76 ACE_Handle_Set wr_mask_;
78 /// Exception events (e.g., SIG_URG).
79 ACE_Handle_Set ex_mask_;
82 /**
83 * @class ACE_Event_Tuple
85 * @brief An ACE_Event_Handler and its associated ACE_HANDLE.
87 * One ACE_Event_Handler is registered for one or more
88 * ACE_HANDLE. At various points, this information must be
89 * stored explicitly. This class provides a lightweight
90 * mechanism to do so.
92 class ACE_Event_Tuple
94 public:
96 /// Default constructor.
97 ACE_Event_Tuple (void);
99 /// Constructor.
100 ACE_Event_Tuple (ACE_Event_Handler *eh, ACE_HANDLE h);
102 /// Equality operator.
103 bool operator== (const ACE_Event_Tuple &rhs) const;
105 /// Inequality operator.
106 bool operator!= (const ACE_Event_Tuple &rhs) const;
108 public:
110 /// Handle.
111 ACE_HANDLE handle_;
113 /// ACE_Event_Handler associated with the ACE_HANDLE.
114 ACE_Event_Handler *event_handler_;
119 * @class ACE_Select_Reactor_Notify
121 * @brief Unblock the ACE_Select_Reactor from its event loop.
123 * This implementation is necessary for cases where the
124 * ACE_Select_Reactor is run in a multi-threaded program. In
125 * this case, we need to be able to unblock @c select or @c poll
126 * when updates occur other than in the main
127 * ACE_Select_Reactor thread. To do this, we signal an
128 * auto-reset event the ACE_Select_Reactor is listening on.
129 * If an ACE_Event_Handler and ACE_Select_Reactor_Mask is
130 * passed to @c notify, the appropriate @c handle_* method is
131 * dispatched in the context of the ACE_Select_Reactor thread.
133 class ACE_Export ACE_Select_Reactor_Notify : public ACE_Reactor_Notify
135 public:
136 /// Constructor.
137 ACE_Select_Reactor_Notify (void);
139 /// Destructor.
140 virtual ~ACE_Select_Reactor_Notify (void);
142 // = Initialization and termination methods.
143 /// Initialize.
144 virtual int open (ACE_Reactor_Impl *,
145 ACE_Timer_Queue * = 0,
146 int disable_notify_pipe = ACE_DISABLE_NOTIFY_PIPE_DEFAULT);
148 /// Destroy.
149 virtual int close (void);
152 * Called by a thread when it wants to unblock the
153 * ACE_Select_Reactor. This wakeups the ACE_Select_Reactor if
154 * currently blocked in @c select/poll. Pass over both the
155 * @c Event_Handler *and* the @c mask to allow the caller to dictate
156 * which @c Event_Handler method the ACE_Select_Reactor will
157 * invoke. The ACE_Time_Value indicates how long to blocking
158 * trying to notify the ACE_Select_Reactor. If @a timeout == 0,
159 * the caller will block until action is possible, else will wait
160 * until the relative time specified in @c *timeout elapses).
162 virtual int notify (ACE_Event_Handler * = 0,
163 ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
164 ACE_Time_Value * timeout = 0);
166 /// Handles pending threads (if any) that are waiting to unblock the
167 /// ACE_Select_Reactor.
168 virtual int dispatch_notifications (int &number_of_active_handles,
169 ACE_Handle_Set &rd_mask);
171 /// Returns the ACE_HANDLE of the notify pipe on which the reactor
172 /// is listening for notifications so that other threads can unblock
173 /// the Select_Reactor
174 virtual ACE_HANDLE notify_handle (void);
176 /// Handle one of the notify call on the @c handle. This could be
177 /// because of a thread trying to unblock the Reactor_Impl
178 virtual int dispatch_notify (ACE_Notification_Buffer &buffer);
180 /// Read one of the notify call on the @a handle into the
181 /// @a buffer. This could be because of a thread trying to unblock
182 /// the Reactor_Impl
183 virtual int read_notify_pipe (ACE_HANDLE handle,
184 ACE_Notification_Buffer &buffer);
186 /// Verify whether the buffer has dispatchable info or not.
187 virtual int is_dispatchable (ACE_Notification_Buffer &buffer);
189 /// Called back by the ACE_Select_Reactor when a thread wants to
190 /// unblock us.
191 virtual int handle_input (ACE_HANDLE handle);
194 * Set the maximum number of times that the
195 * ACE_Select_Reactor_Notify::handle_input() method will iterate and
196 * dispatch the ACE_Event_Handlers that are passed in via the
197 * notify pipe before breaking out of its @c recv loop. By default,
198 * this is set to -1, which means "iterate until the pipe is empty."
199 * Setting this to a value like "1 or 2" will increase "fairness"
200 * (and thus prevent starvation) at the expense of slightly higher
201 * dispatching overhead.
203 virtual void max_notify_iterations (int);
206 * Get the maximum number of times that the
207 * ACE_Select_Reactor_Notify::handle_input() method will iterate and
208 * dispatch the ACE_Event_Handlers that are passed in via the
209 * notify pipe before breaking out of its recv loop.
211 virtual int max_notify_iterations (void);
214 * Purge any notifications pending in this reactor for the specified
215 * ACE_Event_Handler object. If @a eh == 0, all notifications for all
216 * handlers are removed (but not any notifications posted just to wake up
217 * the reactor itself). Returns the number of notifications purged.
218 * Returns -1 on error.
220 virtual int purge_pending_notifications (
221 ACE_Event_Handler *sh,
222 ACE_Reactor_Mask mask = ACE_Event_Handler::ALL_EVENTS_MASK);
224 /// Dump the state of an object.
225 virtual void dump (void) const;
227 /// Declare the dynamic allocation hooks.
228 ACE_ALLOC_HOOK_DECLARE;
230 protected:
232 * Keep a back pointer to the ACE_Select_Reactor. If this value
233 * if NULL then the ACE_Select_Reactor has been initialized with
234 * disable_notify_pipe.
236 ACE_Select_Reactor_Impl *select_reactor_;
239 * Contains the ACE_HANDLE the ACE_Select_Reactor is listening
240 * on, as well as the ACE_HANDLE that threads wanting the
241 * attention of the ACE_Select_Reactor will write to.
243 ACE_Pipe notification_pipe_;
246 * Keeps track of the maximum number of times that the
247 * ACE_Select_Reactor_Notify::handle_input() method will iterate and
248 * dispatch the ACE_Event_Handlers that are passed in via the
249 * notify pipe before breaking out of its recv loop. By default,
250 * this is set to -1, which means "iterate until the pipe is empty."
252 int max_notify_iterations_;
254 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
256 * @brief A user-space queue to store the notifications.
258 * The notification pipe has OS-specific size restrictions. That
259 * is, no more than a certain number of bytes may be stored in the
260 * pipe without blocking. This limit may be too small for certain
261 * applications. In this case, ACE can be configured to store all
262 * the events in user-space. The pipe is still needed to wake up
263 * the reactor thread, but only one event is sent through the pipe
264 * at a time.
266 ACE_Notification_Queue notification_queue_;
267 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
271 * @class ACE_Select_Reactor_Handler_Repository
273 * @brief Used to map ACE_HANDLEs onto the appropriate
274 * ACE_Event_Handler *.
276 * This class is necessary to shield differences between UNIX
277 * and Win32. In UNIX, ACE_HANDLE is an int, whereas in Win32
278 * it's a void *. This class hides all these details from the
279 * bulk of the ACE_Select_Reactor code. All of these methods
280 * are called with the main <Select_Reactor> token lock held.
282 class ACE_Export ACE_Select_Reactor_Handler_Repository
284 public:
285 friend class ACE_Select_Reactor_Handler_Repository_Iterator;
287 typedef ACE_HANDLE key_type;
288 typedef ACE_Event_Handler * value_type;
290 // = The mapping from <HANDLES> to <Event_Handlers>.
291 #ifdef ACE_WIN32
293 * The NT version implements this via a hash map
294 * @c ACE_Event_Handler*. Since NT implements @c ACE_HANDLE
295 * as a void * we can't directly index into this array. Therefore,
296 * we must explicitly map @c ACE_HANDLE to @c ACE_Event_Handler.
298 typedef ACE_Hash_Map_Manager_Ex<key_type,
299 value_type,
300 ACE_Hash<key_type>,
301 std::equal_to<key_type>,
302 ACE_Null_Mutex> map_type;
304 typedef map_type::size_type max_handlep1_type;
305 #else
307 * The UNIX version implements this via a dynamically allocated
308 * array of @c ACE_Event_Handler* that is indexed directly using
309 * the @c ACE_HANDLE value.
311 typedef ACE_Array_Base<value_type> map_type;
312 typedef ACE_HANDLE max_handlep1_type;
313 #endif /* ACE_WIN32 */
315 typedef map_type::size_type size_type;
317 // = Initialization and termination methods.
318 /// Default "do-nothing" constructor.
319 ACE_Select_Reactor_Handler_Repository (ACE_Select_Reactor_Impl &);
321 /// Initialize a repository of the appropriate @a size.
323 * On Unix platforms, the size parameter should be as large as the
324 * maximum number of file descriptors allowed for a given process.
325 * This is necessary since a file descriptor is used to directly
326 * index the array of event handlers maintained by the Reactor's
327 * handler repository. Direct indexing is used for efficiency
328 * reasons.
330 int open (size_type size);
332 /// Close down the repository.
333 int close (void);
335 // = Search structure operations.
338 * Return the @c ACE_Event_Handler* associated with @c ACE_HANDLE.
340 ACE_Event_Handler * find (ACE_HANDLE handle);
342 /// Bind the ACE_Event_Handler * to the ACE_HANDLE with the
343 /// appropriate ACE_Reactor_Mask settings.
344 int bind (ACE_HANDLE,
345 ACE_Event_Handler *,
346 ACE_Reactor_Mask);
348 /// Remove the binding of ACE_HANDLE in accordance with the @a mask.
349 int unbind (ACE_HANDLE,
350 ACE_Reactor_Mask mask);
352 /// Remove all the <ACE_HANDLE, ACE_Event_Handler> tuples.
353 int unbind_all (void);
355 // = Sanity checking.
357 // Check the @a handle to make sure it's a valid @c ACE_HANDLE that
358 // is within the range of legal handles (i.e., >= 0 && < max_size_).
359 bool invalid_handle (ACE_HANDLE handle);
361 // Check the @a handle to make sure it's a valid @c ACE_HANDLE that
362 // within the range of currently registered handles (i.e., >= 0 && <
363 // @c max_handlep1_).
364 bool handle_in_range (ACE_HANDLE handle);
366 // = Accessors.
367 /// Returns the current table size.
368 size_type size (void) const;
370 /// Maximum ACE_HANDLE value, plus 1.
371 max_handlep1_type max_handlep1 (void) const;
373 /// Dump the state of an object.
374 void dump (void) const;
376 /// Declare the dynamic allocation hooks.
377 ACE_ALLOC_HOOK_DECLARE;
379 private:
381 /// Remove the binding of @a handle corresponding to position @a pos
382 /// in accordance with the @a mask.
383 int unbind (ACE_HANDLE handle,
384 map_type::iterator pos,
385 ACE_Reactor_Mask mask);
388 * @return @c iterator corresponding @c ACE_Event_Handler*
389 * associated with @c ACE_HANDLE.
391 map_type::iterator find_eh (ACE_HANDLE handle);
393 private:
394 /// Reference to our @c Select_Reactor.
395 ACE_Select_Reactor_Impl &select_reactor_;
397 #ifndef ACE_WIN32
398 /// The highest currently active handle, plus 1 (ranges between 0 and
399 /// @c max_size_.
400 max_handlep1_type max_handlep1_;
401 #endif /* !ACE_WIN32 */
403 /// Underlying table of event handlers.
404 map_type event_handlers_;
408 * @class ACE_Select_Reactor_Handler_Repository_Iterator
410 * @brief Iterate through the ACE_Select_Reactor_Handler_Repository.
412 class ACE_Export ACE_Select_Reactor_Handler_Repository_Iterator
414 public:
416 typedef
417 ACE_Select_Reactor_Handler_Repository::map_type::const_iterator const_base_iterator;
419 // = Initialization method.
420 explicit ACE_Select_Reactor_Handler_Repository_Iterator (
421 ACE_Select_Reactor_Handler_Repository const * s);
423 // = Iteration methods.
425 /// Pass back the @a next_item that hasn't been seen in the Set.
426 /// Returns @c false when all items have been seen, else @c true.
427 bool next (ACE_Event_Handler* & next_item);
429 /// Returns @c true when all items have been seen, else @c false.
430 bool done (void) const;
432 /// Move forward by one element in the set. Returns @c false when
433 /// all the items in the set have been seen, else @c true.
434 bool advance (void);
436 /// Dump the state of an object.
437 void dump (void) const;
439 /// Declare the dynamic allocation hooks.
440 ACE_ALLOC_HOOK_DECLARE;
442 private:
444 /// Reference to the Handler_Repository we are iterating over.
445 ACE_Select_Reactor_Handler_Repository const * const rep_;
447 /// Pointer to the current iteration level.
448 const_base_iterator current_;
452 * @class ACE_Select_Reactor_Impl
454 * @brief This class simply defines how Select_Reactor's basic interface
455 * functions should look like and provides a common base class for
456 * @c Select_Reactor using various locking mechanism.
458 class ACE_Export ACE_Select_Reactor_Impl : public ACE_Reactor_Impl
460 public:
461 enum
463 /// Default size of the Select_Reactor's handle table.
464 DEFAULT_SIZE = ACE_DEFAULT_SELECT_REACTOR_SIZE
467 /// Constructor.
468 ACE_Select_Reactor_Impl (bool mask_signals = true);
470 friend class ACE_Select_Reactor_Notify;
471 friend class ACE_Select_Reactor_Handler_Repository;
474 * Purge any notifications pending in this reactor for the specified
475 * ACE_Event_Handler object. Returns the number of notifications
476 * purged. Returns -1 on error.
478 virtual int purge_pending_notifications (ACE_Event_Handler * = 0,
479 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
481 /// Does the reactor allow the application to resume the handle on
482 /// its own ie. can it pass on the control of handle resumption to
483 /// the application. The select reactor has no handlers that can be
484 /// resumed by the application. So return 0;
485 virtual int resumable_handler (void);
488 * Hook to add concrete methods required to specialize the
489 * implementation with concrete methods required for the concrete
490 * reactor implementation, for example, select, tp reactors.
492 //@@ REACTOR_SPL_PUBLIC_METHODS_ADD_HOOK
494 protected:
495 /// Allow manipulation of the <wait_set_> mask and <ready_set_> mask.
496 virtual int bit_ops (ACE_HANDLE handle,
497 ACE_Reactor_Mask mask,
498 ACE_Select_Reactor_Handle_Set &handle_set,
499 int ops);
501 /// Enqueue ourselves into the list of waiting threads at the
502 /// appropriate point specified by <requeue_position_>.
503 virtual void renew (void) = 0;
505 /// Check to see if the <Event_Handler> associated with @a handle is
506 /// suspended. Returns 0 if not, 1 if so.
507 virtual int is_suspended_i (ACE_HANDLE handle) = 0;
509 /// When register/unregister occur, then we need to re-eval our
510 /// wait/suspend/dispatch set.
511 virtual void clear_dispatch_mask (ACE_HANDLE handle,
512 ACE_Reactor_Mask mask);
514 /// Table that maps <ACE_HANDLEs> to <ACE_Event_Handler *>'s.
515 ACE_Select_Reactor_Handler_Repository handler_rep_;
517 /// Tracks handles that are ready for dispatch from <select>
518 ACE_Select_Reactor_Handle_Set dispatch_set_;
520 /// Tracks handles that are waited for by <select>.
521 ACE_Select_Reactor_Handle_Set wait_set_;
523 /// Tracks handles that are currently suspended.
524 ACE_Select_Reactor_Handle_Set suspend_set_;
526 /// Track HANDLES we are interested in for various events that must
527 /// be dispatched *without* going through <select>.
528 ACE_Select_Reactor_Handle_Set ready_set_;
530 /// Defined as a pointer to allow overriding by derived classes...
531 ACE_Timer_Queue *timer_queue_;
533 /// Handle signals without requiring global/static variables.
534 ACE_Sig_Handler *signal_handler_;
536 /// Callback object that unblocks the ACE_Select_Reactor if it's
537 /// sleeping.
538 ACE_Reactor_Notify *notify_handler_;
540 /// Keeps track of whether we should delete the timer queue (if we
541 /// didn't create it, then we don't delete it).
542 bool delete_timer_queue_;
544 /// Keeps track of whether we should delete the signal handler (if we
545 /// didn't create it, then we don't delete it).
546 bool delete_signal_handler_;
548 /// Keeps track of whether we need to delete the notify handler (if
549 /// we didn't create it, then we don't delete it).
550 bool delete_notify_handler_;
552 /// True if we've been initialized yet...
553 bool initialized_;
555 /// Restart the <handle_events> event-loop method automatically when
556 /// <select> is interrupted via <EINTR>.
557 int restart_;
560 * Position that the main ACE_Select_Reactor thread is requeued in
561 * the list of waiters during a <notify> callback. If this value ==
562 * -1 we are requeued at the end of the list. Else if it's 0 then
563 * we are requeued at the front of the list. Else if it's > 1 then
564 * that indicates the number of waiters to skip over.
566 int requeue_position_;
568 /// The original thread that created this Select_Reactor.
569 ACE_thread_t owner_;
572 * True if state has changed during dispatching of
573 * <ACE_Event_Handlers>, else false. This is used to determine
574 * whether we need to make another trip through the
575 * <Select_Reactor>'s <wait_for_multiple_events> loop.
577 bool state_changed_;
580 * If false then the Reactor will not mask the signals during the event
581 * dispatching. This is useful for applications that do not
582 * register any signal handlers and want to reduce the overhead
583 * introduce by the kernel level locks required to change the mask.
585 bool mask_signals_;
587 /// Controls/access whether the notify handler should renew the
588 /// Select_Reactor's token or not.
589 int supress_notify_renew (void);
590 void supress_notify_renew (int sr);
592 private:
594 /// Determine whether we should renew Select_Reactor's token after handling
595 /// the notification message.
596 int supress_renew_;
598 /// Deny access since member-wise won't work...
599 ACE_Select_Reactor_Impl (const ACE_Select_Reactor_Impl &);
600 ACE_Select_Reactor_Impl &operator = (const ACE_Select_Reactor_Impl &);
603 ACE_END_VERSIONED_NAMESPACE_DECL
605 #if defined (__ACE_INLINE__)
606 #include "ace/Select_Reactor_Base.inl"
607 #endif /* __ACE_INLINE__ */
609 #include /**/ "ace/post.h"
611 #endif /* ACE_SELECT_REACTOR_BASE_H */