Correct feature names
[ACE_TAO.git] / ACE / ace / WFMO_Reactor.h
blob4d4dccd151fb1b6c5c50656e3a70db876298830d
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file WFMO_Reactor.h
7 * @author Irfan Pyarali <irfan@cs.wustl.edu>
8 * @author Tim Harrison <harrison@cs.wustl.edu>
9 * @author Doug Schmidt <d.schmidt@vanderbilt.edu>
11 //=============================================================================
13 #ifndef ACE_WFMO_REACTOR_H
14 #define ACE_WFMO_REACTOR_H
15 #include /**/ "ace/pre.h"
17 #include /**/ "ace/config-all.h"
19 #if !defined (ACE_LACKS_PRAGMA_ONCE)
20 # pragma once
21 #endif /* ACE_LACKS_PRAGMA_ONCE */
23 #if defined (ACE_WIN32)
25 #include "ace/Signal.h"
26 #include "ace/Timer_Queue.h"
27 #include "ace/Event_Handler.h"
28 #include "ace/Auto_Event.h"
29 #include "ace/Manual_Event.h"
30 #include "ace/Condition_Thread_Mutex.h"
31 #include "ace/Lock_Adapter_T.h"
32 #include "ace/Reactor_Impl.h"
33 #include "ace/Message_Queue.h"
34 #include "ace/Process_Mutex.h"
36 // If we don't have WinSOCK2, we need these defined
37 #if !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0)
39 * WinSock 2 extension -- bit values and indices for FD_XXX network events
41 #define FD_READ_BIT 0
42 #define FD_WRITE_BIT 1
43 #define FD_OOB_BIT 2
44 #define FD_ACCEPT_BIT 3
45 #define FD_CONNECT_BIT 4
46 #define FD_CLOSE_BIT 5
47 #define FD_QOS_BIT 6
48 #define FD_GROUP_QOS_BIT 7
50 #define FD_QOS (1 << FD_QOS_BIT)
51 #define FD_GROUP_QOS (1 << FD_GROUP_QOS_BIT)
53 #define FD_MAX_EVENTS 8
54 #define FD_ALL_EVENTS ((1 << FD_MAX_EVENTS) - 1)
56 #define WSAEVENT HANDLE
58 typedef struct _WSANETWORKEVENTS
60 long lNetworkEvents;
61 int iErrorCode[FD_MAX_EVENTS];
62 } WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;
64 int WSAEventSelect (SOCKET s,
65 WSAEVENT hEventObject,
66 long lNetworkEvents);
68 int WSAEnumNetworkEvents (SOCKET s,
69 WSAEVENT hEventObject,
70 LPWSANETWORKEVENTS lpNetworkEvents);
72 #endif /* !defined ACE_HAS_WINSOCK2 */
74 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
76 // Forward decl.
77 class ACE_WFMO_Reactor_Test;
78 class ACE_WFMO_Reactor;
79 class ACE_Handle_Set;
81 /**
82 * @class ACE_Wakeup_All_Threads_Handler
84 * @brief This is a helper class whose sole purpose is to handle events
85 * on <ACE_WFMO_Reactor->wakeup_all_threads_>
87 class ACE_Export ACE_Wakeup_All_Threads_Handler : public ACE_Event_Handler
89 public:
90 /// Called when the <ACE_WFMO_Reactor->wakeup_all_threads_>
91 virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0);
94 /**
95 * @class ACE_WFMO_Reactor_Handler_Repository
97 * @internal This class is for internal ACE use only.
99 * @brief Used to map ACE_HANDLEs onto the appropriate
100 * ACE_Event_Handler * and other information.
102 class ACE_Export ACE_WFMO_Reactor_Handler_Repository
104 public:
105 friend class ACE_WFMO_Reactor;
106 friend class ACE_WFMO_Reactor_Test;
109 * @class Common_Info
111 * @brief This struct contains the necessary information for every
112 * Event_Handler entry. The reason the event is not in this
113 * structure is because we need to pass an event array into
114 * WaitForMultipleObjects and therefore keeping the events
115 * separate makes sense.
117 class Common_Info
119 public:
120 /// This indicates whether this entry is for I/O or for a regular
121 /// event
122 bool io_entry_;
124 /// The associated Event_Handler
125 ACE_Event_Handler *event_handler_;
127 /// The I/O handle related to the Event_Handler. This entry is
128 /// only valid if the io_entry_ flag is true.
129 ACE_HANDLE io_handle_;
132 * This is the set of events that the Event_Handler is
133 * interested in. This entry is only valid if the io_entry_ flag
134 * is true.
136 long network_events_;
139 * This flag indicates that WFMO_Reactor created the event on
140 * behalf of the user. Therefore we need to clean this up when the
141 * Event_Handler removes itself from WFMO_Reactor. This entry
142 * is only valid if the io_entry_ flag is true.
144 bool delete_event_;
146 /// This is set when the entry needed to be deleted.
147 bool delete_entry_;
150 * These are the masks related to handle_close() for the
151 * Event_Handler. This is only valid when delete_entry_ is
152 * set.
154 ACE_Reactor_Mask close_masks_;
156 /// Constructor used for initializing the structure
157 Common_Info (void);
159 /// Reset the state of the structure
160 void reset (void);
162 /// Set the structure to these new values
163 void set (bool io_entry,
164 ACE_Event_Handler *event_handler,
165 ACE_HANDLE io_handle,
166 long network_events,
167 bool delete_event,
168 bool delete_entry,
169 ACE_Reactor_Mask close_masks);
171 /// Set the structure to these new values
172 void set (Common_Info &common_info);
174 /// Dump the state of an object.
175 void dump (void) const;
179 * @class Current_Info
181 * @brief This structure inherits from the common structure to add
182 * information for current entries.
184 class Current_Info : public Common_Info
186 public:
187 /// This is set when the entry needed to be suspended.
188 bool suspend_entry_;
190 /// Default constructor
191 Current_Info (void);
193 /// Reset the state of the structure
194 void reset (void);
196 /// Set the structure to these new values
197 void set (bool io_entry,
198 ACE_Event_Handler *event_handler,
199 ACE_HANDLE io_handle,
200 long network_events,
201 bool delete_event,
202 bool delete_entry = false,
203 ACE_Reactor_Mask close_masks = ACE_Event_Handler::NULL_MASK,
204 bool suspend_entry = false);
206 /// Set the structure to these new values
207 void set (Common_Info &common_info,
208 bool suspend_entry = false);
210 /// Dump the state of an object.
211 void dump (ACE_HANDLE event_handle) const;
215 * @class To_Be_Added_Info
217 * @brief This structure inherits from the common structure to add
218 * information for <to_be_added> entries.
220 class To_Be_Added_Info : public Common_Info
222 public:
223 /// Handle for the event
224 ACE_HANDLE event_handle_;
226 /// This is set when the entry needed to be suspended.
227 bool suspend_entry_;
229 /// Default constructor
230 To_Be_Added_Info (void);
232 /// Reset the state of the structure
233 void reset (void);
235 /// Set the structure to these new values
236 void set (ACE_HANDLE event_handle,
237 bool io_entry,
238 ACE_Event_Handler *event_handler,
239 ACE_HANDLE io_handle,
240 long network_events,
241 bool delete_event,
242 bool delete_entry = false,
243 ACE_Reactor_Mask close_masks = ACE_Event_Handler::NULL_MASK,
244 bool suspend_entry = false);
246 /// Set the structure to these new values
247 void set (ACE_HANDLE event_handle,
248 Common_Info &common_info,
249 bool suspend_entry = false);
251 /// Dump the state of an object.
252 void dump (void) const;
256 * @class Suspended_Info
258 * @brief This structure inherits from the common structure to add
259 * information for suspended entries.
261 class Suspended_Info : public Common_Info
263 public:
264 /// Handle for the event
265 ACE_HANDLE event_handle_;
267 /// This is set when the entry needed to be resumed.
268 bool resume_entry_;
270 /// Constructor used for initializing the structure
271 Suspended_Info (void);
273 /// Reset the state of the structure
274 void reset (void);
276 /// Set the structure to these new values
277 void set (ACE_HANDLE event_handle,
278 bool io_entry,
279 ACE_Event_Handler *event_handler,
280 ACE_HANDLE io_handle,
281 long network_events,
282 bool delete_event,
283 bool delete_entry = false,
284 ACE_Reactor_Mask close_masks = 0,
285 bool resume_entry = false);
287 /// Set the structure to these new values
288 void set (ACE_HANDLE event_handle,
289 Common_Info &common_info,
290 bool resume_entry = false);
292 /// Dump the state of an object.
293 void dump (void) const;
296 /// Constructor.
297 ACE_WFMO_Reactor_Handler_Repository (ACE_WFMO_Reactor &wfmo_reactor);
299 /// Destructor.
300 virtual ~ACE_WFMO_Reactor_Handler_Repository (void);
302 /// Initialize the repository of the appropriate @a size.
303 int open (size_t size);
305 /// Close down the handler repository.
306 int close (void);
308 // = Search structure operations.
310 /// Insert I/O Event_Handler entry into the system. This method
311 /// assumes that the lock are head *before* this method is invoked.
312 int bind_i (bool io_entry,
313 ACE_Event_Handler *event_handler,
314 long network_events,
315 ACE_HANDLE io_handle,
316 ACE_HANDLE event_handle,
317 bool delete_event);
319 /// Remove the binding of ACE_HANDLE in accordance with the @a mask.
320 int unbind (ACE_HANDLE,
321 ACE_Reactor_Mask mask);
323 /// Non-lock-grabbing version of unbind
324 int unbind_i (ACE_HANDLE,
325 ACE_Reactor_Mask mask,
326 bool &changes_required);
328 /// Remove all bindings of <ACE_HANDLE, ACE_Event_Handler> tuples.
329 void unbind_all (void);
331 // = Sanity checking.
333 // Check the @a handle to make sure it's a valid ACE_HANDLE
334 int invalid_handle (ACE_HANDLE handle) const;
336 // = Accessors.
337 /// Maximum ACE_HANDLE value, plus 1.
338 DWORD max_handlep1 (void) const;
340 /// Pointer to the beginning of the current array of ACE_HANDLE
341 /// *'s.
342 ACE_HANDLE *handles (void) const;
344 /// Pointer to the beginning of the current array of
345 /// ACE_Event_Handler *'s.
346 Current_Info *current_info (void) const;
348 /// Check if changes to the handle set are required.
349 virtual bool changes_required (void);
351 /// Make changes to the handle set
352 virtual int make_changes (void);
354 /// Check to see if @a slot has been scheduled for deletion
355 int scheduled_for_deletion (size_t slot) const;
358 * This method is used to calculate the network mask after a mask_op
359 * request to <WFMO_Reactor>. Note that because the Event_Handler
360 * may already be in the handler repository, we may have to find the
361 * old event and the old network events
363 int modify_network_events_i (ACE_HANDLE io_handle,
364 ACE_Reactor_Mask new_masks,
365 ACE_Reactor_Mask &old_masks,
366 long &new_network_events,
367 ACE_HANDLE &event_handle,
368 bool &delete_event,
369 int operation);
371 /// This method is used to change the network mask left (if any)
372 /// after a remove request to <WFMO_Reactor>
373 ACE_Reactor_Mask bit_ops (long &existing_masks,
374 ACE_Reactor_Mask to_be_removed_masks,
375 int operation);
377 /// Temporarily suspend entry
378 int suspend_handler_i (ACE_HANDLE handle,
379 bool &changes_required);
381 /// Resume suspended entry
382 int resume_handler_i (ACE_HANDLE handle,
383 bool &changes_required);
385 /// Deletions and suspensions in current_info_
386 int make_changes_in_current_infos (void);
388 /// Deletions and resumptions in current_suspended_info_
389 int make_changes_in_suspension_infos (void);
391 /// Deletions in to_be_added_info_, or transfers to current_info_ or
392 /// current_suspended_info_ from to_be_added_info_
393 int make_changes_in_to_be_added_infos (void);
395 /// Removes the ACE_Event_Handler at @a slot from the table.
396 int remove_handler_i (size_t slot,
397 ACE_Reactor_Mask mask);
399 /// Removes the ACE_Event_Handler at @a slot from the table.
400 int remove_suspended_handler_i (size_t slot,
401 ACE_Reactor_Mask mask);
403 /// Removes the ACE_Event_Handler at @a slot from the table.
404 int remove_to_be_added_handler_i (size_t slot,
405 ACE_Reactor_Mask to_be_removed_masks);
408 * Return the Event_Handler associated with @a handle. Return 0 if
409 * @a handle is not registered.
411 ACE_Event_Handler *find_handler (ACE_HANDLE handle);
414 * Check to see if @a handle is associated with a valid Event_Handler
415 * bound to @a mask. Return the @a event_handler associated with this
416 * @a handler if @a event_handler != 0.
418 int handler (ACE_HANDLE handle,
419 ACE_Reactor_Mask mask,
420 ACE_Event_Handler **event_handler = 0);
423 * Check to see if @a handle is associated with a valid
424 * Event_Handler. Return Event_Handler and associated masks.
426 ACE_Event_Handler *handler (ACE_HANDLE handle,
427 long &existing_masks);
429 /// Dump the state of an object.
430 void dump (void) const;
432 protected:
433 /// Reference to our WFMO_Reactor.
434 ACE_WFMO_Reactor &wfmo_reactor_;
436 /// Maximum number of handles.
437 size_t max_size_;
440 * Array of ACE_HANDLEs passed to <WaitForMultipleObjects>. This
441 * is not part of the structure as the handle array needs to be
442 * passed directly to <WaitForMultipleObjects>.
444 ACE_HANDLE *current_handles_;
446 /// Array of current entries in the table
447 Current_Info *current_info_;
449 /// A count of the number of active handles.
450 DWORD max_handlep1_;
452 /// Information for entries to be added
453 To_Be_Added_Info *to_be_added_info_;
455 /// Number of records to be added
456 size_t handles_to_be_added_;
458 /// Currently suspended handles
459 Suspended_Info *current_suspended_info_;
461 /// Number of currently suspended handles
462 size_t suspended_handles_;
464 /// Number of records to be suspended
465 size_t handles_to_be_suspended_;
467 /// Number of records to be resumed
468 size_t handles_to_be_resumed_;
470 /// Number of records to be deleted
471 size_t handles_to_be_deleted_;
476 * @class ACE_WFMO_Reactor_Notify
478 * @brief Unblock the ACE_WFMO_Reactor from its event loop, passing
479 * it an optional ACE_Event_Handler to dispatch.
481 * This implementation is necessary for cases where the
482 * ACE_WFMO_Reactor is run in a multi-threaded program. In
483 * this case, we need to be able to unblock
484 * <WaitForMultipleObjects> when updates occur other than in the
485 * main <ACE_WFMO_Reactor> thread. To do this, we signal an
486 * auto-reset event the <ACE_WFMO_Reactor> is listening on. If
487 * an ACE_Event_Handler and ACE_Reactor_Mask is passed to
488 * <notify>, the appropriate <handle_*> method is dispatched.
490 class ACE_Export ACE_WFMO_Reactor_Notify : public ACE_Reactor_Notify
492 public:
493 /// Constructor
494 ACE_WFMO_Reactor_Notify (size_t max_notifies = 1024);
496 /// Initialization. @a timer_queue is stored to call gettimeofday().
497 virtual int open (ACE_Reactor_Impl *wfmo_reactor,
498 ACE_Timer_Queue *timer_queue,
499 int disable_notify = 0);
501 /// No-op.
502 virtual int close (void);
505 * Special trick to unblock <WaitForMultipleObjects> when updates
506 * occur. All we do is enqueue @a event_handler and @a mask onto the
507 * ACE_Message_Queue and wakeup the <WFMO_Reactor> by signaling
508 * its <ACE_Event> handle. The ACE_Time_Value indicates how long
509 * to blocking trying to notify the <WFMO_Reactor>. If @a timeout ==
510 * 0, the caller will block until action is possible, else will wait
511 * until the relative time specified in @a timeout elapses).
513 virtual int notify (ACE_Event_Handler *event_handler = 0,
514 ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK,
515 ACE_Time_Value *timeout = 0);
517 /// No-op.
518 virtual int dispatch_notifications (int &number_of_active_handles,
519 ACE_Handle_Set &rd_mask);
521 /// Returns a handle to the ACE_Auto_Event.
522 virtual ACE_HANDLE get_handle (void) const;
524 /// Returns the ACE_HANDLE of the notify pipe on which the reactor
525 /// is listening for notifications so that other threads can unblock
526 /// the <Reactor_Impl>
527 virtual ACE_HANDLE notify_handle (void);
529 /// Handle one of the notify call on the <handle>. This could be
530 /// because of a thread trying to unblock the <Reactor_Impl>
531 virtual int dispatch_notify (ACE_Notification_Buffer &buffer);
533 /// Verify whether the buffer has dispatchable info or not.
534 virtual int is_dispatchable (ACE_Notification_Buffer &buffer);
536 /// Read one of the notify call on the @a handle into the
537 /// <buffer>. This could be because of a thread trying to unblock
538 /// the <Reactor_Impl>
539 virtual int read_notify_pipe (ACE_HANDLE handle,
540 ACE_Notification_Buffer &buffer);
543 * Set the maximum number of times that the
544 * ACE_WFMO_Reactor_Notify::handle_input() method will iterate and
545 * dispatch the ACE_Event_Handlers that are passed in via the
546 * notify queue before breaking out of its
547 * ACE_Message_Queue::dequeue() loop. By default, this is set to
548 * -1, which means "iterate until the queue is empty." Setting this
549 * to a value like "1 or 2" will increase "fairness" (and thus
550 * prevent starvation) at the expense of slightly higher dispatching
551 * overhead.
553 void max_notify_iterations (int);
556 * Get the maximum number of times that the
557 * ACE_WFMO_Reactor_Notify::handle_input() method will iterate and
558 * dispatch the ACE_Event_Handlers that are passed in via the
559 * notify queue before breaking out of its
560 * ACE_Message_Queue::dequeue() loop.
562 int max_notify_iterations (void);
565 * Purge any notifications pending in this reactor for the specified
566 * ACE_Event_Handler object. If @a eh == 0, all notifications for all
567 * handlers are removed (but not any notifications posted just to wake up
568 * the reactor itself). Returns the number of notifications purged.
569 * Returns -1 on error.
571 virtual int purge_pending_notifications (ACE_Event_Handler *,
572 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
574 /// Dump the state of an object.
575 virtual void dump (void) const;
577 private:
578 /// Pointer to the wfmo_reactor's timer queue.
579 ACE_Timer_Queue *timer_queue_;
582 * Called when the notification event waited on by
583 * <ACE_WFMO_Reactor> is signaled. This dequeues all pending
584 * ACE_Event_Handlers and dispatches them.
586 virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0);
588 /// An auto event is used so that we can signal() it to wakeup one
589 /// thread up (e.g., when the <notify> method is called).
590 ACE_Auto_Event wakeup_one_thread_;
592 /// Message queue that keeps track of pending ACE_Event_Handlers.
593 /// This queue must be thread-safe because it can be called by
594 /// multiple threads of control.
595 ACE_Message_Queue<ACE_MT_SYNCH> message_queue_;
598 * Keeps track of the maximum number of times that the
599 * <ACE_WFMO_Reactor_Notify::handle_input> method will iterate and
600 * dispatch the ACE_Event_Handlers that are passed in via the
601 * notify queue before breaking out of its
602 * <ACE_Message_Queue::dequeue> loop. By default, this is set to
603 * -1, which means "iterate until the queue is empty."
605 int max_notify_iterations_;
609 * @class ACE_WFMO_Reactor
611 * @brief An object oriented event demultiplexor and event handler.
612 * ACE_WFMO_Reactor is a Windows-only implementation of the ACE_Reactor
613 * interface that uses the WaitForMultipleObjects() event demultiplexer.
615 * Like the other ACE Reactors, ACE_WFMO_Reactor can schedule timers.
616 * It also reacts to signalable handles, such as events (see the documentation
617 * for WaitForMultipleObjects() for a complete list of signalable handle
618 * types). Therefore, I/O handles are not directly usable for registering
619 * for input, output, and exception notification. The exception to this
620 * is ACE_SOCK-based handles, which can be registered for input, output, and
621 * exception notification just as with other platforms. See Chapter 4 in
622 * C++NPv2 for complete details.
624 * Note that changes to the state of ACE_WFMO_Reactor are not
625 * instantaneous. Most changes (registration, removal,
626 * suspension, and resumption of handles, and changes in
627 * ownership) are made when the ACE_WFMO_Reactor reaches a stable
628 * state. Users should be careful, especially when removing
629 * handlers. This is because the ACE_WFMO_Reactor will call
630 * handle_close() on the handler when it is finally removed and
631 * not when remove_handler() is called. If the registered handler's pointer
632 * is not valid when ACE_WFMO_Reactor calls ACE_Event_Handler::handle_close(),
633 * use the DONT_CALL flag with remove_handler(). Preferably, use dynamically
634 * allocated event handlers and call "delete this" inside the handle_close()
635 * hook method.
637 * Note that although multiple threads can concurrently run the
638 * ACE_WFMO_Reactor event loop, the concept of the reactor "owner" is still
639 * important. Only the owner thread can expire timers and wait on the
640 * notifications handle. Thus, be careful to properly set the owner thread
641 * when spawning threads to run the event loop while you are using timers
642 * or notifications.
644 class ACE_Export ACE_WFMO_Reactor : public ACE_Reactor_Impl
646 public:
647 friend class ACE_WFMO_Reactor_Handler_Repository;
648 friend class ACE_WFMO_Reactor_Test;
650 enum
652 /// Default size of the WFMO_Reactor's handle table.
654 * Two slots will be added to the @a size parameter in the
655 * constructor and open methods which will store handles used for
656 * internal management purposes.
658 DEFAULT_SIZE = MAXIMUM_WAIT_OBJECTS - 2
661 /// Initialize ACE_WFMO_Reactor with the default size.
662 ACE_WFMO_Reactor (ACE_Sig_Handler * = 0,
663 ACE_Timer_Queue * = 0,
664 ACE_Reactor_Notify * = 0);
667 * Initialize ACE_WFMO_Reactor with the specified size.
669 * @param size The maximum number of handles the reactor can
670 * register. The value should not exceed
671 * ACE_WFMO_Reactor::DEFAULT_SIZE. Two slots will be
672 * added to the @a size parameter which will store handles
673 * used for internal management purposes.
675 ACE_WFMO_Reactor (size_t size,
676 int unused = 0,
677 ACE_Sig_Handler * = 0,
678 ACE_Timer_Queue * = 0,
679 ACE_Reactor_Notify * = 0);
682 * Initialize ACE_WFMO_Reactor with the specified size.
684 * @param size The maximum number of handles the reactor can
685 * register. The value should not exceed
686 * ACE_WFMO_Reactor::DEFAULT_SIZE. Two slots will be
687 * added to the @a size parameter which will store handles
688 * used for internal management purposes.
690 virtual int open (size_t size = ACE_WFMO_Reactor::DEFAULT_SIZE,
691 bool restart = false,
692 ACE_Sig_Handler * = 0,
693 ACE_Timer_Queue * = 0,
694 int disable_notify_pipe = 0,
695 ACE_Reactor_Notify * = 0);
697 /// Returns -1 (not used in this implementation);
698 virtual int current_info (ACE_HANDLE, size_t & /* size */);
700 /// Use a user specified signal handler instead.
701 virtual int set_sig_handler (ACE_Sig_Handler *signal_handler);
703 /// Set a user-specified timer queue.
704 virtual int timer_queue (ACE_Timer_Queue *tq);
706 /// Return the current ACE_Timer_Queue.
707 virtual ACE_Timer_Queue *timer_queue (void) const;
709 /// Close down the ACE_WFMO_Reactor and release all of its resources.
710 virtual int close (void);
712 /// Close down the ACE_WFMO_Reactor and release all of its resources.
713 virtual ~ACE_WFMO_Reactor (void);
715 // = Event loop drivers.
718 * This method is not currently implemented. We recommend that you
719 * use handle_events (ACE_Time_Value::zero) to get basically the
720 * same effect, i.e., it won't block the caller if there are no events.
722 virtual int work_pending (const ACE_Time_Value &max_wait_time = ACE_Time_Value::zero);
725 * This event loop driver blocks for up to @a max_wait_time before
726 * returning. It will return earlier if timer events, I/O events,
727 * or signal events occur. Note that @a max_wait_time can be 0, in
728 * which case this method blocks indefinitely until events occur.
730 * @a max_wait_time is decremented to reflect how much time this call
731 * took. For instance, if a time value of 3 seconds is passed to
732 * handle_events and an event occurs after 2 seconds,
733 * @a max_wait_time will equal 1 second. This can be used if an
734 * application wishes to handle events for some fixed amount of
735 * time.
737 * <WaitForMultipleObjects> is used as the demultiplexing call
739 * Returns the total number of I/O and timer ACE_Event_Handlers
740 * that were dispatched, 0 if the @a max_wait_time elapsed without
741 * dispatching any handlers, or -1 if an error occurs.
743 * The only difference between <alertable_handle_events> and
744 * <handle_events> is that in the alertable case, TRUE is passed to
745 * <WaitForMultipleObjects> for the <bAlertable> option.
747 virtual int handle_events (ACE_Time_Value *max_wait_time = 0);
748 virtual int alertable_handle_events (ACE_Time_Value *max_wait_time = 0);
751 * This method is just like the one above, except the
752 * @a max_wait_time value is a reference and can therefore never be
753 * NULL.
755 * The only difference between <alertable_handle_events> and
756 * <handle_events> is that in the alertable case, TRUE is passed to
757 * <WaitForMultipleObjects> for the <bAlertable> option.
759 virtual int handle_events (ACE_Time_Value &max_wait_time);
760 virtual int alertable_handle_events (ACE_Time_Value &max_wait_time);
763 // = Event handling control.
766 * Return the status of Reactor. If this function returns 0, the reactor is
767 * actively handling events. If it returns non-zero, <handling_events> and
768 * <handle_alertable_events> return -1 immediately.
770 virtual int deactivated (void);
773 * Control whether the Reactor will handle any more incoming events or not.
774 * If @a do_stop == 1, the Reactor will be disabled. By default, a reactor
775 * is in active state and can be deactivated/reactivated as wish.
777 virtual void deactivate (int do_stop);
779 // = Register and remove Handlers.
782 * Register an ACE_Event_Handler @a event_handler. Since no Event
783 * Mask is passed through this interface, it is assumed that the
784 * @a handle being passed in is an event handle and when the event
785 * becomes signaled, <WFMO_Reactor> will call handle_signal on
786 * @a event_handler. If @a handle == <ACE_INVALID_HANDLE> the
787 * <ACE_WFMO_Reactor> will call the <get_handle> method of
788 * @a event_handler to extract the underlying event handle.
790 virtual int register_handler (ACE_Event_Handler *event_handler,
791 ACE_HANDLE event_handle = ACE_INVALID_HANDLE);
794 * Register an ACE_Event_Handler @a event_handle. @a mask specifies
795 * the network events that the @a event_handler is interested in. If
796 * @a io_handle == ACE_INVALID_HANDLE the ACE_WFMO_Reactor will
797 * call the <get_handle> method of <event_handler> to extract the
798 * underlying I/O handle. If the @a event_handle ==
799 * ACE_INVALID_HANDLE, WFMO_Reactor will create an event for
800 * associating it with the I/O handle. When the @a event_handle is
801 * signalled, the appropriate <handle_*> callback will be invoked on
802 * the Event_Handler
804 virtual int register_handler (ACE_HANDLE event_handle,
805 ACE_HANDLE io_handle,
806 ACE_Event_Handler *event_handler,
807 ACE_Reactor_Mask mask);
810 * This is a simple version of the above <register_handler> method
811 * where the I/O handle is passed in and the event handle will
812 * always be created by <WFMO_Reactor>
814 virtual int register_handler (ACE_HANDLE io_handle,
815 ACE_Event_Handler *event_handler,
816 ACE_Reactor_Mask mask);
819 * This is a simple version of the above <register_handler> method
820 * where the I/O handle will always come from <get_handle> on the
821 * Event_Handler and the event handle will always be created by
822 * <WFMO_Reactor>
824 virtual int register_handler (ACE_Event_Handler *event_handler,
825 ACE_Reactor_Mask mask);
827 /// Register @a event_handler with all the @a handles in the
828 /// <Handle_Set>.
829 virtual int register_handler (const ACE_Handle_Set &handles,
830 ACE_Event_Handler *event_handler,
831 ACE_Reactor_Mask mask);
834 * Register @a new_sh to handle the signal @a signum using the
835 * @a new_disp. Returns the @a old_sh that was previously registered
836 * (if any), along with the @a old_disp of the signal handler.
838 virtual int register_handler (int signum,
839 ACE_Event_Handler *new_sh,
840 ACE_Sig_Action *new_disp = 0,
841 ACE_Event_Handler **old_sh = 0,
842 ACE_Sig_Action *old_disp = 0);
844 /// Registers @a new_sh to handle a set of signals @a sigset using the
845 /// @a new_disp.
846 virtual int register_handler (const ACE_Sig_Set &sigset,
847 ACE_Event_Handler *new_sh,
848 ACE_Sig_Action *new_disp = 0);
851 * Removes @a event_handler from the ACE_WFMO_Reactor. Note that
852 * the ACE_WFMO_Reactor will call the <get_handle> method of
853 * @a event_handler to extract the underlying handle. If @a mask ==
854 * ACE_Event_Handler::DONT_CALL then the <handle_close> method of
855 * the @a event_handler is not invoked. Note that the @a handle can
856 * either be the <event_handle> or the <io_handle>
858 virtual int remove_handler (ACE_Event_Handler *event_handler,
859 ACE_Reactor_Mask mask);
862 * Removes @a handle from the <ACE_WFMO_Reactor>. If @a mask ==
863 * ACE_Event_Handler::DONT_CALL then the <handle_close> method of
864 * the <event_handler> is not invoked. Note that the @a handle can
865 * either be the <event_handle> or the <io_handle>
867 * For the case of I/O entries, this removes the @a mask binding of
868 * Event_Handler whose handle is @a handle from <WFMO_Reactor>. If
869 * there are no more bindings for this <event_handler> then it is
870 * removed from the WFMO_Reactor. For simple event entries, mask is
871 * mostly ignored and the Event_Handler is always removed from
872 * <WFMO_Reactor>
874 virtual int remove_handler (ACE_HANDLE handle,
875 ACE_Reactor_Mask mask);
878 * Removes all the @a mask bindings for handles in the @a handle_set
879 * bind of Event_Handler. If there are no more bindings for any
880 * of these handles then they are removed from WFMO_Reactor.
882 virtual int remove_handler (const ACE_Handle_Set &handle_set,
883 ACE_Reactor_Mask);
886 * Remove the ACE_Event_Handler currently associated with @a signum.
887 * @a sigkey is ignored in this implementation since there is only
888 * one instance of a signal handler. Install the new disposition
889 * (if given) and return the previous disposition (if desired by the
890 * caller). Returns 0 on success and -1 if @a signum is invalid.
892 virtual int remove_handler (int signum,
893 ACE_Sig_Action *new_disp,
894 ACE_Sig_Action *old_disp = 0,
895 int sigkey = -1);
897 /// Calls remove_handler() for every signal in @a sigset.
898 virtual int remove_handler (const ACE_Sig_Set &sigset);
900 // = Suspend and resume Handlers.
902 /// Suspend @a event_handler temporarily. Use
903 /// ACE_Event_Handler::get_handle() to get the handle.
904 virtual int suspend_handler (ACE_Event_Handler *event_handler);
906 /// Suspend @a handle temporarily.
907 virtual int suspend_handler (ACE_HANDLE handle);
909 /// Suspend all @a handles in handle set temporarily.
910 virtual int suspend_handler (const ACE_Handle_Set &handles);
912 /// Suspend all handles temporarily.
913 virtual int suspend_handlers (void);
915 /// Resume @a event_handler. Use <ACE_Event_Handler::get_handle> to
916 /// get the handle.
917 virtual int resume_handler (ACE_Event_Handler *event_handler);
919 /// Resume @a handle.
920 virtual int resume_handler (ACE_HANDLE handle);
922 /// Resume all @a handles in handle set.
923 virtual int resume_handler (const ACE_Handle_Set &handles);
925 /// Resume all <handles>.
926 virtual int resume_handlers (void);
928 /// Does the reactor allow the application to resume the handle on
929 /// its own ie. can it pass on the control of handle resumption to
930 /// the application. A positive value indicates that the handlers
931 /// are application resumable. A value of 0 indicates otherwise.
932 virtual int resumable_handler (void);
935 * Return true if we any event associations were made by the reactor
936 * for the handles that it waits on, false otherwise. Since the
937 * WFMO_Reactor does use event associations, this function always
938 * return true.
940 virtual bool uses_event_associations (void);
942 // Timer management.
945 * Schedule an ACE_Event_Handler that will expire after an amount
946 * of time. The return value of this method, a timer_id value,
947 * uniquely identifies the event_handler in the ACE_Reactor's
948 * internal list of timers.
949 * This timer_id value can be used to cancel the timer
950 * with the cancel_timer() call.
952 * @see cancel_timer()
953 * @see reset_timer_interval()
955 * @param event_handler event handler to schedule on reactor
956 * @param arg argument passed to the handle_timeout() method of event_handler
957 * @param delay time interval after which the timer will expire
958 * @param interval time interval after which the timer will be automatically rescheduled
959 * @return -1 on failure, a timer_id value on success
961 virtual long schedule_timer (ACE_Event_Handler *event_handler,
962 const void *arg,
963 const ACE_Time_Value &delay,
964 const ACE_Time_Value &interval = ACE_Time_Value::zero);
967 * Resets the interval of the timer represented by @a timer_id to
968 * @a interval, which is specified in relative time to the current
969 * gettimeofday(). If @a interval is equal to
970 * ACE_Time_Value::zero, the timer will become a non-rescheduling
971 * timer. Returns 0 if successful, -1 if not.
973 virtual int reset_timer_interval (long timer_id,
974 const ACE_Time_Value &interval);
976 /// Cancel all Event_Handlers that match the address of
977 /// @a event_handler. Returns number of handler's cancelled.
978 virtual int cancel_timer (ACE_Event_Handler *event_handler,
979 int dont_call_handle_close = 1);
982 * Cancel the single Event_Handler that matches the @a timer_id value
983 * (which was returned from the schedule method). If arg is
984 * non-NULL then it will be set to point to the ``magic cookie''
985 * argument passed in when the Event_Handler was registered. This
986 * makes it possible to free up the memory and avoid memory leaks.
987 * Returns 1 if cancellation succeeded and 0 if the @a timer_id
988 * wasn't found.
990 virtual int cancel_timer (long timer_id,
991 const void **arg = 0,
992 int dont_call_handle_close = 1);
994 // = High-level Event_Handler scheduling operations
997 * Add @a masks_to_be_added to the @a event_handler's entry in
998 * WFMO_Reactor. @a event_handler must already have been registered
999 * with WFMO_Reactor.
1001 virtual int schedule_wakeup (ACE_Event_Handler *event_handler,
1002 ACE_Reactor_Mask masks_to_be_added);
1005 * Add @a masks_to_be_added to the @a handle's entry in WFMO_Reactor.
1006 * The Event_Handler associated with @a handle must already have been
1007 * registered with WFMO_Reactor.
1009 virtual int schedule_wakeup (ACE_HANDLE handle,
1010 ACE_Reactor_Mask masks_to_be_added);
1013 * Remove @a masks_to_be_deleted to the <handle>'s entry in
1014 * WFMO_Reactor. The Event_Handler associated with @a event_handler must
1015 * already have been registered with WFMO_Reactor.
1017 virtual int cancel_wakeup (ACE_Event_Handler *event_handler,
1018 ACE_Reactor_Mask masks_to_be_deleted);
1021 * Remove @a masks_to_be_deleted to the @a handle's entry in
1022 * WFMO_Reactor. The Event_Handler associated with @a handle must
1023 * already have been registered with WFMO_Reactor.
1025 virtual int cancel_wakeup (ACE_HANDLE handle,
1026 ACE_Reactor_Mask masks_to_be_deleted);
1028 // = Notification methods.
1031 * Wakeup one <ACE_WFMO_Reactor> thread if it is currently blocked
1032 * in <WaitForMultipleObjects>. The ACE_Time_Value indicates how
1033 * long to blocking trying to notify the <WFMO_Reactor>. If
1034 * @a timeout == 0, the caller will block until action is possible,
1035 * else will wait until the relative time specified in @a timeout
1036 * elapses).
1038 virtual int notify (ACE_Event_Handler * = 0,
1039 ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
1040 ACE_Time_Value * = 0);
1043 * Set the maximum number of times that the
1044 * <ACE_WFMO_Reactor_Notify::handle_input> method will iterate and
1045 * dispatch the ACE_Event_Handlers that are passed in via the
1046 * notify queue before breaking out of its
1047 * <ACE_Message_Queue::dequeue> loop. By default, this is set to
1048 * -1, which means "iterate until the queue is empty." Setting this
1049 * to a value like "1 or 2" will increase "fairness" (and thus
1050 * prevent starvation) at the expense of slightly higher dispatching
1051 * overhead.
1053 virtual void max_notify_iterations (int);
1056 * Get the maximum number of times that the
1057 * <ACE_WFMO_Reactor_Notify::handle_input> method will iterate and
1058 * dispatch the ACE_Event_Handlers that are passed in via the
1059 * notify queue before breaking out of its
1060 * <ACE_Message_Queue::dequeue> loop.
1062 virtual int max_notify_iterations (void);
1065 * Purge any notifications pending in this reactor for the specified
1066 * ACE_Event_Handler object. Returns the number of notifications
1067 * purged. Returns -1 on error.
1069 virtual int purge_pending_notifications (ACE_Event_Handler * = 0,
1070 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
1072 // = Assorted helper methods.
1075 * Return the Event_Handler associated with @a handle. Return 0 if
1076 * @a handle is not registered.
1078 ACE_Event_Handler *find_handler (ACE_HANDLE handle);
1081 * Check to see if @a handle is associated with a valid Event_Handler
1082 * bound to @a mask. Return the @a event_handler associated with this
1083 * @a handler if @a event_handler != 0.
1085 virtual int handler (ACE_HANDLE handle,
1086 ACE_Reactor_Mask mask,
1087 ACE_Event_Handler **event_handler = 0);
1090 * Check to see if @a signum is associated with a valid Event_Handler
1091 * bound to a signal. Return the <event_handler> associated with
1092 * this @a handler if <event_handler> != 0.
1094 virtual int handler (int signum,
1095 ACE_Event_Handler ** = 0);
1097 /// Returns true if WFMO_Reactor has been successfully initialized, else
1098 /// false.
1099 virtual bool initialized (void);
1101 /// Returns the current size of the WFMO_Reactor's internal
1102 /// descriptor table.
1103 virtual size_t size (void) const;
1105 /// Returns a reference to the WFMO_Reactor's internal lock.
1106 virtual ACE_Lock &lock (void);
1108 /// Wake up all threads in WaitForMultipleObjects so that they can
1109 /// reconsult the handle set
1110 virtual void wakeup_all_threads (void);
1113 * Transfers ownership of the WFMO_Reactor to the @a new_owner. The
1114 * transfer will not complete until all threads are ready (just like
1115 * the handle set).
1117 virtual int owner (ACE_thread_t new_owner, ACE_thread_t *old_owner = 0);
1119 /// Return the ID of the "owner" thread.
1120 virtual int owner (ACE_thread_t *owner);
1122 /// Get the existing restart value.
1123 virtual bool restart (void);
1125 /// Set a new value for restart and return the original value.
1126 virtual bool restart (bool r);
1128 /// Not implemented
1129 virtual void requeue_position (int);
1131 /// Not implemented
1132 virtual int requeue_position (void);
1134 // = Low-level wait_set mask manipulation methods.
1137 * Modify @a masks of the @a event_handler's entry in WFMO_Reactor
1138 * depending upon <operation>. @a event_handler must already have
1139 * been registered with WFMO_Reactor.
1141 virtual int mask_ops (ACE_Event_Handler *event_handler,
1142 ACE_Reactor_Mask masks,
1143 int operation);
1146 * Modify @a masks of the <handle>'s entry in WFMO_Reactor depending
1147 * upon <operation>. <handle> must already have been registered
1148 * with WFMO_Reactor.
1150 virtual int mask_ops (ACE_HANDLE handle,
1151 ACE_Reactor_Mask masks,
1152 int ops);
1154 // = Low-level ready_set mask manipulation methods.
1156 /// Not implemented
1157 virtual int ready_ops (ACE_Event_Handler *event_handler,
1158 ACE_Reactor_Mask mask,
1159 int ops);
1161 /// Not implemented
1162 virtual int ready_ops (ACE_HANDLE handle,
1163 ACE_Reactor_Mask,
1164 int ops);
1166 /// Declare the dynamic allocation hooks.
1167 ACE_ALLOC_HOOK_DECLARE;
1169 /// Dump the state of an object.
1170 virtual void dump (void) const;
1172 protected:
1173 /// Registration workhorse
1174 virtual int register_handler_i (ACE_HANDLE event_handle,
1175 ACE_HANDLE io_handle,
1176 ACE_Event_Handler *event_handler,
1177 ACE_Reactor_Mask mask);
1179 /// Event handling workhorse
1180 virtual int event_handling (ACE_Time_Value *max_wait_time = 0,
1181 int alertable = 0);
1183 /// Bit masking workhorse
1184 virtual int mask_ops_i (ACE_HANDLE io_handle,
1185 ACE_Reactor_Mask masks,
1186 int operation);
1188 /// Return the ID of the "owner" thread. Does not do any locking.
1189 virtual ACE_thread_t owner_i (void);
1191 /// Wait up to @a max_wait_time until it's ok to enter
1192 /// WaitForMultipleObjects. Returns 1 (and holding lock_) if ok to wait;
1193 /// -1 (and not holding lock_) if not.
1194 virtual int ok_to_wait (ACE_Time_Value *max_wait_time,
1195 int alertable);
1197 /// Wait for timer and I/O events to occur.
1198 virtual DWORD wait_for_multiple_events (int timeout,
1199 int alertable);
1201 /// Check for activity on remaining handles.
1202 virtual DWORD poll_remaining_handles (DWORD slot);
1204 /// Expire timers. Only the owner thread does useful stuff in this
1205 /// function.
1206 virtual int expire_timers (void);
1208 /// Dispatches the timers and I/O handlers.
1209 virtual int dispatch (DWORD wait_status);
1211 /// Protect against structured exceptions caused by user code when
1212 /// dispatching handles
1213 virtual int safe_dispatch (DWORD wait_status);
1216 * Dispatches any active handles from handles_[@a slot] to
1217 * handles_[active_handles_] using <WaitForMultipleObjects> to poll
1218 * through our handle set looking for active handles.
1220 virtual int dispatch_handles (DWORD slot);
1222 /// Dispatches a single handler. Returns 0 on success, -1 if the
1223 /// handler was removed.
1224 virtual int dispatch_handler (DWORD slot,
1225 DWORD max_handlep1);
1227 /// Dispatches a single handler. Returns 0 on success, -1 if the
1228 /// handler was removed.
1229 virtual int simple_dispatch_handler (DWORD slot,
1230 ACE_HANDLE event_handle);
1232 /// Dispatches a single handler. Returns 0 on success, -1 if the
1233 /// handler was removed.
1234 virtual int complex_dispatch_handler (DWORD slot,
1235 ACE_HANDLE event_handle);
1237 /// Dispatches window messages. Noop for WFMO_Reactor.
1238 virtual int dispatch_window_messages (void);
1240 virtual ACE_Reactor_Mask upcall (ACE_Event_Handler *event_handler,
1241 ACE_HANDLE io_handle,
1242 WSANETWORKEVENTS &events);
1244 /// Used to caluculate the next timeout
1245 virtual int calculate_timeout (ACE_Time_Value *time);
1247 /// Update the state of the handler repository
1248 virtual int update_state (void);
1250 /// Check to see if we have a new owner
1251 virtual int new_owner (void);
1253 /// Set owner to new owner
1254 virtual int change_owner (void);
1256 /// Handle signals without requiring global/static variables.
1257 ACE_Sig_Handler *signal_handler_;
1259 /// Keeps track of whether we should delete the signal handler (if we
1260 /// didn't create it, then we don't delete it).
1261 bool delete_signal_handler_;
1263 /// Defined as a pointer to allow overriding by derived classes...
1264 ACE_Timer_Queue *timer_queue_;
1266 /// Keeps track of whether we should delete the timer queue (if we
1267 /// didn't create it, then we don't delete it).
1268 bool delete_timer_queue_;
1270 /// Keeps track of whether we should delete the handler repository
1271 bool delete_handler_rep_;
1273 /// Used when <notify> is called.
1274 ACE_Reactor_Notify *notify_handler_;
1276 /// Keeps track of whether we should delete the notify handler.
1277 bool delete_notify_handler_;
1280 * Synchronization for the ACE_WFMO_Reactor.
1282 * A Process Mutex is used here because of two reasons:
1283 * (a) The implementation of ACE_Thread_Mutex uses CriticalSections
1284 * CriticalSections are not waitable using ::WaitForMultipleObjects
1285 * (b) This is really not a process mutex because it is not
1286 * named. No other process can use this mutex.
1288 ACE_Process_Mutex lock_;
1290 /// Adapter used to return internal lock to outside world.
1291 ACE_Lock_Adapter<ACE_Process_Mutex> lock_adapter_;
1293 /// Table that maps <ACE_HANDLEs> to <ACE_Event_Handler *>'s.
1294 ACE_WFMO_Reactor_Handler_Repository handler_rep_;
1296 /// A manual event used to block threads from proceeding into
1297 /// WaitForMultipleObjects
1298 ACE_Manual_Event ok_to_wait_;
1301 * A manual event is used so that we can wake everyone up (e.g.,
1302 * when ACE_Event_Handlers are bounded and unbound from the
1303 * handler repository).
1305 ACE_Manual_Event wakeup_all_threads_;
1307 /// Used when <wakeup_all_threads_> is signaled
1308 ACE_Wakeup_All_Threads_Handler wakeup_all_threads_handler_;
1310 /// The changing thread waits on this event, till all threads are not
1311 /// active anymore
1312 ACE_Auto_Event waiting_to_change_state_;
1314 /// Count of currently active threads
1315 size_t active_threads_;
1318 * The thread which is "owner" of the WFMO_Reactor. The owner
1319 * concept is used because we don't want multiple threads to try to
1320 * expire timers. Therefore the "owner" thread is the only one
1321 * allowed to expire timers. Also, the owner thread is the only
1322 * thread which waits on the notify handle. Note that the ownership
1323 * can be transferred.
1325 ACE_thread_t owner_;
1327 /// The owner to be of the WFMO_Reactor
1328 ACE_thread_t new_owner_;
1330 /// This is the thread which is responsible for the changing the
1331 /// state of the <WFMO_Reactor> handle set
1332 ACE_thread_t change_state_thread_;
1334 /// This is an array of ACE_HANDLEs which keep track of the <lock_>
1335 /// and <ok_to_wait_> handles
1336 ACE_HANDLE atomic_wait_array_ [2];
1338 /// This flag is used to keep track of whether we are already closed.
1339 bool open_for_business_;
1341 /// This flag is used to keep track of whether we are actively handling
1342 /// events or not.
1343 sig_atomic_t deactivated_;
1345 private:
1346 /// Deny access since member-wise won't work...
1347 ACE_WFMO_Reactor (const ACE_WFMO_Reactor &);
1348 ACE_WFMO_Reactor &operator = (const ACE_WFMO_Reactor &);
1351 ACE_END_VERSIONED_NAMESPACE_DECL
1353 #if defined (__ACE_INLINE__)
1354 #include "ace/WFMO_Reactor.inl"
1355 #endif /* __ACE_INLINE__ */
1357 #endif /* ACE_WIN32 */
1358 #include /**/ "ace/post.h"
1359 #endif /* ACE_WFMO_REACTOR_H */