1 /* Private libc-internal interface for mutex locks.
2    Copyright (C) 2015-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public License as
7    published by the Free Software Foundation; either version 2.1 of the
8    License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If
17    not, see <https://www.gnu.org/licenses/>.  */
18 
19 #ifndef _HTL_LIBC_LOCK_H
20 #define _HTL_LIBC_LOCK_H 1
21 
22 #include_next <libc-lock.h>
23 #include <bits/cancelation.h>
24 
25 #undef __libc_cleanup_region_start
26 #undef __libc_cleanup_region_end
27 #undef __libc_cleanup_end
28 #undef __libc_cleanup_push
29 #undef __libc_cleanup_pop
30 
31 #define __libc_cleanup_region_start(DOIT, FCT, ARG) \
32   {									      \
33     struct __pthread_cancelation_handler **__handlers = NULL;		      \
34     struct __pthread_cancelation_handler __handler;			      \
35     int __registered = 0;						      \
36     if (DOIT)								      \
37       {									      \
38 	__handler.__handler = FCT;					      \
39 	__handler.__arg = ARG;						      \
40 	if (__pthread_get_cleanup_stack != NULL)			      \
41 	  {								      \
42 	    __handlers = __pthread_get_cleanup_stack ();		      \
43 	    __handler.__next = *__handlers;				      \
44 	    *__handlers = &__handler;					      \
45 	    __registered = 1;						      \
46 	  }								      \
47       }									      \
48 
49 #define __libc_cleanup_end(DOIT) \
50     if (__registered)							      \
51       *__handlers = __handler.__next;					      \
52     if (DOIT)								      \
53       __handler.__handler (__handler.__arg);				      \
54 
55 #define __libc_cleanup_region_end(DOIT) \
56     __libc_cleanup_end(DOIT)						      \
57   }
58 
59 #define __libc_cleanup_push(fct, arg) __libc_cleanup_region_start (1, fct, arg)
60 #define __libc_cleanup_pop(execute) __libc_cleanup_region_end (execute)
61 
62 #if !IS_IN (libpthread)
63 # ifdef weak_extern
64 weak_extern (__pthread_get_cleanup_stack)
65 # else
66 #  pragma weak __pthread_get_cleanup_stack
67 # endif
68 #endif
69 
70 #endif
71