/ltp-full-20110228/testcases/open_posix_testsuite/conformance/interfaces/aio_suspend/8-1.c

https://github.com/barajas/Intel-GLTP · C · 237 lines · 155 code · 44 blank · 38 comment · 31 complexity · 271bfa09844eaf575e84862c586be1a7 MD5 · raw file

  1. /*
  2. * Copyright (c) 2004, Bull SA. All rights reserved.
  3. * Created by: Laurent.Vivier@bull.net
  4. * This file is licensed under the GPL license. For the full content
  5. * of this license, see the COPYING file at the top level of this
  6. * source tree.
  7. */
  8. /*
  9. * assertion:
  10. *
  11. * The aio_suspend() function shall suspend the calling thread until at
  12. * least one of the asynchronous I/O operations referenced by the list
  13. * argument has completed, until a signal interrupts the function, or,
  14. * if timeout is not NULL, until the time interval specified by timeout
  15. * has passed.
  16. *
  17. * method: Testing for a NULL timeout
  18. *
  19. * - write to a file
  20. * - submit a list of read requests
  21. * - check that the selected request has not completed
  22. * - suspend on selected request
  23. * - check that the selected request has completed using aio_error and
  24. * aio_return
  25. *
  26. */
  27. #define _XOPEN_SOURCE 600
  28. #include <sys/stat.h>
  29. #include <aio.h>
  30. #include <errno.h>
  31. #include <fcntl.h>
  32. #include <signal.h>
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include <unistd.h>
  37. #include "posixtest.h"
  38. #define TNAME "aio_suspend/8-1.c"
  39. #define NUM_AIOCBS 10
  40. #define BUF_SIZE 1024*1024
  41. #define WAIT_FOR_AIOCB 6
  42. int received_selected = 0;
  43. int received_all = 0;
  44. void
  45. sigrt1_handler(int signum, siginfo_t *info, void *context)
  46. {
  47. if (info->si_value.sival_int == WAIT_FOR_AIOCB)
  48. received_selected = 1;
  49. }
  50. void
  51. sigrt2_handler(int signum, siginfo_t *info, void *context)
  52. {
  53. received_all = 1;
  54. }
  55. int
  56. main ()
  57. {
  58. char tmpfname[256];
  59. int fd;
  60. struct aiocb **aiocbs;
  61. struct aiocb *plist[2];
  62. char *bufs;
  63. struct sigaction action;
  64. struct sigevent event;
  65. int errors = 0;
  66. int ret;
  67. int err;
  68. int i;
  69. if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L)
  70. return PTS_UNSUPPORTED;
  71. snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_suspend_8_1_%d",
  72. getpid());
  73. unlink(tmpfname);
  74. fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
  75. if (fd == -1) {
  76. printf(TNAME " Error at open(): %s\n",
  77. strerror(errno));
  78. exit(PTS_UNRESOLVED);
  79. }
  80. unlink(tmpfname);
  81. bufs = (char *) malloc (NUM_AIOCBS*BUF_SIZE);
  82. if (bufs == NULL) {
  83. printf (TNAME " Error at malloc(): %s\n", strerror (errno));
  84. close (fd);
  85. exit(PTS_UNRESOLVED);
  86. }
  87. if (write (fd, bufs, NUM_AIOCBS*BUF_SIZE) != (NUM_AIOCBS*BUF_SIZE)) {
  88. printf(TNAME " Error at write(): %s\n", strerror(errno));
  89. free (bufs);
  90. close (fd);
  91. exit(PTS_UNRESOLVED);
  92. }
  93. aiocbs = (struct aiocb**)malloc(sizeof(struct aiocb *) * NUM_AIOCBS);
  94. /* Queue up a bunch of aio reads */
  95. for (i = 0; i < NUM_AIOCBS; i++) {
  96. aiocbs[i] = (struct aiocb*)malloc(sizeof(struct aiocb));
  97. memset(aiocbs[i], 0, sizeof(struct aiocb));
  98. aiocbs[i]->aio_fildes = fd;
  99. aiocbs[i]->aio_offset = i * BUF_SIZE;
  100. aiocbs[i]->aio_buf = &bufs[i*BUF_SIZE];
  101. aiocbs[i]->aio_nbytes = BUF_SIZE;
  102. aiocbs[i]->aio_lio_opcode = LIO_READ;
  103. /* Use SIRTMIN+1 for individual completions */
  104. aiocbs[i]->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
  105. aiocbs[i]->aio_sigevent.sigev_signo = SIGRTMIN+1;
  106. aiocbs[i]->aio_sigevent.sigev_value.sival_int = i;
  107. }
  108. /* Use SIGRTMIN+2 for list completion */
  109. event.sigev_notify = SIGEV_SIGNAL;
  110. event.sigev_signo = SIGRTMIN+2;
  111. event.sigev_value.sival_ptr = NULL;
  112. /* Setup handler for individual operation completion */
  113. action.sa_sigaction = sigrt1_handler;
  114. sigemptyset(&action.sa_mask);
  115. action.sa_flags = SA_SIGINFO|SA_RESTART;
  116. sigaction(SIGRTMIN+1, &action, NULL);
  117. /* Setup handler for list completion */
  118. action.sa_sigaction = sigrt2_handler;
  119. sigemptyset(&action.sa_mask);
  120. action.sa_flags = SA_SIGINFO|SA_RESTART;
  121. sigaction(SIGRTMIN+2, &action, NULL);
  122. /* Setup suspend list */
  123. plist[0] = NULL;
  124. plist[1] = aiocbs[WAIT_FOR_AIOCB];
  125. /* Submit request list */
  126. ret = lio_listio(LIO_NOWAIT, aiocbs, NUM_AIOCBS, &event);
  127. if (ret) {
  128. printf(TNAME " Error at lio_listio() %d: %s\n", errno, strerror(errno));
  129. for (i=0; i<NUM_AIOCBS; i++)
  130. free (aiocbs[i]);
  131. free (bufs);
  132. free (aiocbs);
  133. close (fd);
  134. exit (PTS_UNRESOLVED);
  135. }
  136. /* Check selected request has not completed yet */
  137. if (received_selected) {
  138. printf (TNAME " Error : AIOCB %d already completed before suspend\n",
  139. WAIT_FOR_AIOCB);
  140. for (i=0; i<NUM_AIOCBS; i++)
  141. free (aiocbs[i]);
  142. free (bufs);
  143. free (aiocbs);
  144. close (fd);
  145. exit (PTS_FAIL);
  146. }
  147. /* Suspend on selected request */
  148. ret = aio_suspend((const struct aiocb **)plist, 2, NULL);
  149. if (ret) {
  150. printf (TNAME " Error at aio_suspend() %d: %s\n", errno, strerror (errno));
  151. for (i=0; i<NUM_AIOCBS; i++)
  152. free (aiocbs[i]);
  153. free (bufs);
  154. free (aiocbs);
  155. close (fd);
  156. exit (PTS_FAIL);
  157. }
  158. /* Check selected request has completed */
  159. err = aio_error (aiocbs[WAIT_FOR_AIOCB]);
  160. ret = aio_return (aiocbs[WAIT_FOR_AIOCB]);
  161. if ((err != 0) && (ret != BUF_SIZE)) {
  162. printf (TNAME " Error : AIOCB %d should have completed after suspend\n",
  163. WAIT_FOR_AIOCB);
  164. for (i=0; i<NUM_AIOCBS; i++)
  165. free (aiocbs[i]);
  166. free (bufs);
  167. free (aiocbs);
  168. close (fd);
  169. exit (PTS_FAIL);
  170. }
  171. /* Wait for list processing completion */
  172. while (!received_all)
  173. sleep (1);
  174. /* Check return code and free things */
  175. for (i = 0; i < NUM_AIOCBS; i++) {
  176. if (i == WAIT_FOR_AIOCB)
  177. continue;
  178. err = aio_error(aiocbs[i]);
  179. ret = aio_return(aiocbs[i]);
  180. if ((err != 0) && (ret != BUF_SIZE)) {
  181. printf(TNAME " req %d: error = %d - return = %d\n", i, err, ret);
  182. errors++;
  183. }
  184. free (aiocbs[i]);
  185. }
  186. free (bufs);
  187. free (aiocbs);
  188. close(fd);
  189. if (errors != 0)
  190. exit (PTS_FAIL);
  191. printf (TNAME " PASSED\n");
  192. return PTS_PASS;
  193. }