## NAME

ACE_Select_Reactor_Notify - Unblock the `ACE_Select_Reactor` from its event loop.

## SYNOPSIS

    #include <ace/Select_Reactor_Base.h>

    class ACE_Select_Reactor_Notify : public ACE_Reactor_Notify
    {
      public:
        ACE_Select_Reactor_Notify (void);
        ~ACE_Select_Reactor_Notify (void);
        virtual int open (
            ACE_Reactor_Impl *,
            ACE_Timer_Queue * = 0,
            int disable_notify_pipe = 0
            );
        virtual int close (void);
        virtual ssize_t notify (
            ACE_Event_Handler * = 0,
            ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
            ACE_Time_Value * = 0
            );
        virtual int dispatch_notifications (
            int &number_of_active_handles,
            ACE_Handle_Set &rd_mask
            );
        virtual int handle_input (ACE_HANDLE handle);
        virtual void max_notify_iterations (int);
        virtual int max_notify_iterations (void);
        virtual void dump (void) const;
        ACE_ALLOC_HOOK_DECLARE;
      private:
        ACE_Select_Reactor_Impl *select_reactor_;
        ACE_Pipe notification_pipe_;
        int max_notify_iterations_;
    };

## DESCRIPTION

This implementation is necessary for cases where the `ACE_Select_Reactor` is run in a multi-threaded program. In this case, we need to be able to unblock select() or poll() when updates occur other than in the main `ACE_Select_Reactor` thread. To do this, we signal an auto-reset event the `ACE_Select_Reactor` is listening on. If an `ACE_Event_Handler` and `ACE_Select_Reactor_Mask` is passed to `notify`, the appropriate `handle_*` method is dispatched in the context of the `ACE_Select_Reactor` thread.

## Initialization and termination methods.

    virtual int open (
        ACE_Reactor_Impl *,
        ACE_Timer_Queue * = 0,
        int disable_notify_pipe = 0
        );

Initialize.

    virtual int close (void);

Destroy.

    virtual ssize_t notify (
        ACE_Event_Handler * = 0,
        ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
        ACE_Time_Value * = 0
        );

Called by a thread when it wants to unblock the `ACE_Select_Reactor`. This wakeups the `ACE_Select_Reactor` if currently blocked in select()/poll(). Pass over both the `Event_Handler` *and* the `mask` to allow the caller to dictate which `Event_Handler` method the `ACE_Select_Reactor` will invoke. The `ACE_Time_Value` indicates how long to blocking trying to notify the `ACE_Select_Reactor`. If `timeout` == 0, the caller will block until action is possible, else will wait until the relative time specified in *`timeout` elapses).

    virtual int dispatch_notifications (
        int &number_of_active_handles,
        ACE_Handle_Set &rd_mask
        );

Handles pending threads (if any) that are waiting to unblock the `ACE_Select_Reactor`.

    virtual int handle_input (ACE_HANDLE handle);

Called back by the `ACE_Select_Reactor` when a thread wants to unblock us.

    virtual void max_notify_iterations (int);

Set the maximum number of times that the `ACE_Select_Reactor_Notify::handle_input` method will iterate and dispatch the `ACE_Event_Handlers` that are passed in via the notify pipe before breaking out of its `recv` loop. By default, this is set to -1, which means "iterate until the pipe is empty." Setting this to a value like "1 or 2" will increase "fairness" (and thus prevent starvation) at the expense of slightly higher dispatching overhead.

    virtual int max_notify_iterations (void);

Get the maximum number of times that the `ACE_Select_Reactor_Notify::handle_input` method will iterate and dispatch the `ACE_Event_Handlers` that are passed in via the notify pipe before breaking out of its `recv` loop.

    virtual void dump (void) const;

Dump the state of an object.

    ACE_ALLOC_HOOK_DECLARE;

Declare the dynamic allocation hooks.

## AUTHOR

Doug Schmidt

## LIBRARY

ace