Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / WFMO_Reactor.h
blob05ebf813b9fa51ffae6cb8bd5d1a10460c496fce
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 ();
159 /// Reset the state of the structure
160 void reset ();
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 () 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 ();
193 /// Reset the state of the structure
194 void reset ();
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 ();
232 /// Reset the state of the structure
233 void reset ();
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 () 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 ();
273 /// Reset the state of the structure
274 void reset ();
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 () const;
296 /// Constructor.
297 ACE_WFMO_Reactor_Handler_Repository (ACE_WFMO_Reactor &wfmo_reactor);
299 /// Destructor.
300 virtual ~ACE_WFMO_Reactor_Handler_Repository ();
302 /// Initialize the repository of the appropriate @a size.
303 int open (size_t size);
305 /// Close down the handler repository.
306 int close ();
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 ();
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 () const;
340 /// Pointer to the beginning of the current array of ACE_HANDLE
341 /// *'s.
342 ACE_HANDLE *handles () const;
344 /// Pointer to the beginning of the current array of
345 /// ACE_Event_Handler *'s.
346 Current_Info *current_info () const;
348 /// Check if changes to the handle set are required.
349 virtual bool changes_required ();
351 /// Make changes to the handle set
352 virtual int make_changes ();
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 ();
388 /// Deletions and resumptions in current_suspended_info_
389 int make_changes_in_suspension_infos ();
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 ();
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 () 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_;
475 * @class ACE_WFMO_Reactor_Notify
477 * @brief Unblock the ACE_WFMO_Reactor from its event loop, passing
478 * it an optional ACE_Event_Handler to dispatch.
480 * This implementation is necessary for cases where the
481 * ACE_WFMO_Reactor is run in a multi-threaded program. In
482 * this case, we need to be able to unblock
483 * <WaitForMultipleObjects> when updates occur other than in the
484 * main <ACE_WFMO_Reactor> thread. To do this, we signal an
485 * auto-reset event the <ACE_WFMO_Reactor> is listening on. If
486 * an ACE_Event_Handler and ACE_Reactor_Mask is passed to
487 * <notify>, the appropriate <handle_*> method is dispatched.
489 class ACE_Export ACE_WFMO_Reactor_Notify : public ACE_Reactor_Notify
491 public:
492 /// Constructor
493 ACE_WFMO_Reactor_Notify (size_t max_notifies = 1024);
495 /// Initialization. @a timer_queue is stored to call gettimeofday().
496 virtual int open (ACE_Reactor_Impl *wfmo_reactor,
497 ACE_Timer_Queue *timer_queue,
498 int disable_notify = 0);
500 /// No-op.
501 virtual int close ();
504 * Special trick to unblock <WaitForMultipleObjects> when updates
505 * occur. All we do is enqueue @a event_handler and @a mask onto the
506 * ACE_Message_Queue and wakeup the <WFMO_Reactor> by signaling
507 * its <ACE_Event> handle. The ACE_Time_Value indicates how long
508 * to blocking trying to notify the <WFMO_Reactor>. If @a timeout ==
509 * 0, the caller will block until action is possible, else will wait
510 * until the relative time specified in @a timeout elapses).
512 virtual int notify (ACE_Event_Handler *event_handler = 0,
513 ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK,
514 ACE_Time_Value *timeout = 0);
516 /// No-op.
517 virtual int dispatch_notifications (int &number_of_active_handles,
518 ACE_Handle_Set &rd_mask);
520 /// Returns a handle to the ACE_Auto_Event.
521 virtual ACE_HANDLE get_handle () const;
523 /// Returns the ACE_HANDLE of the notify pipe on which the reactor
524 /// is listening for notifications so that other threads can unblock
525 /// the <Reactor_Impl>
526 virtual ACE_HANDLE notify_handle ();
528 /// Handle one of the notify call on the <handle>. This could be
529 /// because of a thread trying to unblock the <Reactor_Impl>
530 virtual int dispatch_notify (ACE_Notification_Buffer &buffer);
532 /// Verify whether the buffer has dispatchable info or not.
533 virtual int is_dispatchable (ACE_Notification_Buffer &buffer);
535 /// Read one of the notify call on the @a handle into the
536 /// <buffer>. This could be because of a thread trying to unblock
537 /// the <Reactor_Impl>
538 virtual int read_notify_pipe (ACE_HANDLE handle,
539 ACE_Notification_Buffer &buffer);
542 * Set the maximum number of times that the
543 * ACE_WFMO_Reactor_Notify::handle_input() method will iterate and
544 * dispatch the ACE_Event_Handlers that are passed in via the
545 * notify queue before breaking out of its
546 * ACE_Message_Queue::dequeue() loop. By default, this is set to
547 * -1, which means "iterate until the queue is empty." Setting this
548 * to a value like "1 or 2" will increase "fairness" (and thus
549 * prevent starvation) at the expense of slightly higher dispatching
550 * overhead.
552 void max_notify_iterations (int);
555 * Get the maximum number of times that the
556 * ACE_WFMO_Reactor_Notify::handle_input() method will iterate and
557 * dispatch the ACE_Event_Handlers that are passed in via the
558 * notify queue before breaking out of its
559 * ACE_Message_Queue::dequeue() loop.
561 int max_notify_iterations ();
564 * Purge any notifications pending in this reactor for the specified
565 * ACE_Event_Handler object. If @a eh == 0, all notifications for all
566 * handlers are removed (but not any notifications posted just to wake up
567 * the reactor itself). Returns the number of notifications purged.
568 * Returns -1 on error.
570 virtual int purge_pending_notifications (ACE_Event_Handler *,
571 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
573 /// Dump the state of an object.
574 virtual void dump () const;
576 private:
577 /// Pointer to the wfmo_reactor's timer queue.
578 ACE_Timer_Queue *timer_queue_;
581 * Called when the notification event waited on by
582 * <ACE_WFMO_Reactor> is signaled. This dequeues all pending
583 * ACE_Event_Handlers and dispatches them.
585 virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0);
587 /// An auto event is used so that we can signal() it to wakeup one
588 /// thread up (e.g., when the <notify> method is called).
589 ACE_Auto_Event wakeup_one_thread_;
591 /// Message queue that keeps track of pending ACE_Event_Handlers.
592 /// This queue must be thread-safe because it can be called by
593 /// multiple threads of control.
594 ACE_Message_Queue<ACE_MT_SYNCH> message_queue_;
597 * Keeps track of the maximum number of times that the
598 * <ACE_WFMO_Reactor_Notify::handle_input> method will iterate and
599 * dispatch the ACE_Event_Handlers that are passed in via the
600 * notify queue before breaking out of its
601 * <ACE_Message_Queue::dequeue> loop. By default, this is set to
602 * -1, which means "iterate until the queue is empty."
604 int max_notify_iterations_;
608 * @class ACE_WFMO_Reactor
610 * @brief An object oriented event demultiplexor and event handler.
611 * ACE_WFMO_Reactor is a Windows-only implementation of the ACE_Reactor
612 * interface that uses the WaitForMultipleObjects() event demultiplexer.
614 * Like the other ACE Reactors, ACE_WFMO_Reactor can schedule timers.
615 * It also reacts to signalable handles, such as events (see the documentation
616 * for WaitForMultipleObjects() for a complete list of signalable handle
617 * types). Therefore, I/O handles are not directly usable for registering
618 * for input, output, and exception notification. The exception to this
619 * is ACE_SOCK-based handles, which can be registered for input, output, and
620 * exception notification just as with other platforms. See Chapter 4 in
621 * C++NPv2 for complete details.
623 * Note that changes to the state of ACE_WFMO_Reactor are not
624 * instantaneous. Most changes (registration, removal,
625 * suspension, and resumption of handles, and changes in
626 * ownership) are made when the ACE_WFMO_Reactor reaches a stable
627 * state. Users should be careful, especially when removing
628 * handlers. This is because the ACE_WFMO_Reactor will call
629 * handle_close() on the handler when it is finally removed and
630 * not when remove_handler() is called. If the registered handler's pointer
631 * is not valid when ACE_WFMO_Reactor calls ACE_Event_Handler::handle_close(),
632 * use the DONT_CALL flag with remove_handler(). Preferably, use dynamically
633 * allocated event handlers and call "delete this" inside the handle_close()
634 * hook method.
636 * Note that although multiple threads can concurrently run the
637 * ACE_WFMO_Reactor event loop, the concept of the reactor "owner" is still
638 * important. Only the owner thread can expire timers and wait on the
639 * notifications handle. Thus, be careful to properly set the owner thread
640 * when spawning threads to run the event loop while you are using timers
641 * or notifications.
643 class ACE_Export ACE_WFMO_Reactor : public ACE_Reactor_Impl
645 public:
646 friend class ACE_WFMO_Reactor_Handler_Repository;
647 friend class ACE_WFMO_Reactor_Test;
649 enum
651 /// Default size of the WFMO_Reactor's handle table.
653 * Two slots will be added to the @a size parameter in the
654 * constructor and open methods which will store handles used for
655 * internal management purposes.
657 DEFAULT_SIZE = MAXIMUM_WAIT_OBJECTS - 2
660 /// Initialize ACE_WFMO_Reactor with the default size.
661 ACE_WFMO_Reactor (ACE_Sig_Handler * = 0,
662 ACE_Timer_Queue * = 0,
663 ACE_Reactor_Notify * = 0);
666 * Initialize ACE_WFMO_Reactor with the specified size.
668 * @param size The maximum number of handles the reactor can
669 * register. The value should not exceed
670 * ACE_WFMO_Reactor::DEFAULT_SIZE. Two slots will be
671 * added to the @a size parameter which will store handles
672 * used for internal management purposes.
674 ACE_WFMO_Reactor (size_t size,
675 int unused = 0,
676 ACE_Sig_Handler * = 0,
677 ACE_Timer_Queue * = 0,
678 ACE_Reactor_Notify * = 0);
681 * Initialize ACE_WFMO_Reactor with the specified size.
683 * @param size The maximum number of handles the reactor can
684 * register. The value should not exceed
685 * ACE_WFMO_Reactor::DEFAULT_SIZE. Two slots will be
686 * added to the @a size parameter which will store handles
687 * used for internal management purposes.
689 virtual int open (size_t size = ACE_WFMO_Reactor::DEFAULT_SIZE,
690 bool restart = false,
691 ACE_Sig_Handler * = 0,
692 ACE_Timer_Queue * = 0,
693 int disable_notify_pipe = 0,
694 ACE_Reactor_Notify * = 0);
696 /// Returns -1 (not used in this implementation);
697 virtual int current_info (ACE_HANDLE, size_t & /* size */);
699 /// Use a user specified signal handler instead.
700 virtual int set_sig_handler (ACE_Sig_Handler *signal_handler);
702 /// Set a user-specified timer queue.
703 virtual int timer_queue (ACE_Timer_Queue *tq);
705 /// Return the current ACE_Timer_Queue.
706 virtual ACE_Timer_Queue *timer_queue () const;
708 /// Close down the ACE_WFMO_Reactor and release all of its resources.
709 virtual int close ();
711 /// Close down the ACE_WFMO_Reactor and release all of its resources.
712 virtual ~ACE_WFMO_Reactor ();
714 // = Event loop drivers.
717 * This method is not currently implemented. We recommend that you
718 * use handle_events (ACE_Time_Value::zero) to get basically the
719 * same effect, i.e., it won't block the caller if there are no events.
721 virtual int work_pending (const ACE_Time_Value &max_wait_time = ACE_Time_Value::zero);
724 * This event loop driver blocks for up to @a max_wait_time before
725 * returning. It will return earlier if timer events, I/O events,
726 * or signal events occur. Note that @a max_wait_time can be 0, in
727 * which case this method blocks indefinitely until events occur.
729 * @a max_wait_time is decremented to reflect how much time this call
730 * took. For instance, if a time value of 3 seconds is passed to
731 * handle_events and an event occurs after 2 seconds,
732 * @a max_wait_time will equal 1 second. This can be used if an
733 * application wishes to handle events for some fixed amount of
734 * time.
736 * <WaitForMultipleObjects> is used as the demultiplexing call
738 * Returns the total number of I/O and timer ACE_Event_Handlers
739 * that were dispatched, 0 if the @a max_wait_time elapsed without
740 * dispatching any handlers, or -1 if an error occurs.
742 * The only difference between <alertable_handle_events> and
743 * <handle_events> is that in the alertable case, TRUE is passed to
744 * <WaitForMultipleObjects> for the <bAlertable> option.
746 virtual int handle_events (ACE_Time_Value *max_wait_time = 0);
747 virtual int alertable_handle_events (ACE_Time_Value *max_wait_time = 0);
750 * This method is just like the one above, except the
751 * @a max_wait_time value is a reference and can therefore never be
752 * NULL.
754 * The only difference between <alertable_handle_events> and
755 * <handle_events> is that in the alertable case, TRUE is passed to
756 * <WaitForMultipleObjects> for the <bAlertable> option.
758 virtual int handle_events (ACE_Time_Value &max_wait_time);
759 virtual int alertable_handle_events (ACE_Time_Value &max_wait_time);
762 // = Event handling control.
765 * Return the status of Reactor. If this function returns 0, the reactor is
766 * actively handling events. If it returns non-zero, <handling_events> and
767 * <handle_alertable_events> return -1 immediately.
769 virtual int deactivated ();
772 * Control whether the Reactor will handle any more incoming events or not.
773 * If @a do_stop == 1, the Reactor will be disabled. By default, a reactor
774 * is in active state and can be deactivated/reactivated as wish.
776 virtual void deactivate (int do_stop);
778 // = Register and remove Handlers.
781 * Register an ACE_Event_Handler @a event_handler. Since no Event
782 * Mask is passed through this interface, it is assumed that the
783 * @a handle being passed in is an event handle and when the event
784 * becomes signaled, <WFMO_Reactor> will call handle_signal on
785 * @a event_handler. If @a handle == <ACE_INVALID_HANDLE> the
786 * <ACE_WFMO_Reactor> will call the <get_handle> method of
787 * @a event_handler to extract the underlying event handle.
789 virtual int register_handler (ACE_Event_Handler *event_handler,
790 ACE_HANDLE event_handle = ACE_INVALID_HANDLE);
793 * Register an ACE_Event_Handler @a event_handle. @a mask specifies
794 * the network events that the @a event_handler is interested in. If
795 * @a io_handle == ACE_INVALID_HANDLE the ACE_WFMO_Reactor will
796 * call the <get_handle> method of <event_handler> to extract the
797 * underlying I/O handle. If the @a event_handle ==
798 * ACE_INVALID_HANDLE, WFMO_Reactor will create an event for
799 * associating it with the I/O handle. When the @a event_handle is
800 * signalled, the appropriate <handle_*> callback will be invoked on
801 * the Event_Handler
803 virtual int register_handler (ACE_HANDLE event_handle,
804 ACE_HANDLE io_handle,
805 ACE_Event_Handler *event_handler,
806 ACE_Reactor_Mask mask);
809 * This is a simple version of the above <register_handler> method
810 * where the I/O handle is passed in and the event handle will
811 * always be created by <WFMO_Reactor>
813 virtual int register_handler (ACE_HANDLE io_handle,
814 ACE_Event_Handler *event_handler,
815 ACE_Reactor_Mask mask);
818 * This is a simple version of the above <register_handler> method
819 * where the I/O handle will always come from <get_handle> on the
820 * Event_Handler and the event handle will always be created by
821 * <WFMO_Reactor>
823 virtual int register_handler (ACE_Event_Handler *event_handler,
824 ACE_Reactor_Mask mask);
826 /// Register @a event_handler with all the @a handles in the
827 /// <Handle_Set>.
828 virtual int register_handler (const ACE_Handle_Set &handles,
829 ACE_Event_Handler *event_handler,
830 ACE_Reactor_Mask mask);
833 * Register @a new_sh to handle the signal @a signum using the
834 * @a new_disp. Returns the @a old_sh that was previously registered
835 * (if any), along with the @a old_disp of the signal handler.
837 virtual int register_handler (int signum,
838 ACE_Event_Handler *new_sh,
839 ACE_Sig_Action *new_disp = 0,
840 ACE_Event_Handler **old_sh = 0,
841 ACE_Sig_Action *old_disp = 0);
843 /// Registers @a new_sh to handle a set of signals @a sigset using the
844 /// @a new_disp.
845 virtual int register_handler (const ACE_Sig_Set &sigset,
846 ACE_Event_Handler *new_sh,
847 ACE_Sig_Action *new_disp = 0);
850 * Removes @a event_handler from the ACE_WFMO_Reactor. Note that
851 * the ACE_WFMO_Reactor will call the <get_handle> method of
852 * @a event_handler to extract the underlying handle. If @a mask ==
853 * ACE_Event_Handler::DONT_CALL then the <handle_close> method of
854 * the @a event_handler is not invoked. Note that the @a handle can
855 * either be the <event_handle> or the <io_handle>
857 virtual int remove_handler (ACE_Event_Handler *event_handler,
858 ACE_Reactor_Mask mask);
861 * Removes @a handle from the <ACE_WFMO_Reactor>. If @a mask ==
862 * ACE_Event_Handler::DONT_CALL then the <handle_close> method of
863 * the <event_handler> is not invoked. Note that the @a handle can
864 * either be the <event_handle> or the <io_handle>
866 * For the case of I/O entries, this removes the @a mask binding of
867 * Event_Handler whose handle is @a handle from <WFMO_Reactor>. If
868 * there are no more bindings for this <event_handler> then it is
869 * removed from the WFMO_Reactor. For simple event entries, mask is
870 * mostly ignored and the Event_Handler is always removed from
871 * <WFMO_Reactor>
873 virtual int remove_handler (ACE_HANDLE handle,
874 ACE_Reactor_Mask mask);
877 * Removes all the @a mask bindings for handles in the @a handle_set
878 * bind of Event_Handler. If there are no more bindings for any
879 * of these handles then they are removed from WFMO_Reactor.
881 virtual int remove_handler (const ACE_Handle_Set &handle_set,
882 ACE_Reactor_Mask);
885 * Remove the ACE_Event_Handler currently associated with @a signum.
886 * @a sigkey is ignored in this implementation since there is only
887 * one instance of a signal handler. Install the new disposition
888 * (if given) and return the previous disposition (if desired by the
889 * caller). Returns 0 on success and -1 if @a signum is invalid.
891 virtual int remove_handler (int signum,
892 ACE_Sig_Action *new_disp,
893 ACE_Sig_Action *old_disp = 0,
894 int sigkey = -1);
896 /// Calls remove_handler() for every signal in @a sigset.
897 virtual int remove_handler (const ACE_Sig_Set &sigset);
899 // = Suspend and resume Handlers.
901 /// Suspend @a event_handler temporarily. Use
902 /// ACE_Event_Handler::get_handle() to get the handle.
903 virtual int suspend_handler (ACE_Event_Handler *event_handler);
905 /// Suspend @a handle temporarily.
906 virtual int suspend_handler (ACE_HANDLE handle);
908 /// Suspend all @a handles in handle set temporarily.
909 virtual int suspend_handler (const ACE_Handle_Set &handles);
911 /// Suspend all handles temporarily.
912 virtual int suspend_handlers ();
914 /// Resume @a event_handler. Use <ACE_Event_Handler::get_handle> to
915 /// get the handle.
916 virtual int resume_handler (ACE_Event_Handler *event_handler);
918 /// Resume @a handle.
919 virtual int resume_handler (ACE_HANDLE handle);
921 /// Resume all @a handles in handle set.
922 virtual int resume_handler (const ACE_Handle_Set &handles);
924 /// Resume all <handles>.
925 virtual int resume_handlers ();
927 /// Does the reactor allow the application to resume the handle on
928 /// its own ie. can it pass on the control of handle resumption to
929 /// the application. A positive value indicates that the handlers
930 /// are application resumable. A value of 0 indicates otherwise.
931 virtual int resumable_handler ();
934 * Return true if we any event associations were made by the reactor
935 * for the handles that it waits on, false otherwise. Since the
936 * WFMO_Reactor does use event associations, this function always
937 * return true.
939 virtual bool uses_event_associations ();
941 // Timer management.
944 * Schedule an ACE_Event_Handler that will expire after an amount
945 * of time. The return value of this method, a timer_id value,
946 * uniquely identifies the event_handler in the ACE_Reactor's
947 * internal list of timers.
948 * This timer_id value can be used to cancel the timer
949 * with the cancel_timer() call.
951 * @see cancel_timer()
952 * @see reset_timer_interval()
954 * @param event_handler event handler to schedule on reactor
955 * @param arg argument passed to the handle_timeout() method of event_handler
956 * @param delay time interval after which the timer will expire
957 * @param interval time interval after which the timer will be automatically rescheduled
958 * @return -1 on failure, a timer_id value on success
960 virtual long schedule_timer (ACE_Event_Handler *event_handler,
961 const void *arg,
962 const ACE_Time_Value &delay,
963 const ACE_Time_Value &interval = ACE_Time_Value::zero);
966 * Resets the interval of the timer represented by @a timer_id to
967 * @a interval, which is specified in relative time to the current
968 * gettimeofday(). If @a interval is equal to
969 * ACE_Time_Value::zero, the timer will become a non-rescheduling
970 * timer. Returns 0 if successful, -1 if not.
972 virtual int reset_timer_interval (long timer_id,
973 const ACE_Time_Value &interval);
975 /// Cancel all Event_Handlers that match the address of
976 /// @a event_handler. Returns number of handler's cancelled.
977 virtual int cancel_timer (ACE_Event_Handler *event_handler,
978 int dont_call_handle_close = 1);
981 * Cancel the single Event_Handler that matches the @a timer_id value
982 * (which was returned from the schedule method). If arg is
983 * non-NULL then it will be set to point to the ``magic cookie''
984 * argument passed in when the Event_Handler was registered. This
985 * makes it possible to free up the memory and avoid memory leaks.
986 * Returns 1 if cancellation succeeded and 0 if the @a timer_id
987 * wasn't found.
989 virtual int cancel_timer (long timer_id,
990 const void **arg = 0,
991 int dont_call_handle_close = 1);
993 // = High-level Event_Handler scheduling operations
996 * Add @a masks_to_be_added to the @a event_handler's entry in
997 * WFMO_Reactor. @a event_handler must already have been registered
998 * with WFMO_Reactor.
1000 virtual int schedule_wakeup (ACE_Event_Handler *event_handler,
1001 ACE_Reactor_Mask masks_to_be_added);
1004 * Add @a masks_to_be_added to the @a handle's entry in WFMO_Reactor.
1005 * The Event_Handler associated with @a handle must already have been
1006 * registered with WFMO_Reactor.
1008 virtual int schedule_wakeup (ACE_HANDLE handle,
1009 ACE_Reactor_Mask masks_to_be_added);
1012 * Remove @a masks_to_be_deleted to the <handle>'s entry in
1013 * WFMO_Reactor. The Event_Handler associated with @a event_handler must
1014 * already have been registered with WFMO_Reactor.
1016 virtual int cancel_wakeup (ACE_Event_Handler *event_handler,
1017 ACE_Reactor_Mask masks_to_be_deleted);
1020 * Remove @a masks_to_be_deleted to the @a handle's entry in
1021 * WFMO_Reactor. The Event_Handler associated with @a handle must
1022 * already have been registered with WFMO_Reactor.
1024 virtual int cancel_wakeup (ACE_HANDLE handle,
1025 ACE_Reactor_Mask masks_to_be_deleted);
1027 // = Notification methods.
1030 * Wakeup one <ACE_WFMO_Reactor> thread if it is currently blocked
1031 * in <WaitForMultipleObjects>. The ACE_Time_Value indicates how
1032 * long to blocking trying to notify the <WFMO_Reactor>. If
1033 * @a timeout == 0, the caller will block until action is possible,
1034 * else will wait until the relative time specified in @a timeout
1035 * elapses).
1037 virtual int notify (ACE_Event_Handler * = 0,
1038 ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
1039 ACE_Time_Value * = 0);
1042 * Set the maximum number of times that the
1043 * <ACE_WFMO_Reactor_Notify::handle_input> method will iterate and
1044 * dispatch the ACE_Event_Handlers that are passed in via the
1045 * notify queue before breaking out of its
1046 * <ACE_Message_Queue::dequeue> loop. By default, this is set to
1047 * -1, which means "iterate until the queue is empty." Setting this
1048 * to a value like "1 or 2" will increase "fairness" (and thus
1049 * prevent starvation) at the expense of slightly higher dispatching
1050 * overhead.
1052 virtual void max_notify_iterations (int);
1055 * Get the maximum number of times that the
1056 * <ACE_WFMO_Reactor_Notify::handle_input> method will iterate and
1057 * dispatch the ACE_Event_Handlers that are passed in via the
1058 * notify queue before breaking out of its
1059 * <ACE_Message_Queue::dequeue> loop.
1061 virtual int max_notify_iterations ();
1064 * Purge any notifications pending in this reactor for the specified
1065 * ACE_Event_Handler object. Returns the number of notifications
1066 * purged. Returns -1 on error.
1068 virtual int purge_pending_notifications (ACE_Event_Handler * = 0,
1069 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
1071 // = Assorted helper methods.
1074 * Return the Event_Handler associated with @a handle. Return 0 if
1075 * @a handle is not registered.
1077 ACE_Event_Handler *find_handler (ACE_HANDLE handle);
1080 * Check to see if @a handle is associated with a valid Event_Handler
1081 * bound to @a mask. Return the @a event_handler associated with this
1082 * @a handler if @a event_handler != 0.
1084 virtual int handler (ACE_HANDLE handle,
1085 ACE_Reactor_Mask mask,
1086 ACE_Event_Handler **event_handler = 0);
1089 * Check to see if @a signum is associated with a valid Event_Handler
1090 * bound to a signal. Return the <event_handler> associated with
1091 * this @a handler if <event_handler> != 0.
1093 virtual int handler (int signum,
1094 ACE_Event_Handler ** = 0);
1096 /// Returns true if WFMO_Reactor has been successfully initialized, else
1097 /// false.
1098 virtual bool initialized ();
1100 /// Returns the current size of the WFMO_Reactor's internal
1101 /// descriptor table.
1102 virtual size_t size () const;
1104 /// Returns a reference to the WFMO_Reactor's internal lock.
1105 virtual ACE_Lock &lock ();
1107 /// Wake up all threads in WaitForMultipleObjects so that they can
1108 /// reconsult the handle set
1109 virtual void wakeup_all_threads ();
1112 * Transfers ownership of the WFMO_Reactor to the @a new_owner. The
1113 * transfer will not complete until all threads are ready (just like
1114 * the handle set).
1116 virtual int owner (ACE_thread_t new_owner, ACE_thread_t *old_owner = 0);
1118 /// Return the ID of the "owner" thread.
1119 virtual int owner (ACE_thread_t *owner);
1121 /// Get the existing restart value.
1122 virtual bool restart ();
1124 /// Set a new value for restart and return the original value.
1125 virtual bool restart (bool r);
1127 /// Not implemented
1128 virtual void requeue_position (int);
1130 /// Not implemented
1131 virtual int requeue_position ();
1133 // = Low-level wait_set mask manipulation methods.
1136 * Modify @a masks of the @a event_handler's entry in WFMO_Reactor
1137 * depending upon <operation>. @a event_handler must already have
1138 * been registered with WFMO_Reactor.
1140 virtual int mask_ops (ACE_Event_Handler *event_handler,
1141 ACE_Reactor_Mask masks,
1142 int operation);
1145 * Modify @a masks of the <handle>'s entry in WFMO_Reactor depending
1146 * upon <operation>. <handle> must already have been registered
1147 * with WFMO_Reactor.
1149 virtual int mask_ops (ACE_HANDLE handle,
1150 ACE_Reactor_Mask masks,
1151 int ops);
1153 // = Low-level ready_set mask manipulation methods.
1155 /// Not implemented
1156 virtual int ready_ops (ACE_Event_Handler *event_handler,
1157 ACE_Reactor_Mask mask,
1158 int ops);
1160 /// Not implemented
1161 virtual int ready_ops (ACE_HANDLE handle,
1162 ACE_Reactor_Mask,
1163 int ops);
1165 /// Declare the dynamic allocation hooks.
1166 ACE_ALLOC_HOOK_DECLARE;
1168 /// Dump the state of an object.
1169 virtual void dump () const;
1171 protected:
1172 /// Registration workhorse
1173 virtual int register_handler_i (ACE_HANDLE event_handle,
1174 ACE_HANDLE io_handle,
1175 ACE_Event_Handler *event_handler,
1176 ACE_Reactor_Mask mask);
1178 /// Event handling workhorse
1179 virtual int event_handling (ACE_Time_Value *max_wait_time = 0,
1180 int alertable = 0);
1182 /// Bit masking workhorse
1183 virtual int mask_ops_i (ACE_HANDLE io_handle,
1184 ACE_Reactor_Mask masks,
1185 int operation);
1187 /// Return the ID of the "owner" thread. Does not do any locking.
1188 virtual ACE_thread_t owner_i ();
1190 /// Wait up to @a max_wait_time until it's ok to enter
1191 /// WaitForMultipleObjects. Returns 1 (and holding lock_) if ok to wait;
1192 /// -1 (and not holding lock_) if not.
1193 virtual int ok_to_wait (ACE_Time_Value *max_wait_time,
1194 int alertable);
1196 /// Wait for timer and I/O events to occur.
1197 virtual DWORD wait_for_multiple_events (int timeout,
1198 int alertable);
1200 /// Check for activity on remaining handles.
1201 virtual DWORD poll_remaining_handles (DWORD slot);
1203 /// Expire timers. Only the owner thread does useful stuff in this
1204 /// function.
1205 virtual int expire_timers ();
1207 /// Dispatches the timers and I/O handlers.
1208 virtual int dispatch (DWORD wait_status);
1210 /// Protect against structured exceptions caused by user code when
1211 /// dispatching handles
1212 virtual int safe_dispatch (DWORD wait_status);
1215 * Dispatches any active handles from handles_[@a slot] to
1216 * handles_[active_handles_] using <WaitForMultipleObjects> to poll
1217 * through our handle set looking for active handles.
1219 virtual int dispatch_handles (DWORD slot);
1221 /// Dispatches a single handler. Returns 0 on success, -1 if the
1222 /// handler was removed.
1223 virtual int dispatch_handler (DWORD slot,
1224 DWORD max_handlep1);
1226 /// Dispatches a single handler. Returns 0 on success, -1 if the
1227 /// handler was removed.
1228 virtual int simple_dispatch_handler (DWORD slot,
1229 ACE_HANDLE event_handle);
1231 /// Dispatches a single handler. Returns 0 on success, -1 if the
1232 /// handler was removed.
1233 virtual int complex_dispatch_handler (DWORD slot,
1234 ACE_HANDLE event_handle);
1236 /// Dispatches window messages. Noop for WFMO_Reactor.
1237 virtual int dispatch_window_messages ();
1239 virtual ACE_Reactor_Mask upcall (ACE_Event_Handler *event_handler,
1240 ACE_HANDLE io_handle,
1241 WSANETWORKEVENTS &events);
1243 /// Used to caluculate the next timeout
1244 virtual int calculate_timeout (ACE_Time_Value *time);
1246 /// Update the state of the handler repository
1247 virtual int update_state ();
1249 /// Check to see if we have a new owner
1250 virtual int new_owner ();
1252 /// Set owner to new owner
1253 virtual int change_owner ();
1255 /// Handle signals without requiring global/static variables.
1256 ACE_Sig_Handler *signal_handler_;
1258 /// Keeps track of whether we should delete the signal handler (if we
1259 /// didn't create it, then we don't delete it).
1260 bool delete_signal_handler_;
1262 /// Defined as a pointer to allow overriding by derived classes...
1263 ACE_Timer_Queue *timer_queue_;
1265 /// Keeps track of whether we should delete the timer queue (if we
1266 /// didn't create it, then we don't delete it).
1267 bool delete_timer_queue_;
1269 /// Keeps track of whether we should delete the handler repository
1270 bool delete_handler_rep_;
1272 /// Used when <notify> is called.
1273 ACE_Reactor_Notify *notify_handler_;
1275 /// Keeps track of whether we should delete the notify handler.
1276 bool delete_notify_handler_;
1279 * Synchronization for the ACE_WFMO_Reactor.
1281 * A Process Mutex is used here because of two reasons:
1282 * (a) The implementation of ACE_Thread_Mutex uses CriticalSections
1283 * CriticalSections are not waitable using ::WaitForMultipleObjects
1284 * (b) This is really not a process mutex because it is not
1285 * named. No other process can use this mutex.
1287 ACE_Process_Mutex lock_;
1289 /// Adapter used to return internal lock to outside world.
1290 ACE_Lock_Adapter<ACE_Process_Mutex> lock_adapter_;
1292 /// Table that maps <ACE_HANDLEs> to <ACE_Event_Handler *>'s.
1293 ACE_WFMO_Reactor_Handler_Repository handler_rep_;
1295 /// A manual event used to block threads from proceeding into
1296 /// WaitForMultipleObjects
1297 ACE_Manual_Event ok_to_wait_;
1300 * A manual event is used so that we can wake everyone up (e.g.,
1301 * when ACE_Event_Handlers are bounded and unbound from the
1302 * handler repository).
1304 ACE_Manual_Event wakeup_all_threads_;
1306 /// Used when <wakeup_all_threads_> is signaled
1307 ACE_Wakeup_All_Threads_Handler wakeup_all_threads_handler_;
1309 /// The changing thread waits on this event, till all threads are not
1310 /// active anymore
1311 ACE_Auto_Event waiting_to_change_state_;
1313 /// Count of currently active threads
1314 size_t active_threads_;
1317 * The thread which is "owner" of the WFMO_Reactor. The owner
1318 * concept is used because we don't want multiple threads to try to
1319 * expire timers. Therefore the "owner" thread is the only one
1320 * allowed to expire timers. Also, the owner thread is the only
1321 * thread which waits on the notify handle. Note that the ownership
1322 * can be transferred.
1324 ACE_thread_t owner_;
1326 /// The owner to be of the WFMO_Reactor
1327 ACE_thread_t new_owner_;
1329 /// This is the thread which is responsible for the changing the
1330 /// state of the <WFMO_Reactor> handle set
1331 ACE_thread_t change_state_thread_;
1333 /// This is an array of ACE_HANDLEs which keep track of the <lock_>
1334 /// and <ok_to_wait_> handles
1335 ACE_HANDLE atomic_wait_array_ [2];
1337 /// This flag is used to keep track of whether we are already closed.
1338 bool open_for_business_;
1340 /// This flag is used to keep track of whether we are actively handling
1341 /// events or not.
1342 sig_atomic_t deactivated_;
1344 private:
1345 ACE_WFMO_Reactor (const ACE_WFMO_Reactor &) = delete;
1346 ACE_WFMO_Reactor &operator = (const ACE_WFMO_Reactor &) = delete;
1349 ACE_END_VERSIONED_NAMESPACE_DECL
1351 #if defined (__ACE_INLINE__)
1352 #include "ace/WFMO_Reactor.inl"
1353 #endif /* __ACE_INLINE__ */
1355 #endif /* ACE_WIN32 */
1356 #include /**/ "ace/post.h"
1357 #endif /* ACE_WFMO_REACTOR_H */