diff options
Diffstat (limited to 'tests/Aio_Platform_Test.cpp')
-rw-r--r-- | tests/Aio_Platform_Test.cpp | 414 |
1 files changed, 285 insertions, 129 deletions
diff --git a/tests/Aio_Platform_Test.cpp b/tests/Aio_Platform_Test.cpp index ed239e7de61..636b5b68757 100644 --- a/tests/Aio_Platform_Test.cpp +++ b/tests/Aio_Platform_Test.cpp @@ -5,7 +5,9 @@ // aio_platform_test.cpp // // = DESCRITPTION -// Testing the platform for POSIX Asynchronous I/O. +// Testing the platform for POSIX Asynchronous I/O. If +// ACE_HAS_AIO_CALLS is defined, we also test the POSIX <aio_> +// calls with real time signals on. // // = AUTHOR // Programming for the Real World. Bill O. GallMeister. @@ -23,48 +25,42 @@ USELIB("..\ace\aced.lib"); //--------------------------------------------------------------------------- #endif /* defined(__BORLANDC__) && __BORLANDC__ >= 0x0530 */ -// Define old style feature selector. -//#define _POSIX_SOURCE - -// Use 9/93 POSIX.1 .2 and .4 definitions only. -//#define _POSIX_C_SOURCE 199309L - -#if defined _POSIX_ASYNCHRONOUS_IO - -#if defined _POSIX_ASYNC_IO - -#if _POSIX_ASYNC_IO == -1 - -int -have_asynchio (void) -{ - ACE_DEBUG ((LM_DEBUG, - "_POSIX_ASYNC_IO = -1.. Not supported at all\n")); - return 0; -} - -#else /* _POSIX_ASYNC_IO is != -1 */ -// Supported everywhere. +#include "ace/Message_Block.h" + +int do_sysconf (void); +int have_asynchio (void); + +#if defined (ACE_HAS_AIO_CALLS) +static ACE_HANDLE file_handle = ACE_INVALID_HANDLE; +ACE_Message_Block mb1 (BUFSIZ + 1); +ACE_Message_Block mb2 (BUFSIZ + 1); +aiocb aiocb1, aiocb2; +sigset_t completion_signal; + +// For testing the <aio> stuff. +int test_aio_calls (void); +int issue_aio_calls (void); +int query_aio_completions (void); +int setup_signal_delivery (void); +#endif /* ACE_HAS_AIO_CALLS */ + int -have_asynchio (void) +do_sysconf (void) { - ACE_DEBUG ((LM_DEBUG, "_POSIX_ASYNC_IO is != -1..AIO is supported everywhere\n")); - ACE_DEBUG ((LM_DEBUG, "System claims to have POSIX_ASYNCHRONOUS_IO\n")); - ACE_DEBUG ((LM_DEBUG, "_POSIX_AIO_LISTIO_MAX = %d\n", _POSIX_AIO_LISTIO_MAX)); - ACE_DEBUG ((LM_DEBUG, "_POSIX_AIO_MAX = %d\n", _POSIX_AIO_MAX)); - // Call sysconf to find out runtime values. errno = 0; - ACE_ERROR ((LM_ERROR, #if defined (_SC_LISTIO_AIO_MAX) + ACE_ERROR ((LM_ERROR, "Runtime value of LISTIO_AIO_MAX is %d, errno = %d\n", sysconf(_SC_LISTIO_AIO_MAX), + errno)); #else + ACE_ERROR ((LM_ERROR, "Runtime value of AIO_LISTIO_MAX is %d, errno = %d\n", sysconf(_SC_AIO_LISTIO_MAX), -#endif errno)); - +#endif + errno = 0; ACE_ERROR ((LM_ERROR, "Runtime value of AIO_MAX is %d, errno = %d\n", @@ -85,129 +81,289 @@ have_asynchio (void) errno = 0; ACE_ERROR ((LM_ERROR, - "Runtime value of RTSIG_MAX %d\n", - sysconf (_SC_RTSIG_MAX))); - return 1; + "Runtime value of RTSIG_MAX %d, Errno = %d\n", + sysconf (_SC_RTSIG_MAX), + errno)); + + errno = 0; + ACE_ERROR ((LM_ERROR, + "Runtime value of SIGQUEUE_MAX %d, Errno = %d\n", + sysconf (_SC_SIGQUEUE_MAX), + errno)); + return 0; } -#endif /* _POSIX_ASYNC_IO == -1 */ - -#else /* _POSIX_ASYNC_IO_ is not defined */ - +#if defined (ACE_HAS_AIO_CALLS) +int +test_aio_calls (void) +{ + ACE_DEBUG ((LM_DEBUG, "test_aio_calls: Errno : %d\n", errno)); + + // Set up the input file. + // Open file (in SEQUENTIAL_SCAN mode) + file_handle = ACE_OS::open ("Aio_Platform_Test.cpp", O_RDONLY); + + if (file_handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_OS::open"), -1); + + if (setup_signal_delivery () < 0) + return -1; + + if (issue_aio_calls () < 0) + return -1; + + if (query_aio_completions () < 0) + return -1; + + return 0; +} -char * -asynch_io_files[] = +int +setup_signal_delivery (void) { - "/tmp/fu", - "/fu", - "./fu", - "/mnt/fu", - "/dev/tty", - "dev/dsk/c2t0ds0", - NULL -}; + // Make the sigset_t consisting of the completion signal. + if (sigemptyset (&completion_signal) < 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Error:%p:Couldnt init the RT completion signal set\n"), + -1); + + if (sigaddset (&completion_signal, + SIGRTMIN) < 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Error:%p:Couldnt init the RT completion signal set\n"), + -1); + + // Mask them. + if (sigprocmask (SIG_BLOCK, &completion_signal, 0) < 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Error:%p:Couldnt maks the RT completion signals\n"), + -1); + + // Setting up the handler(!) for these signals. + struct sigaction reaction; + sigemptyset (&reaction.sa_mask); // Nothing else to mask. + reaction.sa_flags = SA_SIGINFO; // Realtime flag. +#if defined (SA_SIGACTION) + // Lynx says, it is better to set this bit to be portable. + reaction.sa_flags &= SA_SIGACTION; +#endif /* SA_SIGACTION */ + reaction.sa_sigaction = 0; // No handler. + int sigaction_return = sigaction (SIGRTMIN, + &reaction, + 0); + if (sigaction_return == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "Error:%p:Proactor couldnt do sigaction for the RT SIGNAL"), + -1); + + return 0; +} int -have_asynchio (void) +issue_aio_calls (void) { - int i, res, num_ok; - - ACE_ERROR ((LM_DEBUG, - "_POSIX_ASYNC_IO_ is not defined.\n")); - ACE_DEBUG ((LM_DEBUG, - "AIO might *not* be supported everwhere.\n")); - - ACE_DEBUG ((LM_DEBUG, "System claims to have POSIX_ASYNCHRONOUS_IO\n")); - ACE_DEBUG ((LM_DEBUG, "_POSIX_AIO_LISTIO_MAX = %d\n", _POSIX_AIO_LISTIO_MAX)); - ACE_DEBUG ((LM_DEBUG, "_POSIX_AIO_MAX = %d\n", _POSIX_AIO_MAX)); - - // Call sysconf to find out runtime values. - errno = 0; - ACE_ERROR ((LM_ERROR, - "Runtime value of AIO_LISTIO_MAX is %d, errno = %d\n", - sysconf(_SC_AIO_LISTIO_MAX), - errno)); - - errno = 0; - ACE_ERROR ((LM_ERROR, - "Runtime value of AIO_MAX is %d, errno = %d\n", - sysconf (_SC_AIO_MAX), - errno)); - - errno = 0; - ACE_ERROR ((LM_ERROR, - "Runtime value of _POSIX_ASYNCHRONOUS_IO is %d\n", - sysconf (_SC_ASYNCHRONOUS_IO))); - - errno = 0; - ACE_ERROR ((LM_ERROR, - "Runtime value of _POSIX_REALTIME_SIGNALS is %d\n", - sysconf (_SC_REALTIME_SIGNALS))); - - errno = 0; - ACE_ERROR ((LM_ERROR, - "Runtime value of RTSIG_MAX %d\n", - sysconf (_SC_RTSIG_MAX))); - - ACE_DEBUG ((LM_DEBUG, - "Checking individual files using pathconf \n")); + // Setup AIOCB. + aiocb1.aio_fildes = file_handle; + aiocb1.aio_offset = 0; + aiocb1.aio_buf = mb1.wr_ptr (); + aiocb1.aio_nbytes = BUFSIZ; + aiocb1.aio_reqprio = 0; + aiocb1.aio_sigevent.sigev_notify = SIGEV_SIGNAL; + aiocb1.aio_sigevent.sigev_signo = SIGRTMIN; + aiocb1.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb1; + + // Fire off the aio write. + if (aio_read (&aiocb1) == -1) + // Queueing failed. + ACE_ERROR_RETURN ((LM_ERROR, + "Erro:%p:Asynch_Read_Stream: aio_read queueing failed\n"), + -1); + + // Setup AIOCB. + aiocb2.aio_fildes = file_handle; + aiocb2.aio_offset = BUFSIZ + 1; + aiocb2.aio_buf = mb2.wr_ptr (); + aiocb2.aio_nbytes = BUFSIZ; + aiocb2.aio_reqprio = 0; + aiocb2.aio_sigevent.sigev_notify = SIGEV_SIGNAL; + aiocb2.aio_sigevent.sigev_signo = SIGRTMIN; + aiocb2.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb2; + + // Fire off the aio write. + if (aio_read (&aiocb2) == -1) + // Queueing failed. + ACE_ERROR_RETURN ((LM_ERROR, + "Erro:%p:Asynch_Read_Stream: aio_read queueing failed\n"), + -1); + + return 0; +} - for (i = num_ok = 0; - asynch_io_files[i]; - i++) +int +query_aio_completions (void) +{ + size_t number_of_compleions = 0; + for (number_of_compleions = 0; + number_of_compleions < 2; + number_of_compleions ++) { + // Wait for <milli_seconds> amount of time. + // @@ Assigning <milli_seconds> to tv_sec. + timespec timeout; + timeout.tv_sec = ACE_INFINITE; + timeout.tv_nsec = 0; + + // To get back the signal info. + siginfo_t sig_info; + + // Await the RT completion signal. + int sig_return = sigtimedwait (&completion_signal, + &sig_info, + &timeout); + + // Error case. + // If failure is coz of timeout, then return *0* but set + // errno appropriately. This is what the WinNT proactor + // does. + if (sig_return == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "Error:%p:Error waiting for RT completion signals\n"), + 0); + + // RT completion signals returned. + if (sig_return != SIGRTMIN) + ACE_ERROR_RETURN ((LM_ERROR, + "Unexpected signal (%d) has been received while waiting for RT Completion Signals\n", + sig_return), + -1); + + // @@ Debugging. + ACE_DEBUG ((LM_DEBUG, + "Sig number found in the sig_info block : %d\n", + sig_info.si_signo)); + + // Is the signo returned consistent? + if (sig_info.si_signo != sig_return) + ACE_ERROR_RETURN ((LM_ERROR, + "Inconsistent signal number (%d) in the signal info block\n", + sig_info.si_signo), + -1); + + // @@ Debugging. ACE_DEBUG ((LM_DEBUG, - "Checking on path %s\n", asynch_io_files [i])); - errno = 0; - res = pathconf (asynch_io_files [i], _PC_ASYNC_IO); - if ((res == -1) && (!errno)) - { - ACE_DEBUG ((LM_DEBUG, - "\tAsynch IO is allowed :-)\n")); - num_ok++; - } - else if (res < 0) - { - ACE_ERROR ((LM_ERROR, - "(%p)\n", "Asynch I/O is not allowed >:-<")); - } + "Signal code for this signal delivery : %d\n", + sig_info.si_code)); + + // Is the signal code an aio completion one? + if ((sig_info.si_code != SI_ASYNCIO) && + (sig_info.si_code != SI_QUEUE)) + ACE_ERROR_RETURN ((LM_DEBUG, + "Unexpected signal code (%d) returned on completion querying\n", + sig_info.si_code), + 0); + + // Retrive the aiocb. + aiocb* aiocb_ptr = (aiocb *) sig_info.si_value.sival_ptr; + + // Analyze error and return values. Return values are + // actually <errno>'s associated with the <aio_> call + // corresponding to aiocb_ptr. + int error_code = aio_error (aiocb_ptr); + if (error_code == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p:Invalid control block was sent to <aio_error> for compleion querying\n"), + -1); + + if (error_code != 0) + // Error occurred in the <aio_>call. Return the errno + // corresponding to that <aio_> call. + ACE_ERROR_RETURN ((LM_ERROR, + "%p:An AIO call has failed\n"), + error_code); + + // No error occured in the AIO operation. + int nbytes = aio_return (aiocb_ptr); + if (nbytes == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p:Invalid control block was send to <aio_return>\n"), + -1); + if (number_of_compleions == 0) + // Print the buffer. + ACE_DEBUG ((LM_DEBUG, + "\n Number of bytes transferred : %d\n The buffer : %s \n", + nbytes, + mb1.rd_ptr ())); else - { - ACE_ERROR ((LM_ERROR, - "Asynch. I/O is allowed :-), res = %d, errno = %d\n", - res, - errno)); - num_ok++; - } + // Print the buffer. + ACE_DEBUG ((LM_DEBUG, + "\n Number of bytes transferred : %d\n The buffer : %s \n", + nbytes, + mb2.rd_ptr ())); } - if (num_ok == i) - return 1; - else - return 0; + + return 0; } -#endif /* _POSIX_ASYNC_IO_ */ +#endif /* ACE_HAS_AIO_CALLS */ -#else /* _POSIX_ASYNCHRONOUS_IO is not defined*/ int have_asynchio (void) { +#if defined (_POSIX_ASYNCHRONOUS_IO) + +#if defined (_POSIX_ASYNC_IO) + +#if _POSIX_ASYNC_IO == -1 ACE_DEBUG ((LM_DEBUG, - "_POSIX_ASYNCHRONOUS_IO itself is not defined\n")); + "_POSIX_ASYNC_IO = -1.. ASYNCH IO NOT supported at all\n")); + return -1; +#else /* Not _POSIX_ASYNC_IO == -1 */ + ACE_DEBUG ((LM_DEBUG, + "_POSIX_ASYNC_IO = %d\n ASYNCH IO is supported FULLY\n", + _POSIX_ASYNC_IO)); +#endif /* _POSIX_ASYNC_IO == -1 */ + +#else /* Not defined _POSIX_ASYNC_IO */ + ACE_ERROR ((LM_DEBUG, + "_POSIX_ASYNC_IO is not defined.\n")); + ACE_DEBUG ((LM_DEBUG, + "AIO might *not* be supported on some paths\n")); +#endif /* _POSIX_ASYNC_IO */ + + // System defined POSIX Values. + ACE_DEBUG ((LM_DEBUG, "System claims to have POSIX_ASYNCHRONOUS_IO\n")); + ACE_DEBUG ((LM_DEBUG, "_POSIX_AIO_LISTIO_MAX = %d\n", _POSIX_AIO_LISTIO_MAX)); + ACE_DEBUG ((LM_DEBUG, "_POSIX_AIO_MAX = %d\n", _POSIX_AIO_MAX)); + + // @@ Debugging. + ACE_DEBUG ((LM_DEBUG, "Before do_sysconf : Errno %d\n", errno)); + + // Check and print the run time values. + do_sysconf (); + + ACE_DEBUG ((LM_DEBUG, "After do_sysconf: Errno : %d\n", errno)); + +#if defined (ACE_HAS_AIO_CALLS) + // Test the aio calls. Issue two <aio_read>s. Assing SIGRTMIN as the + // notification signal. Mask these signal from delivery. Receive + // this signal by doing <sigtimedwait>. + test_aio_calls (); +#endif /* ACE_HAS_AIO_CALLS */ + return 0; + +#else /* Not _POSIX_ASYNCHRONOUS_IO */ + ACE_DEBUG ((LM_DEBUG, + "No support._POSIX_ASYNCHRONOUS_IO itself is not defined\n")); + return -1; +#endif /* _POSIX_ASYNCHRONOUS_IO */ } -#endif /* _POSIX_ASYNCHRONOUS_IO */ int main (int, char *[]) { ACE_START_TEST ("Aio_Platform_Test"); - int ret_val = have_asynchio (); - - if (ret_val == 1) - ACE_DEBUG ((LM_DEBUG, "POSIX Asynchronous IO is supported\n")); - else - ACE_DEBUG ((LM_DEBUG, "POSIX Asynchronous IO is not supported\n")); + have_asynchio (); ACE_END_TEST; return 0; |