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