aio_suspend.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /****************************************************************************
  2. * libs/libc/aio/aio_suspend.c
  3. *
  4. * Copyright (C) 2014 Gregory Nutt. All rights reserved.
  5. * Author: Gregory Nutt <gnutt@nuttx.org>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <nuttx/config.h>
  39. #include <sched.h>
  40. #include <signal.h>
  41. #include <aio.h>
  42. #include <assert.h>
  43. #include <errno.h>
  44. #ifdef CONFIG_FS_AIO
  45. /****************************************************************************
  46. * Public Functions
  47. ****************************************************************************/
  48. /****************************************************************************
  49. * Name: aio_suspend
  50. *
  51. * Description:
  52. * The aio_suspend() function suspends the calling thread until at least
  53. * one of the asynchronous I/O operations referenced by the 'list' argument
  54. * has completed, until a signal interrupts the function, or, if 'timeout'
  55. * is not NULL, until the time interval specified by 'timeout' has passed.
  56. * If any of the aiocb structures in the list correspond to completed
  57. * asynchronous I/O operations (that is, the error status for the
  58. * operation is not equal to EINPROGRESS) at the time of the call, the
  59. * function returns without suspending the calling thread.
  60. *
  61. * Each aiocb structure pointed to must have been used in initiating an
  62. * asynchronous I/O request via aio_read(), aio_write(), or lio_listio().
  63. * This array may contain NULL pointers, which are ignored. If this
  64. * array contains pointers that refer to aiocb structures that have not
  65. * been used in submitting asynchronous I/O, the effect is undefined.
  66. *
  67. * Input Parameters:
  68. * list - An array of pointers to asynchronous I/O control blocks.
  69. * nent - The number of elements in the array.
  70. * aiocbp - A pointer to an array
  71. * timeout - If not NULL, this parameter is pointer to a timespec
  72. * structure that determines a timeout on the operation. If
  73. * the time referred to timeout passes before any of the I/O
  74. * operations referenced by list are completed, then
  75. * aio_suspend() returns with an error.
  76. *
  77. * Returned Value:
  78. * If the aio_suspend() function returns after one or more asynchronous
  79. * I/O operations have completed, the function returns zero. Otherwise,
  80. * the function returns a value of -1 and sets errno to indicate the
  81. * error. The application may determine which asynchronous I/O completed
  82. * by scanning the associated error and return status using aio_error()
  83. * and aio_return(), respectively.
  84. *
  85. * The aio_suspend() function will fail if:
  86. *
  87. * EAGAIN - No asynchronous I/O indicated in the list referenced by
  88. * list completed in the time interval indicated by timeout.
  89. * EINTR - A signal interrupted the aio_suspend() function.
  90. *
  91. ****************************************************************************/
  92. int aio_suspend(FAR const struct aiocb * const list[], int nent,
  93. FAR const struct timespec *timeout)
  94. {
  95. sigset_t set;
  96. int ret;
  97. int i;
  98. DEBUGASSERT(list);
  99. /* Lock the scheduler so that no I/O events can complete on the worker
  100. * thread until we set our wait set up. Pre-emption will, of course, be
  101. * re-enabled while we are waiting for the signal.
  102. */
  103. sched_lock();
  104. /* Check each entry in the list. Break out of the loop if any entry
  105. * has completed.
  106. */
  107. for (i = 0; i < nent; i++)
  108. {
  109. /* Check if the I/O has completed */
  110. if (list[i] && list[i]->aio_result != -EINPROGRESS)
  111. {
  112. /* Yes, return success */
  113. sched_unlock();
  114. return OK;
  115. }
  116. }
  117. /* Then wait for SIGPOLL. On success sigtimedwait() will return the
  118. * signal number that cause the error (SIGPOLL). It will set errno
  119. * appropriately for this function on errors.
  120. *
  121. * NOTE: If completion of the I/O causes other signals to be generated
  122. * first, then this will wake up and return EINTR instead of success.
  123. */
  124. sigemptyset(&set);
  125. sigaddset(&set, SIGPOLL);
  126. ret = sigtimedwait(&set, NULL, timeout);
  127. sched_unlock();
  128. return ret >= 0 ? OK : ERROR;
  129. }
  130. #endif /* CONFIG_FS_AIO */