c5a11f45505feed17ea1920855a159a9e78a3731
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / pthread / aio_misc.h
1 /* Copyright (C) 2006 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 /* We define a special synchronization primitive for AIO.  POSIX
20    conditional variables would be ideal but the pthread_cond_*wait
21    operations do not return on EINTR.  This is a requirement for
22    correct aio_suspend and lio_listio implementations.  */
23
24 #include <assert.h>
25 #include <pthreadP.h>
26 #include <lowlevellock.h>
27
28 #define DONT_NEED_AIO_MISC_COND 1
29
30 #define AIO_MISC_NOTIFY(waitlist) \
31   do {                                                                        \
32     if (*waitlist->counterp > 0 && --*waitlist->counterp == 0)                \
33       lll_futex_wake (waitlist->counterp, 1);                                 \
34   } while (0)
35
36 #define AIO_MISC_WAIT(result, futex, timeout, cancel)                         \
37   do {                                                                        \
38     volatile int *futexaddr = &futex;                                         \
39     int oldval = futex;                                                       \
40                                                                               \
41     if (oldval != 0)                                                          \
42       {                                                                       \
43         pthread_mutex_unlock (&__aio_requests_mutex);                         \
44                                                                               \
45         int oldtype;                                                          \
46         if (cancel)                                                           \
47           oldtype = LIBC_CANCEL_ASYNC ();                                     \
48                                                                               \
49         int status;                                                           \
50         do                                                                    \
51           {                                                                   \
52             status = lll_futex_timed_wait (futexaddr, oldval, timeout);       \
53             if (status != -EWOULDBLOCK)                                       \
54               break;                                                          \
55                                                                               \
56             oldval = *futexaddr;                                              \
57           }                                                                   \
58         while (oldval != 0);                                                  \
59                                                                               \
60         if (cancel)                                                           \
61           LIBC_CANCEL_RESET (oldtype);                                        \
62                                                                               \
63         if (status == -EINTR)                                                 \
64           result = EINTR;                                                     \
65         else if (status == -ETIMEDOUT)                                        \
66           result = EAGAIN;                                                    \
67         else                                                                  \
68           assert (status == 0 || status == -EWOULDBLOCK);                     \
69                                                                               \
70         pthread_mutex_lock (&__aio_requests_mutex);                           \
71       }                                                                       \
72   } while (0)
73
74 #include_next <aio_misc.h>