2 //=============================================================================
6 * Allows manual operations on local and remote tokens.
10 //=============================================================================
13 #include "ace/Get_Opt.h"
14 #include "ace/Local_Tokens.h"
15 #include "ace/Remote_Tokens.h"
16 #include "ace/Singleton.h"
17 #include "ace/Thread_Manager.h"
18 #include "ace/Token_Invariants.h"
19 #include "ace/Token_Collection.h"
20 #include "ace/Map_Manager.h"
21 #include "ace/Service_Config.h"
23 #if defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREADS_LIBRARY)
27 typedef ACE_Token_Invariant_Manager ACE_TOKEN_INVARIANTS
;
34 * Translates STDIN commands to ACE Token commands.
36 class STDIN_Token
: public ACE_Event_Handler
42 /// Parse command-line arguments.
43 int parse_args (int argc
, ACE_TCHAR
*argv
[]);
45 //FUZZ: disable check_for_lack_ACE_OS
46 /// Register with whatever event dispatcher is needed and run.
47 ///FUZZ: enable check_for_lack_ACE_OS
48 int open (int argc
, char *argv
[]);
50 // = Event_Handler methods.
51 int handle_input (ACE_HANDLE
);
52 int handle_exception (ACE_HANDLE
);
54 typedef ACE_CString TID
;
59 void display_menu (void);
61 /// Get or make a proxy to <token> with a <tid> client id.
62 ACE_Token_Proxy
*get_proxy (const char *tid
, const char *token
, char type
);
64 /// Create a proxy to <token> with a <tid> client id.
65 ACE_Token_Proxy
*create_proxy (const char *token
, char type
);
67 // = Mapping from tid to Token_Collection.
68 /// COLLECTION maintains a mapping from tid to a collection.
69 typedef ACE_Map_Manager
<TID
, ACE_Token_Collection
*, ACE_Null_Mutex
>
72 /// Allows iterations through collections_.
73 typedef ACE_Map_Iterator
<TID
, ACE_Token_Collection
*, ACE_Null_Mutex
>
76 /// Allows iterations through collections_.
77 typedef ACE_Map_Entry
<TID
, ACE_Token_Collection
*>
80 /// A collection for each <tid>.
81 COLLECTIONS collections_
;
83 const char *server_host_
;
90 STDIN_Token::STDIN_Token (void)
91 : server_host_ (ACE_DEFAULT_SERVER_HOST
),
92 server_port_ (ACE_DEFAULT_SERVER_PORT
),
100 STDIN_Token::parse_args (int argc
, ACE_TCHAR
*argv
[])
102 ACE_LOG_MSG
->open (argv
[0], ACE_Log_Msg::STDERR
);
104 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT("h:p:diu"), 1);
106 for (int c
; (c
= get_opt ()) != -1; )
110 case 'h': // specify the host machine on which the server is running
111 server_host_
= get_opt
.opt_arg ();
114 case 'p': // specify the port on which the server is running
115 server_port_
= ACE_OS::atoi (get_opt
.opt_arg ());
122 ignore_deadlock_
= 1;
125 // usage: fallthrough
127 ACE_ERROR_RETURN ((LM_ERROR
,
129 "[-h <remote host>]\n"
130 "[-p <remote port>]\n"
131 "[-i ignore deadlock]\n"
132 "[-d debug]\n", 1), -1);
137 ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port_
,
144 STDIN_Token::open (int argc
, char *argv
[])
146 if (this->parse_args (argc
, argv
) == -1)
149 // Register for signals.
150 if (ACE_Reactor::instance ()->register_handler
151 (SIGINT
, this) == -1)
152 ACE_DEBUG ((LM_DEBUG
, "Can't register signal handler\n"));
154 #if defined (ACE_WIN32)
157 // Register for STDIN events with Reactor.
158 if (ACE_Reactor::instance ()->register_handler
159 (ACE_STDIN
, this, ACE_Event_Handler::READ_MASK
) == -1)
160 ACE_ERROR_RETURN ((LM_DEBUG
, "Can't register signal handler\n"), 0);
163 #endif /* ACE_WIN32 */
166 this->display_menu ();
168 #if defined (ACE_WIN32)
171 ACE_Reactor::run_event_loop ();
172 #endif /* ACE_WIN32 */
174 ACE_OS::printf ("Exiting...\n");
179 STDIN_Token::handle_input (ACE_HANDLE fd
)
188 if (::scanf ("%s %s %s %s", tid
, token
, type
, operation
) <= 0)
190 ACE_OS::printf ("Try again.\n");
194 ACE_Token_Proxy
*proxy
=
195 this->get_proxy (tid
, token
, type
[0]);
200 switch (operation
[0])
204 if (proxy
->acquire () == 0)
206 ACE_OS::printf ("Succeeded.\n");
207 if (ACE_TOKEN_INVARIANTS::instance ()->acquired (proxy
) == 0)
208 ACE_OS::printf ("Violated invariant.\n");
211 ACE_ERROR ((LM_ERROR
, "%p.\n", "Acquire failed"));
215 ACE_TOKEN_INVARIANTS::instance ()->releasing (proxy
);
216 if (proxy
->renew () == 0)
218 ACE_OS::printf ("Succeeded.\n");
219 if (ACE_TOKEN_INVARIANTS::instance ()->acquired (proxy
) == 0)
220 ACE_OS::printf ("Violated invariant.\n");
223 ACE_ERROR ((LM_ERROR
, "%p.\n", "Renew failed"));
228 ACE_TOKEN_INVARIANTS::instance ()->releasing (proxy
);
229 if (proxy
->release () == 0)
230 ACE_OS::printf ("Succeeded.\n");
232 ACE_ERROR ((LM_ERROR
, "%p.\n", "Release failed"));
237 if (proxy
->tryacquire () == 0)
239 ACE_OS::printf ("Succeeded.\n");
240 if (ACE_TOKEN_INVARIANTS::instance ()->acquired (proxy
) == 0)
241 ACE_OS::printf ("Violated invariant.\n");
244 ACE_ERROR ((LM_ERROR
, "%p.\n", "Tryacquire failed"));
248 this->display_menu ();
253 STDIN_Token::display_menu (void)
255 ACE_OS::printf ("<tid> <token> <type> <operation>\n");
259 STDIN_Token::handle_exception (ACE_HANDLE fd
)
263 ACE_Reactor::run_event_loop ();
268 STDIN_Token::get_proxy (const char *_tid
, const char *token
, char type
)
270 ACE_Token_Collection
*proxy_collection
;
274 if (collections_
.find (tid
, proxy_collection
) == -1)
275 // We did not find a proxy_collection.
278 proxy_collection
= new ACE_Token_Collection (debug_
, "no name collection");
280 // Put it in the collections.
281 if (collections_
.bind (tid
, proxy_collection
) == -1)
283 delete proxy_collection
;
288 // Either way, we have a proxy_collection now.
290 // See if the proxy already exists in the collection.
291 ACE_Token_Proxy
*proxy
= proxy_collection
->is_member (token
);
293 // If not, create one.
296 proxy
= this->create_proxy (token
, type
);
298 // Put the new_proxy in this tid's collection.
299 if (proxy_collection
->insert (*proxy
) == -1)
300 ACE_ERROR_RETURN ((LM_ERROR
, "insert failed\n"), 0);
302 // Delete our copy (one was created in the collection).
304 proxy
= proxy_collection
->is_member (token
);
307 ACE_ERROR_RETURN ((LM_ERROR
, "is_member failed\n"), 0);
309 // Set the client_id (it was set to 1 since we're
311 proxy
->client_id (_tid
);
318 STDIN_Token::create_proxy (const char *token
, char type
)
325 return new ACE_Remote_Mutex (token
, ignore_deadlock_
, debug_
);
327 return new ACE_Local_Mutex (token
, ignore_deadlock_
, debug_
);
332 return new ACE_Remote_RLock (token
, ignore_deadlock_
, debug_
);
334 return new ACE_Local_RLock (token
, ignore_deadlock_
, debug_
);
339 return new ACE_Remote_WLock (token
, ignore_deadlock_
, debug_
);
341 return new ACE_Local_WLock (token
, ignore_deadlock_
, debug_
);
344 // should never get here, but this avoids a compiler warning . . .
349 ACE_TMAIN(int argc
, ACE_TCHAR
*argv
[])
352 return st
.open (argc
, argv
);
357 ACE_TMAIN(int, ACE_TCHAR
*[])
359 ACE_ERROR_RETURN ((LM_ERROR
,
360 "threads or ACE_HAS_TOKENS_LIBRARY not supported on this platform\n"), -1);
362 #endif /* ACE_HAS_THREADS && ACE_HAS_TOKENS_LIBRARY */