NAME

ACE_Select_Reactor_Token_T - Used as a synchronization mechanism to coordinate concurrent access to a Select_Reactor object.

SYNOPSIS

#include <ace/Select_Reactor_T.h>

template<class ACE_SELECT_REACTOR_MUTEX> class ACE_Select_Reactor_Token_T : public ACE_SELECT_REACTOR_MUTEX { public: ACE_Select_Reactor_Token_T (ACE_Select_Reactor_Impl &r); ACE_Select_Reactor_Token_T (void); virtual ~ACE_Select_Reactor_Token_T (void); virtual void sleep_hook (void); ACE_Select_Reactor_Impl &select_reactor (void); void select_reactor (ACE_Select_Reactor_Impl &); virtual void dump (void) const; ACE_ALLOC_HOOK_DECLARE; private: ACE_Select_Reactor_Impl *select_reactor_; };

DESCRIPTION

This class is used to make the ACE_Select_Reactor thread-safe. By default, the thread that runs the handle_events loop holds the token, even when it is blocked in the select call. Whenever another thread wants to access the ACE_Reactor via its register_handler, remove_handler, etc. methods) it must ask the token owner for temporary release of the token. To accomplish this, the owner of a token must define a sleep_hook through which it can be notified to temporarily release the token if the current situation permits this.

The owner of the token is responsible for deciding which request for the token can be granted. By using the ACE_Token::renew API, the thread that releases the token temporarily can specify to get the token back right after the other thread has completed using the token. Thus, there is a dedicated thread that owns the token ``by default.'' This thread grants other threads access to the token by ensuring that whenever somebody else has finished using the token the ``default owner'' first holds the token again, i.e., the owner has the chance to schedule other threads.

The thread that most likely needs the token most of the time is the thread running the dispatch loop. Typically the token gets released prior to entering the select call and gets ``re-acquired'' as soon as the select call returns, which results probably in many calls to release/acquire that are not really needed since no other thread would need the token in the meantime. That's why the dispatcher thread is chosen to be the owner of the token.

In case the token would have been released while in select there would be a good chance that the fd_set could have been modified while the select returns from blocking and trying to re-acquire the lock. Through the token mechanism it is ensured that while another thread is holding the token, the dispatcher thread is blocked in the renew call and not in select. Thus, it is not critical to change the fd_set. The implementation of the sleep_hook mechanism provided by the ACE_Select_Reactor_Token enables the default owner to be the thread that executes the dispatch loop.

PUBLIC MEMBERS

ACE_Select_Reactor_Token_T (ACE_Select_Reactor_Impl &r);

ACE_Select_Reactor_Token_T (void);

virtual ~ACE_Select_Reactor_Token_T (void);

virtual void sleep_hook (void);

ACE_Select_Reactor_Impl &select_reactor (void);

void select_reactor (ACE_Select_Reactor_Impl &);

virtual void dump (void) const;

ACE_ALLOC_HOOK_DECLARE;

PRIVATE MEMBERS

ACE_Select_Reactor_Impl *select_reactor_;

AUTHOR

Doug Schmidt

LIBRARY

ace