📄 manual.cpp
字号:
// manual.cpp,v 4.20 2003/11/01 11:15:24 dhinton Exp
// ============================================================================
//
// = LIBRARY
// examples
//
// = FILENAME
// manual.cpp
//
// = DESCRIPTION
// Allows manual operations on local and remote tokens.
//
// = AUTHOR
// Tim Harrison
//
// ============================================================================
#include "ace/Get_Opt.h"
#include "ace/Local_Tokens.h"
#include "ace/Remote_Tokens.h"
#include "ace/Singleton.h"
#include "ace/Thread_Manager.h"
#include "ace/Token_Invariants.h"
#include "ace/Token_Collection.h"
#include "ace/Map_Manager.h"
#include "ace/Service_Config.h"
#if defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREADS_LIBRARY)
ACE_RCSID(manual, manual, "manual.cpp,v 4.20 2003/11/01 11:15:24 dhinton Exp")
typedef ACE_Token_Invariant_Manager ACE_TOKEN_INVARIANTS;
class STDIN_Token : public ACE_Event_Handler
// = TITLE
// STDIN Token
//
// = DESCRIPTION
// Translates STDIN commands to ACE Token commands.
{
public:
STDIN_Token (void);
// Construction.
int parse_args (int argc, char *argv[]);
// Parse command-line arguments.
int open (int argc, char *argv[]);
// Register with whatever event dispatcher is needed and run.
// = Event_Handler methods.
int handle_input (ACE_HANDLE);
int handle_exception (ACE_HANDLE);
typedef ACE_CString TID;
private:
void display_menu (void);
// Display options.
ACE_Token_Proxy *get_proxy (const char *tid, const char *token, char type);
// Get or make a proxy to <token> with a <tid> client id.
ACE_Token_Proxy *create_proxy (const char *token, char type);
// Create a proxy to <token> with a <tid> client id.
// = Mapping from tid to Token_Collection.
typedef ACE_Map_Manager<TID, ACE_Token_Collection *, ACE_Null_Mutex>
COLLECTIONS;
// COLLECTION maintains a mapping from tid to a collection.
typedef ACE_Map_Iterator<TID, ACE_Token_Collection *, ACE_Null_Mutex>
COLLECTIONS_ITERATOR;
// Allows iterations through collections_.
typedef ACE_Map_Entry<TID, ACE_Token_Collection *>
COLLECTIONS_ENTRY;
// Allows iterations through collections_.
COLLECTIONS collections_;
// A collection for each <tid>.
const char *server_host_;
int server_port_;
int ignore_deadlock_;
int debug_;
int remote_;
};
STDIN_Token::STDIN_Token (void)
: server_host_ (ACE_DEFAULT_SERVER_HOST),
server_port_ (ACE_DEFAULT_SERVER_PORT),
ignore_deadlock_ (0),
debug_ (0),
remote_ (0)
{
}
int
STDIN_Token::parse_args (int argc, char *argv[])
{
ACE_LOG_MSG->open (argv[0], ACE_Log_Msg::STDERR);
ACE_Get_Opt get_opt (argc, argv, "h:p:diu", 1);
for (int c; (c = get_opt ()) != -1; )
{
switch (c)
{
case 'h': // specify the host machine on which the server is running
server_host_ = get_opt.opt_arg ();
remote_ = 1;
break;
case 'p': // specify the port on which the server is running
server_port_ = ACE_OS::atoi (get_opt.opt_arg ());
remote_ = 1;
break;
case 'd':
debug_ = 1;
break;
case 'i':
ignore_deadlock_ = 1;
break;
case 'u':
// usage: fallthrough
default:
ACE_ERROR_RETURN ((LM_ERROR,
"%n:\n"
"[-h <remote host>]\n"
"[-p <remote port>]\n"
"[-i ignore deadlock]\n"
"[-d debug]\n", 1), -1);
}
}
if (remote_)
ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port_,
server_host_));
return 0;
}
int
STDIN_Token::open (int argc, char *argv[])
{
if (this->parse_args (argc, argv) == -1)
return -1;
// Register for signals.
if (ACE_Reactor::instance ()->register_handler
(SIGINT, this) == -1)
ACE_DEBUG ((LM_DEBUG, "Can't register signal handler\n"));
#if defined (ACE_WIN32)
#else
// Register for STDIN events with Reactor.
if (ACE_Reactor::instance ()->register_handler
(ACE_STDIN, this, ACE_Event_Handler::READ_MASK) == -1)
ACE_ERROR_RETURN ((LM_DEBUG, "Can't register signal handler\n"), 0);
#endif /* ACE_WIN32 */
this->display_menu ();
#if defined (ACE_WIN32)
#else
ACE_Reactor::run_event_loop ();
#endif /* ACE_WIN32 */
ACE_OS::printf ("Exiting...\n");
return 0;
}
int
STDIN_Token::handle_input (ACE_HANDLE fd)
{
ACE_UNUSED_ARG (fd);
char tid[BUFSIZ];
char token[BUFSIZ];
char type[16];
char operation[16];
if (::scanf ("%s %s %s %s", tid, token, type, operation) <= 0)
{
ACE_OS::printf ("Try again.\n");
return 0;
}
ACE_Token_Proxy *proxy =
this->get_proxy (tid, token, type[0]);
if (proxy == 0)
return -1;
switch (operation[0])
{
case 'a':
case 'A':
if (proxy->acquire () == 0)
{
ACE_OS::printf ("Succeeded.\n");
if (ACE_TOKEN_INVARIANTS::instance ()->acquired (proxy) == 0)
ACE_OS::printf ("Violated invariant.\n");
}
else
ACE_ERROR ((LM_ERROR, "%p.\n", "Acquire failed"));
break;
case 'n':
case 'N':
ACE_TOKEN_INVARIANTS::instance ()->releasing (proxy);
if (proxy->renew () == 0)
{
ACE_OS::printf ("Succeeded.\n");
if (ACE_TOKEN_INVARIANTS::instance ()->acquired (proxy) == 0)
ACE_OS::printf ("Violated invariant.\n");
}
else
ACE_ERROR ((LM_ERROR, "%p.\n", "Renew failed"));
break;
case 'r':
case 'R':
ACE_TOKEN_INVARIANTS::instance ()->releasing (proxy);
if (proxy->release () == 0)
ACE_OS::printf ("Succeeded.\n");
else
ACE_ERROR ((LM_ERROR, "%p.\n", "Release failed"));
break;
case 't':
case 'T':
if (proxy->tryacquire () == 0)
{
ACE_OS::printf ("Succeeded.\n");
if (ACE_TOKEN_INVARIANTS::instance ()->acquired (proxy) == 0)
ACE_OS::printf ("Violated invariant.\n");
}
else
ACE_ERROR ((LM_ERROR, "%p.\n", "Tryacquire failed"));
break;
}
this->display_menu ();
return 0;
}
void
STDIN_Token::display_menu (void)
{
ACE_OS::printf ("<tid> <token> <type> <operation>\n");
}
int
STDIN_Token::handle_exception (ACE_HANDLE fd)
{
ACE_UNUSED_ARG (fd);
ACE_Reactor::run_event_loop ();
return -1;
}
ACE_Token_Proxy *
STDIN_Token::get_proxy (const char *_tid, const char *token, char type)
{
ACE_Token_Collection *proxy_collection;
TID tid (_tid);
if (collections_.find (tid, proxy_collection) == -1)
// We did not find a proxy_collection.
{
// Make one.
proxy_collection = new ACE_Token_Collection (debug_, "no name collection");
// Put it in the collections.
if (collections_.bind (tid, proxy_collection) == -1)
{
delete proxy_collection;
return 0;
}
}
// Either way, we have a proxy_collection now.
// See if the proxy already exists in the collection.
ACE_Token_Proxy *proxy = proxy_collection->is_member (token);
// If not, create one.
if (proxy == 0)
{
proxy = this->create_proxy (token, type);
// Put the new_proxy in this tid's collection.
if (proxy_collection->insert (*proxy) == -1)
ACE_ERROR_RETURN ((LM_ERROR, "insert failed\n"), 0);
// Delete our copy (one was created in the collection).
delete proxy;
proxy = proxy_collection->is_member (token);
if (proxy == 0)
ACE_ERROR_RETURN ((LM_ERROR, "is_member failed\n"), 0);
// Set the client_id (it was set to 1 since we're
// single-threaded.
proxy->client_id (_tid);
}
return proxy;
}
ACE_Token_Proxy *
STDIN_Token::create_proxy (const char *token, char type)
{
switch (type)
{
case 'm':
case 'M':
if (remote_)
return new ACE_Remote_Mutex (token, ignore_deadlock_, debug_);
else
return new ACE_Local_Mutex (token, ignore_deadlock_, debug_);
case 'r':
case 'R':
if (remote_)
return new ACE_Remote_RLock (token, ignore_deadlock_, debug_);
else
return new ACE_Local_RLock (token, ignore_deadlock_, debug_);
case 'w':
case 'W':
if (remote_)
return new ACE_Remote_WLock (token, ignore_deadlock_, debug_);
else
return new ACE_Local_WLock (token, ignore_deadlock_, debug_);
}
// should never get here, but this avoids a compiler warning . . .
return 0;
}
int
main (int argc, char* argv[])
{
STDIN_Token st;
return st.open (argc, argv);
}
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
template class ACE_Map_Entry<STDIN_Token::TID, ACE_Token_Collection *>;
template class ACE_Map_Manager<STDIN_Token::TID, ACE_Token_Collection *, ACE_Null_Mutex>;
template class ACE_Map_Iterator_Base<STDIN_Token::TID, ACE_Token_Collection *, ACE_Null_Mutex>;
template class ACE_Map_Iterator<STDIN_Token::TID, ACE_Token_Collection *, ACE_Null_Mutex>;
template class ACE_Map_Reverse_Iterator<STDIN_Token::TID, ACE_Token_Collection *, ACE_Null_Mutex>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
#pragma instantiate ACE_Map_Entry<STDIN_Token::TID, ACE_Token_Collection *>
#pragma instantiate ACE_Map_Manager<STDIN_Token::TID, ACE_Token_Collection *, ACE_Null_Mutex>
#pragma instantiate ACE_Map_Iterator_Base<STDIN_Token::TID, ACE_Token_Collection *, ACE_Null_Mutex>
#pragma instantiate ACE_Map_Iterator<STDIN_Token::TID, ACE_Token_Collection *, ACE_Null_Mutex>
#pragma instantiate ACE_Map_Reverse_Iterator<STDIN_Token::TID, ACE_Token_Collection *, ACE_Null_Mutex>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
#else
int
main (int, char *[])
{
ACE_ERROR_RETURN ((LM_ERROR,
"threads or ACE_HAS_TOKENS_LIBRARY not supported on this platform\n"), -1);
}
#endif /* ACE_HAS_THREADS && ACE_HAS_TOKENS_LIBRARY */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -