(root)/
glibc-2.38/
sysdeps/
nptl/
aio_misc.h
       1  /* Copyright (C) 2006-2023 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, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  /* We define a special synchronization primitive for AIO.  POSIX
      19     conditional variables would be ideal but the pthread_cond_*wait
      20     operations do not return on EINTR.  This is a requirement for
      21     correct aio_suspend and lio_listio implementations.  */
      22  
      23  #include <assert.h>
      24  #include <pthreadP.h>
      25  #include <futex-internal.h>
      26  
      27  #define DONT_NEED_AIO_MISC_COND	1
      28  
      29  #define AIO_MISC_NOTIFY(waitlist) \
      30    do {									      \
      31      if (*waitlist->counterp > 0 && --*waitlist->counterp == 0)		      \
      32        futex_wake ((unsigned int *) waitlist->counterp, 1, FUTEX_PRIVATE);     \
      33    } while (0)
      34  
      35  #define AIO_MISC_WAIT(result, futex, timeout, cancel)			      \
      36    do {									      \
      37      volatile unsigned int *futexaddr = &futex;				      \
      38      unsigned int oldval = futex;					      \
      39  									      \
      40      if (oldval != 0)							      \
      41        {									      \
      42  	__pthread_mutex_unlock (&__aio_requests_mutex);			      \
      43  									      \
      44  	int status;							      \
      45  	do								      \
      46  	  {								      \
      47  	    if (cancel)							      \
      48  	      status = __futex_abstimed_wait_cancelable64 (		      \
      49  		(unsigned int *) futexaddr, oldval, CLOCK_MONOTONIC, timeout, \
      50  		FUTEX_PRIVATE);						      \
      51  	    else							      \
      52  	      status = __futex_abstimed_wait64 ((unsigned int *) futexaddr,   \
      53  		oldval, CLOCK_REALTIME, timeout, FUTEX_PRIVATE); 	      \
      54  	    if (status != EAGAIN)					      \
      55  	      break;							      \
      56  									      \
      57  	    oldval = *futexaddr;					      \
      58  	  }								      \
      59  	while (oldval != 0);						      \
      60  									      \
      61  	if (status == EINTR)						      \
      62  	  result = EINTR;						      \
      63  	else if (status == ETIMEDOUT)					      \
      64  	  result = EAGAIN;						      \
      65  	else if (status == EOVERFLOW)					      \
      66  	  result = EOVERFLOW;						      \
      67  	else								      \
      68  	  assert (status == 0 || status == EAGAIN);			      \
      69  									      \
      70  	__pthread_mutex_lock (&__aio_requests_mutex);			      \
      71        }									      \
      72    } while (0)
      73  
      74  #include_next <aio_misc.h>