flockfile.c revision 1.9.8.2 1 1.9.8.2 martin /* $NetBSD: flockfile.c,v 1.9.8.2 2008/04/28 20:23:01 martin Exp $ */
2 1.9.8.2 martin
3 1.9.8.2 martin /*-
4 1.9.8.2 martin * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 1.9.8.2 martin * All rights reserved.
6 1.9.8.2 martin *
7 1.9.8.2 martin * This code is derived from software contributed to The NetBSD Foundation
8 1.9.8.2 martin * by Nathan J. Williams.
9 1.9.8.2 martin *
10 1.9.8.2 martin * Redistribution and use in source and binary forms, with or without
11 1.9.8.2 martin * modification, are permitted provided that the following conditions
12 1.9.8.2 martin * are met:
13 1.9.8.2 martin * 1. Redistributions of source code must retain the above copyright
14 1.9.8.2 martin * notice, this list of conditions and the following disclaimer.
15 1.9.8.2 martin * 2. Redistributions in binary form must reproduce the above copyright
16 1.9.8.2 martin * notice, this list of conditions and the following disclaimer in the
17 1.9.8.2 martin * documentation and/or other materials provided with the distribution.
18 1.9.8.2 martin *
19 1.9.8.2 martin * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.9.8.2 martin * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.9.8.2 martin * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.9.8.2 martin * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.9.8.2 martin * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.9.8.2 martin * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.9.8.2 martin * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.9.8.2 martin * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.9.8.2 martin * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.9.8.2 martin * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.9.8.2 martin * POSSIBILITY OF SUCH DAMAGE.
30 1.9.8.2 martin */
31 1.9.8.2 martin
32 1.9.8.2 martin #include <sys/cdefs.h>
33 1.9.8.2 martin #if defined(LIBC_SCCS) && !defined(lint)
34 1.9.8.2 martin __RCSID("$NetBSD: flockfile.c,v 1.9.8.2 2008/04/28 20:23:01 martin Exp $");
35 1.9.8.2 martin #endif /* LIBC_SCCS and not lint */
36 1.9.8.2 martin
37 1.9.8.2 martin #include "namespace.h"
38 1.9.8.2 martin
39 1.9.8.2 martin #include <assert.h>
40 1.9.8.2 martin #include <errno.h>
41 1.9.8.2 martin #include <stdio.h>
42 1.9.8.2 martin #include <string.h>
43 1.9.8.2 martin #include "reentrant.h"
44 1.9.8.2 martin #include "local.h"
45 1.9.8.2 martin
46 1.9.8.2 martin #ifdef __weak_alias
47 1.9.8.2 martin __weak_alias(flockfile,_flockfile)
48 1.9.8.2 martin __weak_alias(ftrylockfile,_ftrylockfile)
49 1.9.8.2 martin __weak_alias(funlockfile,_funlockfile)
50 1.9.8.2 martin #endif
51 1.9.8.2 martin
52 1.9.8.2 martin #ifdef _REENTRANT
53 1.9.8.2 martin /*
54 1.9.8.2 martin * XXX This code makes the assumption that a thr_t (pthread_t) is a
55 1.9.8.2 martin * XXX pointer.
56 1.9.8.2 martin */
57 1.9.8.2 martin
58 1.9.8.2 martin extern int __isthreaded;
59 1.9.8.2 martin
60 1.9.8.2 martin void
61 1.9.8.2 martin flockfile(FILE *fp)
62 1.9.8.2 martin {
63 1.9.8.2 martin
64 1.9.8.2 martin __flockfile_internal(fp, 0);
65 1.9.8.2 martin }
66 1.9.8.2 martin
67 1.9.8.2 martin int
68 1.9.8.2 martin ftrylockfile(FILE *fp)
69 1.9.8.2 martin {
70 1.9.8.2 martin int retval;
71 1.9.8.2 martin
72 1.9.8.2 martin if (__isthreaded == 0)
73 1.9.8.2 martin return 0;
74 1.9.8.2 martin
75 1.9.8.2 martin retval = 0;
76 1.9.8.2 martin mutex_lock(&_LOCK(fp));
77 1.9.8.2 martin
78 1.9.8.2 martin if (_LOCKOWNER(fp) == thr_self()) {
79 1.9.8.2 martin _LOCKCOUNT(fp)++;
80 1.9.8.2 martin } else if (_LOCKOWNER(fp) == NULL) {
81 1.9.8.2 martin _LOCKOWNER(fp) = thr_self();
82 1.9.8.2 martin _LOCKCOUNT(fp) = 1;
83 1.9.8.2 martin } else
84 1.9.8.2 martin retval = -1;
85 1.9.8.2 martin
86 1.9.8.2 martin mutex_unlock(&_LOCK(fp));
87 1.9.8.2 martin
88 1.9.8.2 martin return retval;
89 1.9.8.2 martin }
90 1.9.8.2 martin
91 1.9.8.2 martin void
92 1.9.8.2 martin funlockfile(FILE *fp)
93 1.9.8.2 martin {
94 1.9.8.2 martin
95 1.9.8.2 martin __funlockfile_internal(fp, 0);
96 1.9.8.2 martin }
97 1.9.8.2 martin
98 1.9.8.2 martin void
99 1.9.8.2 martin __flockfile_internal(FILE *fp, int internal)
100 1.9.8.2 martin {
101 1.9.8.2 martin
102 1.9.8.2 martin if (__isthreaded == 0)
103 1.9.8.2 martin return;
104 1.9.8.2 martin
105 1.9.8.2 martin mutex_lock(&_LOCK(fp));
106 1.9.8.2 martin
107 1.9.8.2 martin if (_LOCKOWNER(fp) == thr_self()) {
108 1.9.8.2 martin _LOCKCOUNT(fp)++;
109 1.9.8.2 martin if (internal)
110 1.9.8.2 martin _LOCKINTERNAL(fp)++;
111 1.9.8.2 martin } else {
112 1.9.8.2 martin /* danger! cond_wait() is a cancellation point. */
113 1.9.8.2 martin int oldstate;
114 1.9.8.2 martin thr_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
115 1.9.8.2 martin while (_LOCKOWNER(fp) != NULL)
116 1.9.8.2 martin cond_wait(&_LOCKCOND(fp), &_LOCK(fp));
117 1.9.8.2 martin thr_setcancelstate(oldstate, NULL);
118 1.9.8.2 martin _LOCKOWNER(fp) = thr_self();
119 1.9.8.2 martin _LOCKCOUNT(fp) = 1;
120 1.9.8.2 martin if (internal)
121 1.9.8.2 martin _LOCKINTERNAL(fp) = 1;
122 1.9.8.2 martin }
123 1.9.8.2 martin
124 1.9.8.2 martin if (_LOCKINTERNAL(fp) == 1)
125 1.9.8.2 martin /* stash cancellation state and disable */
126 1.9.8.2 martin thr_setcancelstate(PTHREAD_CANCEL_DISABLE,
127 1.9.8.2 martin &_LOCKCANCELSTATE(fp));
128 1.9.8.2 martin
129 1.9.8.2 martin mutex_unlock(&_LOCK(fp));
130 1.9.8.2 martin }
131 1.9.8.2 martin
132 1.9.8.2 martin void
133 1.9.8.2 martin __funlockfile_internal(FILE *fp, int internal)
134 1.9.8.2 martin {
135 1.9.8.2 martin
136 1.9.8.2 martin if (__isthreaded == 0)
137 1.9.8.2 martin return;
138 1.9.8.2 martin
139 1.9.8.2 martin mutex_lock(&_LOCK(fp));
140 1.9.8.2 martin
141 1.9.8.2 martin if (internal) {
142 1.9.8.2 martin _LOCKINTERNAL(fp)--;
143 1.9.8.2 martin if (_LOCKINTERNAL(fp) == 0)
144 1.9.8.2 martin thr_setcancelstate(_LOCKCANCELSTATE(fp), NULL);
145 1.9.8.2 martin }
146 1.9.8.2 martin
147 1.9.8.2 martin _LOCKCOUNT(fp)--;
148 1.9.8.2 martin if (_LOCKCOUNT(fp) == 0) {
149 1.9.8.2 martin _LOCKOWNER(fp) = NULL;
150 1.9.8.2 martin cond_signal(&_LOCKCOND(fp));
151 1.9.8.2 martin }
152 1.9.8.2 martin
153 1.9.8.2 martin mutex_unlock(&_LOCK(fp));
154 1.9.8.2 martin }
155 1.9.8.2 martin
156 1.9.8.2 martin #else /* _REENTRANT */
157 1.9.8.2 martin
158 1.9.8.2 martin void
159 1.9.8.2 martin flockfile(FILE *fp)
160 1.9.8.2 martin {
161 1.9.8.2 martin /* LINTED deliberate lack of effect */
162 1.9.8.2 martin (void)fp;
163 1.9.8.2 martin
164 1.9.8.2 martin return;
165 1.9.8.2 martin }
166 1.9.8.2 martin
167 1.9.8.2 martin int
168 1.9.8.2 martin ftrylockfile(FILE *fp)
169 1.9.8.2 martin {
170 1.9.8.2 martin /* LINTED deliberate lack of effect */
171 1.9.8.2 martin (void)fp;
172 1.9.8.2 martin
173 1.9.8.2 martin return (0);
174 1.9.8.2 martin }
175 1.9.8.2 martin
176 1.9.8.2 martin void
177 1.9.8.2 martin funlockfile(FILE *fp)
178 1.9.8.2 martin {
179 1.9.8.2 martin /* LINTED deliberate lack of effect */
180 1.9.8.2 martin (void)fp;
181 1.9.8.2 martin
182 1.9.8.2 martin return;
183 1.9.8.2 martin }
184 1.9.8.2 martin
185 1.9.8.2 martin #endif /* _REENTRANT */
186