Merge branch 'master' into jwi-bcc64xsingletonwarning
[ACE_TAO.git] / ACE / examples / Reactor / Proactor / test_cancel.cpp
blob8dfb8259e16cf378000c88430b834b21db4770b4
2 //=============================================================================
3 /**
4 * @file test_cancel.cpp
6 * This program tests cancelling an Asynchronous Operation in the
7 * Proactor framework.
9 * This tests accepts a connection and issues an Asynchronous Read
10 * Stream. It reads <read_size> (option -s) number of bytes and
11 * when this operation completes, it issues another Asynchronous
12 * Read Stream to <read_size> and immediately calls <cancel> to
13 * cancel the operation and so the program exits closing the
14 * connection.
16 * Works fine on NT. LynxOS has a good <aio_cancel> implementation. It works
17 * fine.
19 * = RUN
20 * ./test_cancel -p <port_number>
21 * Then telnet to this port and send <read_size> bytes and your
22 * connection should get closed down.
24 * @author Irfan Pyarali (irfan@cs.wustl.edu)
26 //=============================================================================
29 #include "ace/OS_main.h"
30 #include "ace/Service_Config.h"
31 #include "ace/Proactor.h"
32 #include "ace/Asynch_IO.h"
33 #include "ace/Asynch_IO_Impl.h"
34 #include "ace/Asynch_Acceptor.h"
35 #include "ace/INET_Addr.h"
36 #include "ace/SOCK_Connector.h"
37 #include "ace/SOCK_Acceptor.h"
38 #include "ace/SOCK_Stream.h"
39 #include "ace/Message_Block.h"
40 #include "ace/Get_Opt.h"
41 #include "ace/Log_Msg.h"
42 #include "ace/OS_NS_sys_socket.h"
45 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
46 // This only works on Win32 platforms and on Unix platforms supporting
47 // POSIX aio calls.
49 #include "test_cancel.h"
51 static u_short port = ACE_DEFAULT_SERVER_PORT;
52 static int done = 0;
53 static int read_size = 2;
56 Receiver::Receiver ()
57 : mb_ (read_size + 1),
58 handle_ (ACE_INVALID_HANDLE)
62 Receiver::~Receiver ()
64 ACE_DEBUG ((LM_DEBUG,
65 "Receiver: Closing down Remote connection:%d\n",
66 this->handle_));
68 ACE_OS::closesocket (this->handle_);
71 void
72 Receiver::open (ACE_HANDLE handle,
73 ACE_Message_Block &)
75 // New connection, initiate stuff
77 ACE_DEBUG ((LM_DEBUG, "%N:%l:Receiver::open called\n"));
79 // Cache the new connection
80 this->handle_ = handle;
82 // Initiate ACE_Asynch_Read_Stream
83 if (this->rs_.open (*this, this->handle_) == -1)
85 ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Asynch_Read_Stream::open"));
86 return;
89 // Try to read <n> bytes from the stream.
91 ACE_DEBUG ((LM_DEBUG,
92 "Receiver::open: Issuing Asynch Read of (%d) bytes from the stream\n",
93 read_size));
95 if (this->rs_.read (this->mb_,
96 read_size) == -1)
97 ACE_ERROR ((LM_ERROR,
98 "%p\n",
99 "Receiver::open: Failed to issue the read"));
102 void
103 Receiver::handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)
105 ACE_DEBUG ((LM_DEBUG, "handle_read_stream called\n"));
107 // Reset pointers
108 result.message_block ().rd_ptr ()[result.bytes_transferred ()] = '\0';
110 ACE_DEBUG ((LM_DEBUG, "********************\n"));
111 ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "bytes_to_read", result.bytes_to_read ()));
112 ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "handle", result.handle ()));
113 ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "bytes_transfered", result.bytes_transferred ()));
114 ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "act", (uintptr_t) result.act ()));
115 ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "success", result.success ()));
116 ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "completion_key", (uintptr_t) result.completion_key ()));
117 ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "error", result.error ()));
118 ACE_DEBUG ((LM_DEBUG, "********************\n"));
119 ACE_DEBUG ((LM_DEBUG, "%s = %s\n", "message_block", result.message_block ().rd_ptr ()));
121 if (result.success () && !result.error ())
123 // Successful read: No error.
125 // Set the pointers back in the message block.
126 result.message_block ().wr_ptr (result.message_block ().rd_ptr ());
128 // Issue another read, but immediately cancel it.
130 // Issue the read.
132 ACE_DEBUG ((LM_DEBUG,
133 "Issuing Asynch Read of (%d) bytes from the stream\n",
134 read_size));
136 if (this->rs_.read (this->mb_,
137 read_size) == -1)
138 ACE_ERROR ((LM_ERROR,
139 "%p\n",
140 "Receiver::handle_read_stream: Failed to issue the read"));
142 // Cancel the read.
144 ACE_DEBUG ((LM_DEBUG,
145 "Cacelling Asynch Read "));
147 int ret_val = this->rs_.cancel ();
148 if (ret_val == -1)
149 ACE_ERROR ((LM_ERROR,
150 "%p\n",
151 "Receiver::handle_read_stream: Failed to cancel the read"));
153 ACE_DEBUG ((LM_DEBUG, "Asynch IO : Cancel : Result = %d\n",
154 ret_val));
156 else
158 done = 1;
160 ACE_DEBUG ((LM_DEBUG, "Receiver completed\n"));
162 // Print the error message if any.
163 if (result.error () != 0)
165 errno = result.error ();
167 ACE_ERROR ((LM_ERROR,
168 "%p\n",
169 "Asynch Read Stream Error: "));
174 static int
175 parse_args (int argc, ACE_TCHAR *argv[])
177 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT("p:s:"));
178 int c;
180 while ((c = get_opt ()) != EOF)
181 switch (c)
183 case 'p':
184 port = ACE_OS::atoi (get_opt.opt_arg ());
185 break;
186 case 's':
187 read_size = ACE_OS::atoi (get_opt.opt_arg ());
188 break;
189 default:
190 ACE_ERROR ((LM_ERROR, "%p.\n",
191 "usage :\n"
192 "-p <port>\n"
193 "-s <read_size>\n"));
194 return -1;
197 return 0;
201 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
203 if (parse_args (argc, argv) == -1)
204 return -1;
206 // Note: acceptor parameterized by the Receiver
207 ACE_Asynch_Acceptor<Receiver> acceptor;
209 // Listening passively.
210 if (acceptor.open (ACE_INET_Addr (port),
211 read_size,
212 1) == -1)
213 ACE_ERROR_RETURN ((LM_ERROR,
214 "ACE:acceptor::open failed\n"),
217 int success = 1;
219 while (success > 0 && !done)
220 // dispatch events
221 success = ACE_Proactor::instance ()->handle_events ();
223 return 0;
226 #else /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */
229 ACE_TMAIN (int, ACE_TCHAR *[])
231 ACE_DEBUG ((LM_DEBUG,
232 "This example does not work on this platform.\n"));
233 return 1;
236 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */