Update NEWS
[ACE_TAO.git] / ACE / netsvcs / clients / Tokens / collection / collection.cpp
blob7480288e6b85886681ae7339a418bfb2958e5b69
2 //=============================================================================
3 /**
4 * @file collection.cpp
6 * Shows how applications can use the ACE_Token_Collection
7 * utility. This example creates three collections and spawns a
8 * thread to operate on each. The threads use the collective
9 * acquire, renew, and release features of ACE_Token_Collection.
11 * @author Tim Harrison
13 //=============================================================================
16 #include "ace/Get_Opt.h"
17 #include "ace/Local_Tokens.h"
18 #include "ace/Token_Collection.h"
19 #include "ace/Remote_Tokens.h"
20 #include "ace/Thread_Manager.h"
21 #include "ace/Service_Config.h"
25 #if defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREADS_LIBRARY)
27 static const char *server_host = ACE_DEFAULT_SERVER_HOST;
28 static int server_port = ACE_DEFAULT_SERVER_PORT;
29 // unused: static int threads = 2;
30 static int iterations = 50;
31 static int debug = 0;
32 static int remote = 0;
33 // unused: static int tokens = 5;
35 static void *
36 run_thread (void *vp)
38 ACE_Token_Proxy *collection = (ACE_Token_Proxy *) vp;
40 int count = iterations;
41 while (count--)
43 if (collection->acquire () == -1)
45 if (ACE_OS::last_error () == EDEADLK)
47 ACE_DEBUG ((LM_DEBUG, "deadlock detected in acquire"));
48 continue;
50 ACE_ERROR ((LM_ERROR, "(%t) %p acquire failed\n","run_thread"));
51 return (void *) -1;
54 ACE_DEBUG ((LM_DEBUG, "(%t) %s acquired.\n", collection->name ()));
56 if (collection->renew () == -1)
58 if (ACE_OS::last_error () == EDEADLK)
60 ACE_DEBUG ((LM_DEBUG, "deadlock detected"));
61 goto deadlock;
63 ACE_ERROR ((LM_ERROR, "(%t) %p renew failed\n","run_thread"));
64 return (void *) -1;
67 ACE_DEBUG ((LM_DEBUG, "(%t) %s renewed.\n", collection->name ()));
69 deadlock:
70 if (collection->release () == -1)
72 ACE_ERROR ((LM_ERROR, "(%t) %p release failed\n","run_thread"));
73 return (void *) -1;
76 ACE_DEBUG ((LM_DEBUG, "(%t) %s released.\n", collection->name ()));
79 ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n"));
80 return 0;
83 static int
84 parse_args (int argc, ACE_TCHAR *argv[])
86 ACE_LOG_MSG->open (argv[0], ACE_Log_Msg::STDERR); // | ACE_Log_Msg::VERBOSE);
88 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT("un:dp:h:"), 1);
90 for (int c; (c = get_opt ()) != -1; )
92 switch (c)
94 case 'h': // specify the host machine on which the server is running
95 server_host = get_opt.opt_arg ();
96 remote = 1;
97 break;
98 case 'p': // specify the port on which the server is running
99 server_port = ACE_OS::atoi (get_opt.opt_arg ());
100 remote = 1;
101 break;
102 case 'd':
103 debug = 1;
104 break;
105 case 'n':
106 iterations = ACE_OS::atoi (get_opt.opt_arg ());
107 break;
108 case 'u':
109 // usage: fallthrough
110 default:
111 ACE_ERROR_RETURN ((LM_ERROR,
112 "%n:\n"
113 "[-h <remote host>]\n"
114 "[-p <remote port>]\n"
115 "[-n <iterations>]\n"
116 "[-d debug]\n", 1), -1);
117 /* NOTREACHED */
121 return 0;
125 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
127 if (parse_args (argc, argv) == -1)
128 return -1;
130 ACE_Token_Proxy *A; // Mutex *A*.
131 ACE_Token_Proxy *B; // Mutex *B*.
132 ACE_Token_Proxy *R; // *R*eader Lock.
133 ACE_Token_Proxy *W; // *W*riter Lock.
135 // Depending on the command line arguments, we will create local or
136 // remote tokens. The names of the tokens are not important as long
137 // as they are unique.
138 if (remote)
140 ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host));
141 A = new ACE_Remote_Mutex ("R Mutex A", 0, debug);
142 B = new ACE_Remote_Mutex ("R Mutex B", 0, debug);
143 R = new ACE_Remote_RLock ("R Reader Lock", 0, debug);
144 W = new ACE_Remote_WLock ("R Writer Lock", 0, debug);
146 else
148 A = new ACE_Local_Mutex ("L Mutex A", 0, debug);
149 B = new ACE_Local_Mutex ("L Mutex B", 0, debug);
150 R = new ACE_Local_RLock ("L Reader Lock", 0, debug);
151 W = new ACE_Local_WLock ("L Writer Lock", 0, debug);
154 // These collections will be treated as Tokens by the threads.
155 ACE_Token_Collection collectionAR (debug, "A and Reader");
156 ACE_Token_Collection collectionAW (debug, "A and Writer");
157 ACE_Token_Collection collectionBR (debug, "B and Reader");
159 // AR and BR can run concurrently. Neither AR or BR can run when AW
160 // is running.
161 collectionAR.insert (*A);
162 collectionAR.insert (*R);
164 collectionAW.insert (*A);
165 collectionAW.insert (*W);
167 collectionBR.insert (*B);
168 collectionBR.insert (*R);
170 // Spawn off three threads.
171 ACE_Thread_Manager *mgr = ACE_Thread_Manager::instance ();
173 if (mgr->spawn (ACE_THR_FUNC (run_thread),
174 (void *) &collectionAR, THR_BOUND | THR_SUSPENDED) == -1)
175 ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn 1 failed"), -1);
177 if (mgr->spawn (ACE_THR_FUNC (run_thread),
178 (void *) &collectionAW, THR_BOUND | THR_SUSPENDED) == -1)
179 ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn 2 failed"), -1);
181 if (mgr->spawn (ACE_THR_FUNC (run_thread),
182 (void *) &collectionBR, THR_BOUND | THR_SUSPENDED) == -1)
183 ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn 3 failed"), -1);
185 #if ! defined (ACE_HAS_PTHREADS)
186 if (mgr->resume_all () == -1)
187 ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "resume failed"), -1);
188 #endif
190 // Wait for all threads to exit.
191 mgr->wait ();
193 return 0;
196 #else
198 ACE_TMAIN(int, ACE_TCHAR *[])
200 ACE_ERROR_RETURN ((LM_ERROR,
201 "threads not supported on this platform\n"), -1);
203 #endif /* ACE_HAS_THREADS && ACE_HAS_TOKENS_LIBRARY */