test_aiosig.cpp

来自「ace开发环境 用来开发网络程序 其运用了设计模式、多平台、C++等多种知识」· C++ 代码 · 共 296 行

CPP
296
字号
// $Id: test_aiosig.cpp 78962 2007-07-20 03:27:14Z sowayaa $// ============================================================================//// = FILENAME//     test_aiosig.cpp//// = DESCRITPTION//     Check out test_aiosig_ace.cpp, the ACE'ified version of this//     program. This program may not be uptodate.//// = COMPILATION//     CC -g -o test_aiosig -lrt test_aiosig.cpp//// = RUN//     ./test_aiosig//// = AUTHOR//     Programming for the Real World. Bill O. GallMeister.//     Modified by Alexander Babu Arulanthu <alex@cs.wustl.edu>//// =====================================================================//FUZZ: disable check_for_lack_ACE_OS#include <unistd.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <signal.h>#include <string.h>#include <errno.h>#include <stdio.h>#include <limits.h>#include <pthread.h>#include <aio.h>int file_handle = -1;char mb1 [BUFSIZ + 1];char mb2 [BUFSIZ + 1];aiocb aiocb1, aiocb2;sigset_t completion_signal;// Function prototypes.int setup_signal_delivery (void);int issue_aio_calls (void);int query_aio_completions (void);int test_aio_calls (void);int setup_signal_handler (void);int setup_signal_handler (int signal_number);intsetup_signal_delivery (void){  // Make the sigset_t consisting of the completion signal.  if (sigemptyset (&completion_signal) == -1)    {      perror ("Error:Couldnt init the RT completion signal set\n");      return -1;    }  if (sigaddset (&completion_signal, SIGRTMIN) == -1)    {      perror ("Error:Couldnt init the RT completion signal set\n");      return -1;    }  // Mask them.  if (pthread_sigmask (SIG_BLOCK, &completion_signal, 0) == -1)    {      perror ("Error:Couldnt maks the RT completion signals\n");      return -1;    }  return setup_signal_handler (SIGRTMIN);}intissue_aio_calls (void){  // Setup AIOCB.  aiocb1.aio_fildes = file_handle;  aiocb1.aio_offset = 0;  aiocb1.aio_buf = mb1;  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.      perror ("Error:Asynch_Read_Stream: aio_read queueing failed\n");      return -1;    }  // Setup AIOCB.  aiocb2.aio_fildes = file_handle;  aiocb2.aio_offset = BUFSIZ + 1;  aiocb2.aio_buf = mb2;  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.      perror ("Error:Asynch_Read_Stream: aio_read queueing failed\n");      return -1;    }  return 0;}intquery_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 = INT_MAX;      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)        {          perror ("Error:Error waiting for RT completion signals\n");          return -1;        }      // RT completion signals returned.      if (sig_return != SIGRTMIN)        {          printf ("Unexpected signal (%d) has been received while waiting for RT Completion Signals\n",                  sig_return);          return -1;        }      // @@ Debugging.      printf ("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)        {          printf ("Inconsistent signal number (%d) in the signal info block\n",                  sig_info.si_signo);          return -1;        }      // @@ Debugging.      printf ("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))        {          printf ("Unexpected signal code (%d) returned on completion querying\n",                  sig_info.si_code);          return -1;        }      // 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)        {          perror ("Error:Invalid control block was sent to <aio_error> for compleion querying\n");          return -1;        }      if (error_code != 0)        {          // Error occurred in the <aio_>call. Return the errno          // corresponding to that <aio_> call.          printf ("Error:An AIO call has failed:Error code = %d\n",                  error_code);          return -1;        }      // No error occured in the AIO operation.      int nbytes = aio_return (aiocb_ptr);      if (nbytes == -1)        {          perror ("Error:Invalid control block was send to <aio_return>\n");          return -1;        }      if (number_of_compleions == 0)        // Print the buffer.        printf ("Number of bytes transferred : %d\n The buffer : %s \n",                nbytes,                mb1);      else        // Print the buffer.        printf ("Number of bytes transferred : %d\n The buffer : %s \n",                nbytes,                mb2);    }  return 0;}inttest_aio_calls (void){  // Set up the input file.  // Open file (in SEQUENTIAL_SCAN mode)  file_handle = open ("test_aiosig.cpp", O_RDONLY);  if (file_handle == -1)    {      perror ("Error:Opening the inputfile");      return -1;    }  if (setup_signal_delivery () < 0)    return -1;  if (issue_aio_calls () < 0)    return -1;  if (query_aio_completions () < 0)    return -1;  return 0;}voidnull_handler (int         /* signal_number */,              siginfo_t * /* info */,              void *      /* context */){}intsetup_signal_handler (int signal_number){   // 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 = null_handler;     // Null handler.  int sigaction_return = sigaction (SIGRTMIN,                                    &reaction,                                    0);  if (sigaction_return == -1)    {      perror ("Error:Proactor couldnt do sigaction for the RT SIGNAL");      return -1;    }  return 0;}intmain (int, char *[]){  if (test_aio_calls () == 0)    printf ("RT SIG test successful:\n"            "ACE_POSIX_SIG_PROACTOR should work in this platform\n");  else    printf ("RT SIG test failed:\n"            "ACE_POSIX_SIG_PROACTOR may not work in this platform\n");  return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?