1 //=============================================================================
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
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
20 #include <sys/types.h>
33 char mb1
[BUFSIZ
+ 1];
34 char mb2
[BUFSIZ
+ 1];
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
);
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");
56 if (sigaddset (&completion_signal
, SIGRTMIN
) == -1)
58 perror ("Error:Couldnt init the RT completion signal set\n");
63 if (pthread_sigmask (SIG_BLOCK
, &completion_signal
, 0) == -1)
65 perror ("Error:Couldnt maks the RT completion signals\n");
69 return setup_signal_handler (SIGRTMIN
);
76 aiocb1
.aio_fildes
= file_handle
;
77 aiocb1
.aio_offset
= 0;
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)
89 perror ("Error:Asynch_Read_Stream: aio_read queueing failed\n");
94 aiocb2
.aio_fildes
= file_handle
;
95 aiocb2
.aio_offset
= BUFSIZ
+ 1;
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)
107 perror ("Error:Asynch_Read_Stream: aio_read queueing failed\n");
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.
124 timeout
.tv_sec
= INT_MAX
;
127 // To get back the signal info.
130 // Await the RT completion signal.
131 int sig_return
= sigtimedwait (&completion_signal
,
136 // If failure is coz of timeout, then return *0* but set
137 // errno appropriately. This is what the WinNT proactor
139 if (sig_return
== -1)
141 perror ("Error:Error waiting for RT completion signals\n");
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",
154 printf ("Sig number found in the sig_info block : %d\n",
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",
166 printf ("Signal code for this signal delivery : %d\n",
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",
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");
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",
200 // No error occurred in the AIO operation.
201 int nbytes
= aio_return (aiocb_ptr
);
204 perror ("Error:Invalid control block was send to <aio_return>\n");
208 if (number_of_compleions
== 0)
210 printf ("Number of bytes transferred : %d\n The buffer : %s\n",
215 printf ("Number of bytes transferred : %d\n The buffer : %s\n",
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");
235 if (setup_signal_delivery () < 0)
238 if (issue_aio_calls () < 0)
241 if (query_aio_completions () < 0)
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
,
269 if (sigaction_return
== -1)
271 perror ("Error:Proactor couldnt do sigaction for the RT SIGNAL");
281 if (test_aio_calls () == 0)
282 printf ("RT SIG test successful:\n"
283 "ACE_POSIX_SIG_PROACTOR should work in this platform\n");
285 printf ("RT SIG test failed:\n"
286 "ACE_POSIX_SIG_PROACTOR may not work in this platform\n");