Back to index

glibc  2.9
aio_misc.h
Go to the documentation of this file.
00001 /* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 /* We define a special synchronization primitive for AIO.  POSIX
00020    conditional variables would be ideal but the pthread_cond_*wait
00021    operations do not return on EINTR.  This is a requirement for
00022    correct aio_suspend and lio_listio implementations.  */
00023 
00024 #include <assert.h>
00025 #include <pthreadP.h>
00026 #include <lowlevellock.h>
00027 
00028 #define DONT_NEED_AIO_MISC_COND    1
00029 
00030 #define AIO_MISC_NOTIFY(waitlist) \
00031   do {                                                               \
00032     if (*waitlist->counterp > 0 && --*waitlist->counterp == 0)              \
00033       lll_futex_wake (waitlist->counterp, 1, LLL_PRIVATE);                  \
00034   } while (0)
00035 
00036 #define AIO_MISC_WAIT(result, futex, timeout, cancel)                       \
00037   do {                                                               \
00038     volatile int *futexaddr = &futex;                                       \
00039     int oldval = futex;                                                     \
00040                                                                      \
00041     if (oldval != 0)                                                 \
00042       {                                                                     \
00043        pthread_mutex_unlock (&__aio_requests_mutex);                        \
00044                                                                      \
00045        int oldtype;                                                  \
00046        if (cancel)                                                   \
00047          oldtype = LIBC_CANCEL_ASYNC ();                             \
00048                                                                      \
00049        int status;                                                   \
00050        do                                                            \
00051          {                                                           \
00052            status = lll_futex_timed_wait (futexaddr, oldval, timeout,       \
00053                                       LLL_PRIVATE);                  \
00054            if (status != -EWOULDBLOCK)                                      \
00055              break;                                                  \
00056                                                                      \
00057            oldval = *futexaddr;                                      \
00058          }                                                           \
00059        while (oldval != 0);                                          \
00060                                                                      \
00061        if (cancel)                                                   \
00062          LIBC_CANCEL_RESET (oldtype);                                       \
00063                                                                      \
00064        if (status == -EINTR)                                                \
00065          result = EINTR;                                             \
00066        else if (status == -ETIMEDOUT)                                       \
00067          result = EAGAIN;                                            \
00068        else                                                          \
00069          assert (status == 0 || status == -EWOULDBLOCK);                    \
00070                                                                      \
00071        pthread_mutex_lock (&__aio_requests_mutex);                          \
00072       }                                                                     \
00073   } while (0)
00074 
00075 #include_next <aio_misc.h>