Compile fixes
[ACE_TAO.git] / ACE / tests / TkReactor_Test.cpp
blobba05bc3738ec82cb0c9cda599d70dfd895851c17
1 //=============================================================================
2 /**
3 * @file TkReactor_Test.cpp
5 * This is a simple test that illustrates the possibility to integrate
6 * ACE to the Tk Main Loop. This program uses ACE_TkReactor class to
7 * schedule three additional event sources:
8 * 1. Events from button "Stop Test" (registed with Tk_CreateEventHandler)
9 * 2. Events from button "Press Me" (registed with Tk_CreateEventHandler)
10 * 3. Events from X timer (registed with Tk_CreateTimerHandler)
11 * 4. Events from ACE timer (registed with ACE_TkReactor::schedule_timer)
12 * 5. Events from the TCP/IP channel using ACE_Acceptor
13 * No command line arguments are needed to run the test.
15 * @author Nagarajan Surendran <naga@cs.wustl.edu>
17 //=============================================================================
19 #include "test_config.h"
21 #include "ace/Event_Handler.h"
22 #include "ace/Acceptor.h"
23 #include "ace/SOCK_Acceptor.h"
24 #include "ace/SOCK_Connector.h"
25 #include "ace/Service_Config.h"
26 #include "ace/Thread_Manager.h"
27 #include "ace/TkReactor/TkReactor.h"
28 #include "ace/OS_NS_unistd.h"
30 #include <tcl.h>
31 #include <tk.h>
33 Tcl_Interp* tcl_interp;
34 void eval (const char *s)
36 char buf[BUFSIZ];
37 ACE_OS::strcpy (buf,s);
38 int st = Tcl_GlobalEval(tcl_interp,buf);
39 if (st != TCL_OK)
41 int n = ACE_OS::strlen(s);
42 char *wrk = new char[n + 80];
43 ACE_OS::snprintf (wrk, n + 80, "tkerror \"%s\"", s);
44 Tcl_GlobalEval(tcl_interp, wrk);
45 delete [] wrk;
49 // Port we listen on.
50 static const u_short SERV_TCP_PORT = 6670;
52 // counter for events from "Press Me" button.
53 static int count1 = 0;
55 // counter for events from Tk Timer.
56 static int count2 = 0;
58 // counter for events from ACE Timer.
59 static int count3 = 0;
61 static int quit = 0;
62 // Callback for "Stop Test" buton - quit the program.
63 void
64 Quit (ClientData, XEvent *)
66 ACE_DEBUG ((LM_DEBUG,"Quit called\n"));
67 quit = 1;
70 static void *
71 client (void *)
73 char buf[100];
74 size_t mes_len;
75 ACE_OS::sleep (1);
77 ACE_DEBUG ((LM_DEBUG,
78 " (%P) Client: Starting...\n"));
80 ACE_SOCK_Stream stream;
81 ACE_SOCK_Connector connector;
82 ACE_OS::snprintf (buf, 100, "Client: the life was good!");
84 mes_len = (int) htonl (ACE_OS::strlen (buf) + 1);
86 if (connector.connect (stream,
87 ACE_INET_Addr (SERV_TCP_PORT,
88 ACE_DEFAULT_SERVER_HOST)) == -1)
89 ACE_ERROR ((LM_ERROR,
90 "(%P) %p\n",
91 "Socket open"));
93 if (stream.send (4,
94 (void *) &mes_len,
95 sizeof (size_t),
96 (void *)buf,
97 ACE_OS::strlen (buf) + 1) == -1)
99 ACE_ERROR ((LM_ERROR,
100 "(%P) %p\n",
101 "Socket send"));
103 if (stream.close () == -1)
104 ACE_ERROR ((LM_ERROR,
105 "(%P) %p\n",
106 "Socket close"));
108 ACE_DEBUG ((LM_DEBUG,
109 "(%P) Client: Message has been sent, about to exit...\n"));
110 return 0;
113 // Callback for "Press Me" button.
115 static int
116 #if TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION > 3
117 inc_count (ClientData client_data, Tcl_Interp *interp,int, const char **)
118 #else
119 inc_count (ClientData client_data, Tcl_Interp *interp,int, char **)
120 #endif
122 ACE_DEBUG ((LM_DEBUG,"inc_count "));
123 char new_string[80];
125 ACE_OS::snprintf (new_string, 80, "Events: [%d] [%d] [%d]",
126 count1++, count2, count3);
128 // sprintf (command,"set %s %s",(char *)client_data,new_string);
129 // eval (command);
130 const char *varValue = Tcl_SetVar (interp,(char *)client_data,new_string,TCL_LEAVE_ERR_MSG);
131 if (varValue == 0)
132 return TCL_ERROR;
133 return TCL_OK;
136 // Callback for X Timer.
138 static void
139 inc_tmo (ClientData client_data)
141 char new_string[80];
143 if (count2 > 10)
144 ACE_OS::exit (0);
145 ACE_OS::snprintf (new_string, 80, "Events: [%d] [%d] [%d]",
146 count1, count2++, count3);
148 // sprintf (command,"set %s %s",(char *)client_data,new_string);
149 // eval (command);
150 const char *varValue = Tcl_SetVar (tcl_interp,(char *)client_data,new_string,TCL_LEAVE_ERR_MSG);
151 if (varValue == 0)
152 ACE_ERROR ((LM_ERROR,"Tcl_SetVar failed in inc_tmo\n"));
154 (void) Tk_CreateTimerHandler (1000,
155 inc_tmo,
156 client_data);
159 class EV_handler : public ACE_Event_Handler
161 public:
162 virtual int handle_timeout (const ACE_Time_Value &,
163 const void *arg)
165 char new_string[80];
166 ACE_OS::snprintf (new_string, 80, "Events: [%d] [%d] [%d]",
167 count1, count2, count3++);
169 // sprintf (command,"set %s %s",(char *)arg,new_string);
170 // eval (command);
171 const char *varValue = Tcl_SetVar (tcl_interp,(char *)arg,new_string,TCL_LEAVE_ERR_MSG);
172 if (varValue == 0)
173 ACE_ERROR_RETURN ((LM_ERROR,"Tcl_SetVar failed in handle_timeout\n"),-1);
175 return 0;
179 class Connection_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
181 public:
182 //FUZZ: disable check_for_lack_ACE_OS
183 virtual int open (void *)
185 //FUZZ: enable check_for_lack_ACE_OS
186 char buf[100];
187 int head;
188 ssize_t ret = this->peer ().recv_n ((char *) &head,
189 sizeof (int));
190 if (ret != sizeof (int))
191 ACE_ERROR_RETURN ((LM_ERROR,
192 "(%P) %p\n",
193 "read header"),
194 -1);
196 ret = this->peer ().recv_n (buf,
197 (int) ntohl (head));
199 if (ret != (int) ntohl (head))
200 ACE_ERROR_RETURN ((LM_ERROR,
201 "(%P) %p\n",
202 "read message"),
203 -1);
204 ACE_DEBUG ((LM_DEBUG,
205 " (%P)Server (ACE_SOCKET channel message): [%s]\n",
206 buf));
207 return 0;
212 init (Tcl_Interp *interp)
214 if (Tcl_Init (interp) == TCL_ERROR)
215 return TCL_ERROR;
216 if (Tk_Init (interp) == TCL_ERROR)
217 return TCL_ERROR;
218 return TCL_OK;
222 run_main (int, ACE_TCHAR *[])
224 ACE_START_TEST (ACE_TEXT ("TkReactor_Test"));
226 tcl_interp = Tcl_CreateInterp ();
228 if (init (tcl_interp) != TCL_OK) {
229 ACE_OS::exit (1);
232 Tk_Window tk = 0;
233 tk = Tk_MainWindow(tcl_interp);
234 if (tk == 0)
236 ACE_ERROR_RETURN ((LM_ERROR, "Tk_Reactor_Test: Tk_MainWindow() failed\n"),1);
239 char tcl_cmd[] = "source TkReactor_Test.tcl";
240 if (Tcl_Eval (tcl_interp, tcl_cmd) != TCL_OK) {
241 ACE_OS::exit (1);
243 // set up callback
244 char label_var_name[] = "label_var";
245 char pressme[] = "pressme";
246 Tcl_CreateCommand (tcl_interp,
247 pressme,
248 inc_count,
249 label_var_name,
252 // Register callback for X Timer
253 (void) Tk_CreateTimerHandler (1000,
254 inc_tmo,
255 label_var_name);
257 // It will perform Tk Main Loop
258 ACE_TkReactor reactor;
259 ACE_Reactor r (&reactor);
261 //Event Handler for ACE Timer.
262 EV_handler evh;
264 ACE_Acceptor <Connection_Handler, ACE_SOCK_ACCEPTOR> acceptor;
266 if (acceptor.open (ACE_INET_Addr ((u_short) SERV_TCP_PORT),
267 &r) == -1)
268 ACE_ERROR_RETURN ((LM_ERROR,
269 "%p\n",
270 "open"),
271 -1);
273 if (reactor.schedule_timer (&evh,
274 (const void *) "label_var",
275 ACE_Time_Value (2),
276 ACE_Time_Value (2))==-1)
277 ACE_ERROR_RETURN ((LM_ERROR,
278 " (%P|%t) can't register with reactor\n"),
279 -1);
281 ACE_Thread_Manager::instance ()->spawn ((ACE_THR_FUNC) client,
283 THR_NEW_LWP | THR_DETACHED);
285 while (!quit)
287 int result = reactor.handle_events ();
288 switch (result)
290 case 0:
291 // ACE_DEBUG ((LM_DEBUG,"handle_events timed out\n"));
292 break;
293 case -1:
294 ACE_DEBUG ((LM_DEBUG,"handle_events returned -1\n"));
295 quit = 1;
296 break;
300 ACE_END_TEST;
301 return 0;