Merge branch 'master' into jwi-bcc64xsingletonwarning
[ACE_TAO.git] / ACE / examples / Reactor / Proactor / test_aiosig.cpp
blobbea369ad14092dc3956a73ba567e61146300c9e8
1 //=============================================================================
2 /**
3 * @file test_aiosig.cpp
5 * Check out test_aiosig_ace.cpp, the ACE'ified version of this
6 * program. This program may not be uptodate.
7 * CC -g -o test_aiosig -lrt test_aiosig.cpp
8 * ./test_aiosig
10 * @author Programming for the Real World. Bill O. GallMeister. Modified by Alexander Babu Arulanthu <alex@cs.wustl.edu>
12 //=============================================================================
15 //FUZZ: disable check_for_lack_ACE_OS
16 //FUZZ: disable check_for_improper_main_declaration
18 #include <unistd.h>
19 #include <fcntl.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <signal.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <stdio.h>
27 #include <limits.h>
28 #include <pthread.h>
30 #include <aio.h>
32 int file_handle = -1;
33 char mb1 [BUFSIZ + 1];
34 char mb2 [BUFSIZ + 1];
35 aiocb aiocb1, aiocb2;
36 sigset_t completion_signal;
38 // Function prototypes.
39 int setup_signal_delivery ();
40 int issue_aio_calls ();
41 int query_aio_completions ();
42 int test_aio_calls ();
43 int setup_signal_handler ();
44 int setup_signal_handler (int signal_number);
46 int
47 setup_signal_delivery ()
49 // Make the sigset_t consisting of the completion signal.
50 if (sigemptyset (&completion_signal) == -1)
52 perror ("Error:Couldnt init the RT completion signal set\n");
53 return -1;
56 if (sigaddset (&completion_signal, SIGRTMIN) == -1)
58 perror ("Error:Couldnt init the RT completion signal set\n");
59 return -1;
62 // Mask them.
63 if (pthread_sigmask (SIG_BLOCK, &completion_signal, 0) == -1)
65 perror ("Error:Couldnt maks the RT completion signals\n");
66 return -1;
69 return setup_signal_handler (SIGRTMIN);
72 int
73 issue_aio_calls ()
75 // Setup AIOCB.
76 aiocb1.aio_fildes = file_handle;
77 aiocb1.aio_offset = 0;
78 aiocb1.aio_buf = mb1;
79 aiocb1.aio_nbytes = BUFSIZ;
80 aiocb1.aio_reqprio = 0;
81 aiocb1.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
82 aiocb1.aio_sigevent.sigev_signo = SIGRTMIN;
83 aiocb1.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb1;
85 // Fire off the aio write.
86 if (aio_read (&aiocb1) == -1)
88 // Queueing failed.
89 perror ("Error:Asynch_Read_Stream: aio_read queueing failed\n");
90 return -1;
93 // Setup AIOCB.
94 aiocb2.aio_fildes = file_handle;
95 aiocb2.aio_offset = BUFSIZ + 1;
96 aiocb2.aio_buf = mb2;
97 aiocb2.aio_nbytes = BUFSIZ;
98 aiocb2.aio_reqprio = 0;
99 aiocb2.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
100 aiocb2.aio_sigevent.sigev_signo = SIGRTMIN;
101 aiocb2.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb2;
103 // Fire off the aio write.
104 if (aio_read (&aiocb2) == -1)
106 // Queueing failed.
107 perror ("Error:Asynch_Read_Stream: aio_read queueing failed\n");
108 return -1;
110 return 0;
114 query_aio_completions ()
116 size_t number_of_compleions = 0;
117 for (number_of_compleions = 0;
118 number_of_compleions < 2;
119 number_of_compleions ++)
121 // Wait for <milli_seconds> amount of time.
122 // @@ Assigning <milli_seconds> to tv_sec.
123 timespec timeout;
124 timeout.tv_sec = INT_MAX;
125 timeout.tv_nsec = 0;
127 // To get back the signal info.
128 siginfo_t sig_info;
130 // Await the RT completion signal.
131 int sig_return = sigtimedwait (&completion_signal,
132 &sig_info,
133 &timeout);
135 // Error case.
136 // If failure is coz of timeout, then return *0* but set
137 // errno appropriately. This is what the WinNT proactor
138 // does.
139 if (sig_return == -1)
141 perror ("Error:Error waiting for RT completion signals\n");
142 return -1;
145 // RT completion signals returned.
146 if (sig_return != SIGRTMIN)
148 printf ("Unexpected signal (%d) has been received while waiting for RT Completion Signals\n",
149 sig_return);
150 return -1;
153 // @@ Debugging.
154 printf ("Sig number found in the sig_info block : %d\n",
155 sig_info.si_signo);
157 // Is the signo returned consistent?
158 if (sig_info.si_signo != sig_return)
160 printf ("Inconsistent signal number (%d) in the signal info block\n",
161 sig_info.si_signo);
162 return -1;
165 // @@ Debugging.
166 printf ("Signal code for this signal delivery : %d\n",
167 sig_info.si_code);
169 // Is the signal code an aio completion one?
170 if ((sig_info.si_code != SI_ASYNCIO) &&
171 (sig_info.si_code != SI_QUEUE))
173 printf ("Unexpected signal code (%d) returned on completion querying\n",
174 sig_info.si_code);
175 return -1;
178 // Retrive the aiocb.
179 aiocb* aiocb_ptr = (aiocb *) sig_info.si_value.sival_ptr;
181 // Analyze error and return values. Return values are
182 // actually <errno>'s associated with the <aio_> call
183 // corresponding to aiocb_ptr.
184 int error_code = aio_error (aiocb_ptr);
185 if (error_code == -1)
187 perror ("Error:Invalid control block was sent to <aio_error> for compleion querying\n");
188 return -1;
191 if (error_code != 0)
193 // Error occurred in the <aio_>call. Return the errno
194 // corresponding to that <aio_> call.
195 printf ("Error:An AIO call has failed:Error code = %d\n",
196 error_code);
197 return -1;
200 // No error occurred in the AIO operation.
201 int nbytes = aio_return (aiocb_ptr);
202 if (nbytes == -1)
204 perror ("Error:Invalid control block was send to <aio_return>\n");
205 return -1;
208 if (number_of_compleions == 0)
209 // Print the buffer.
210 printf ("Number of bytes transferred : %d\n The buffer : %s\n",
211 nbytes,
212 mb1);
213 else
214 // Print the buffer.
215 printf ("Number of bytes transferred : %d\n The buffer : %s\n",
216 nbytes,
217 mb2);
219 return 0;
223 test_aio_calls ()
225 // Set up the input file.
226 // Open file (in SEQUENTIAL_SCAN mode)
227 file_handle = open ("test_aiosig.cpp", O_RDONLY);
229 if (file_handle == -1)
231 perror ("Error:Opening the inputfile");
232 return -1;
235 if (setup_signal_delivery () < 0)
236 return -1;
238 if (issue_aio_calls () < 0)
239 return -1;
241 if (query_aio_completions () < 0)
242 return -1;
244 return 0;
247 void
248 null_handler (int /* signal_number */,
249 siginfo_t * /* info */,
250 void * /* context */)
255 setup_signal_handler (int signal_number)
257 // Setting up the handler(!) for these signals.
258 struct sigaction reaction;
259 sigemptyset (&reaction.sa_mask); // Nothing else to mask.
260 reaction.sa_flags = SA_SIGINFO; // Realtime flag.
261 #if defined (SA_SIGACTION)
262 // Lynx says, it is better to set this bit to be portable.
263 reaction.sa_flags &= SA_SIGACTION;
264 #endif /* SA_SIGACTION */
265 reaction.sa_sigaction = null_handler; // Null handler.
266 int sigaction_return = sigaction (SIGRTMIN,
267 &reaction,
269 if (sigaction_return == -1)
271 perror ("Error:Proactor couldnt do sigaction for the RT SIGNAL");
272 return -1;
275 return 0;
279 main (int, char *[])
281 if (test_aio_calls () == 0)
282 printf ("RT SIG test successful:\n"
283 "ACE_POSIX_SIG_PROACTOR should work in this platform\n");
284 else
285 printf ("RT SIG test failed:\n"
286 "ACE_POSIX_SIG_PROACTOR may not work in this platform\n");
287 return 0;