1 /* Thread package specific definitions of stream lock type. NPTL version. 2 Copyright (C) 2000-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 7 License as published by the Free Software Foundation; either 8 version 2.1 of the 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; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 #ifndef _STDIO_LOCK_H 20 #define _STDIO_LOCK_H 1 21 22 #include <libc-lock.h> 23 #include <lowlevellock.h> 24 25 26 typedef struct { int lock; int cnt; void *owner; } _IO_lock_t; 27 #define _IO_lock_t_defined 1 28 29 #define _IO_lock_initializer { LLL_LOCK_INITIALIZER, 0, NULL } 30 31 #define _IO_lock_init(_name) \ 32 ((void) ((_name) = (_IO_lock_t) _IO_lock_initializer)) 33 34 #define _IO_lock_fini(_name) \ 35 ((void) 0) 36 37 #define _IO_lock_lock(_name) \ 38 do { \ 39 void *__self = THREAD_SELF; \ 40 if ((_name).owner != __self) \ 41 { \ 42 lll_lock ((_name).lock, LLL_PRIVATE); \ 43 (_name).owner = __self; \ 44 } \ 45 ++(_name).cnt; \ 46 } while (0) 47 48 #define _IO_lock_trylock(_name) \ 49 ({ \ 50 int __result = 0; \ 51 void *__self = THREAD_SELF; \ 52 if ((_name).owner != __self) \ 53 { \ 54 if (lll_trylock ((_name).lock) == 0) \ 55 { \ 56 (_name).owner = __self; \ 57 (_name).cnt = 1; \ 58 } \ 59 else \ 60 __result = EBUSY; \ 61 } \ 62 else \ 63 ++(_name).cnt; \ 64 __result; \ 65 }) 66 67 #define _IO_lock_unlock(_name) \ 68 do { \ 69 if (--(_name).cnt == 0) \ 70 { \ 71 (_name).owner = NULL; \ 72 lll_unlock ((_name).lock, LLL_PRIVATE); \ 73 } \ 74 } while (0) 75 76 77 78 #define _IO_cleanup_region_start(_fct, _fp) \ 79 __libc_cleanup_region_start (((_fp)->_flags & _IO_USER_LOCK) == 0, _fct, _fp) 80 #define _IO_cleanup_region_start_noarg(_fct) \ 81 __libc_cleanup_region_start (1, _fct, NULL) 82 #define _IO_cleanup_region_end(_doit) \ 83 __libc_cleanup_region_end (_doit) 84 85 #if defined _LIBC && IS_IN (libc) 86 87 # ifdef __EXCEPTIONS 88 # define _IO_acquire_lock(_fp) \ 89 do { \ 90 FILE *_IO_acquire_lock_file \ 91 __attribute__((cleanup (_IO_acquire_lock_fct))) \ 92 = (_fp); \ 93 _IO_flockfile (_IO_acquire_lock_file); 94 # else 95 # define _IO_acquire_lock(_fp) _IO_acquire_lock_needs_exceptions_enabled 96 # endif 97 # define _IO_release_lock(_fp) ; } while (0) 98 99 #endif 100 101 #endif /* stdio-lock.h */ 102