3 //=============================================================================
5 * @file Token_Handler.h
7 * @author Douglas C. Schmidt (d.schmidt@vanderbilt.edu)
8 * Tim Harrison (harrison@cs.wustl.edu)
10 //=============================================================================
12 #ifndef ACE_TOKEN_HANDLER_H
13 #define ACE_TOKEN_HANDLER_H
15 #include "ace/Acceptor.h"
17 #if !defined (ACE_LACKS_PRAGMA_ONCE)
19 #endif /* ACE_LACKS_PRAGMA_ONCE */
21 #include "ace/SOCK_Acceptor.h"
22 #include "ace/Local_Tokens.h"
23 #include "ace/Token_Collection.h"
24 #include "ace/Token_Request_Reply.h"
25 #include "ace/svc_export.h"
27 #if defined (ACE_HAS_TOKENS_LIBRARY)
30 * @class ACE_Token_Handler
32 * @brief Product object created by an <ACE_Token_Acceptor>. A
33 * <Token_Handler> exchanges messages with a <Token_Proxy> object
36 * This class is the main workhorse of the ACE Token service. It
37 * receives token operation requests from remote clients and turns
38 * them into calls on local tokens (acquire, release, renew, and
39 * remove). In OMG CORBA terms, it is an object adapter. It also
40 * schedules and handles timeouts that are used to support "timed
41 * waits." Clients used timed waits to bound the amount of time
42 * they block trying to get a token.
44 class ACE_Svc_Export ACE_Token_Handler
: public ACE_Svc_Handler
<ACE_SOCK_STREAM
, ACE_NULL_SYNCH
>
47 /// Default constructor.
48 ACE_Token_Handler (ACE_Thread_Manager
* = 0);
50 // = Accessor and mutator methods.
52 // = Remote operations "exported" to a client.
54 * Try to acquire the token.
55 * Precondition: client *may* hold the token already (i.e.,
56 * supports recursive acquisitions).
58 virtual int acquire (ACE_Token_Proxy
*proxy
);
60 /// Try to acquire the token.
61 virtual int try_acquire (ACE_Token_Proxy
*proxy
);
63 /// Release the token and allow the next client that is waiting to
64 /// proceed. Preconditions: client must hold the token.
65 virtual int release (ACE_Token_Proxy
*proxy
);
67 /// Yield the token if any clients are waiting, otherwise keep the
68 /// token. Preconditions: client must hold the token.
69 virtual int renew (ACE_Token_Proxy
*proxy
);
72 * Remove the specified token from the Token_Map. Preconditions:
73 * ACE_Token must exist. @@ Any other preconditions, e.g., must
74 * client hold token, must there be no waiters, etc.?
76 virtual int remove (ACE_Token_Proxy
*proxy
);
78 /// Called by TS_[Mutex,RLock,WLock] when we hold the mutex and
82 /// Called by TS_[Mutex,RLock,WLock] when we are waiting and acquire
84 void token_acquired (ACE_TPQ_Entry
*);
87 // = Low level routines for framing requests, dispatching
88 // operations, and returning replies.
90 /// Our connection has been closed.
91 virtual int abandon (int send_error
);
93 /// Receive, frame, and decode the client's request.
94 virtual int recv_request ();
96 /// Dispatch the appropriate operation to handle the client's
98 virtual int dispatch ();
100 /// Create and send a reply to the client.
101 virtual int send_reply (ACE_UINT32 errnum
);
103 // = Demultiplexing hooks.
104 /// Callback method invoked by the <ACE_Reactor> when client events
106 virtual int handle_input (ACE_HANDLE
);
109 /// Enable clients to limit the amount of time they wait for a token.
110 virtual int handle_timeout (const ACE_Time_Value
&tv
, const void *arg
);
112 /// return a proxy for the calling client_id and token name.
113 ACE_Token_Proxy
*get_proxy ();
116 /// Switches on the type of token_request_ and creates a new
118 virtual ACE_Token_Proxy
*create_proxy ();
120 /// Keeps track of the synchronization options (i.e., the timeout
122 ACE_Synch_Options request_options_
;
124 /// collection of the client's token proxies.
125 ACE_Token_Collection collection_
;
127 /// ID returned by the Reactor that is used to kill registered timers
128 /// when a token operation times out.
131 /// Cache request from the client.
132 ACE_Token_Request token_request_
;
134 /// Cache reply to the client.
135 ACE_Token_Reply token_reply_
;
138 // = DESCRIPTION of ACE_TS_* classes:
139 // When Tokens are released, waiting token proxies are notified
140 // when the releasing thread calls token_acquired on the waiting
141 // proxy. The Token Server specializes ACE_Token_Proxy to
142 // redefine the implementation of token_acquired. When
143 // token_acquired is called, the Token_Handler can then send the
144 // response back over the socket connection to unblock the
146 // Since only the Token_Handler uses ACE_TS_Mutex, we've moved
147 // the definition to the .cpp file.
150 * @class ACE_TS_Mutex
152 * @brief ACE_TS_Mutex -- ACE_*T*oken_*S*erver_Mutex
154 class ACE_TS_Mutex
: public ACE_Local_Mutex
158 ACE_TS_Mutex (const ACE_TCHAR
*name
,
159 ACE_Token_Handler
*th
);
162 /// Somebody wants our token!
163 virtual void sleep_hook ();
166 * We've been taken off the waiters list and given the token! Call
167 * the Token_Handler associated at construction, so it can tell the
170 virtual void token_acquired (ACE_TPQ_Entry
*);
173 ACE_TS_Mutex (const ACE_TS_Mutex
&);
175 /// Return a deep copy.
176 virtual ACE_Token_Proxy
*clone () const;
179 /// The Token Handler associated with this proxy. Set at
180 /// construction and notified when blocking acquires succeed.
181 ACE_Token_Handler
* th_
;
185 * @class ACE_TS_RLock
187 * @brief ACE_TS_RLock -- ACE_*T*oken_*S*erver_RLock
189 class ACE_TS_RLock
: public ACE_Local_RLock
193 ACE_TS_RLock (const ACE_TCHAR
*name
,
194 ACE_Token_Handler
*th
);
197 /// Somebody wants our token!
198 virtual void sleep_hook ();
201 * We've been taken off the waiters list and given the token! Call
202 * the Token_Handler associated at construction, so it can tell the
205 virtual void token_acquired (ACE_TPQ_Entry
*);
208 ACE_TS_RLock (const ACE_TS_RLock
&);
210 /// Return a deep copy.
211 virtual ACE_Token_Proxy
*clone () const;
214 /// the Token Handler associated with this proxy. Set at
215 /// construction and notified when blocking acquires succeed.
216 ACE_Token_Handler
* th_
;
220 * @class ACE_TS_WLock
222 * @brief ACE_TS_WLock -- ACE_*T*oken_*S*erver_WLock
224 class ACE_TS_WLock
: public ACE_Local_WLock
228 ACE_TS_WLock (const ACE_TCHAR
*name
,
229 ACE_Token_Handler
*th
);
232 /// Somebody wants our token!
233 virtual void sleep_hook ();
236 * We've been taken off the waiters list and given the token! Call
237 * the Token_Handler associated at construction, so it can tell the
240 virtual void token_acquired (ACE_TPQ_Entry
*);
243 ACE_TS_WLock (const ACE_TS_WLock
&);
245 /// Return a deep copy.
246 virtual ACE_Token_Proxy
*clone () const;
249 /// the Token Handler associated with this proxy. Set at
250 /// construction and notified when blocking acquires succeed.
251 ACE_Token_Handler
* th_
;
255 * @class ACE_Token_Acceptor
257 * @brief This class contains the service-specific methods that can't
258 * easily be factored into the <ACE_Strategy_Acceptor>.
260 class ACE_Token_Acceptor
: public ACE_Strategy_Acceptor
<ACE_Token_Handler
, ACE_SOCK_ACCEPTOR
>
263 /// Dynamic linking hook.
264 virtual int init (int argc
, ACE_TCHAR
*argv
[]);
266 /// Parse svc.conf arguments.
267 int parse_args (int argc
, ACE_TCHAR
*argv
[]);
270 /// The scheduling strategy is designed for Reactive services.
271 ACE_Schedule_All_Reactive_Strategy
<ACE_Token_Handler
> scheduling_strategy_
;
274 ACE_SVC_FACTORY_DECLARE (ACE_Token_Acceptor
)
276 #endif /* ACE_HAS_TOKENS_LIBRARY */
277 #endif /* ACE_TOKEN_HANDLER_H */