Deleted Added
full compact
_flock_stub.c (72373) _flock_stub.c (72529)
1/*
2 * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by John Birrell.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
1/*
2 * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by John Birrell.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $FreeBSD: head/lib/libc/stdio/_flock_stub.c 72373 2001-02-11 22:06:43Z deischen $
32 * $FreeBSD: head/lib/libc/stdio/_flock_stub.c 72529 2001-02-16 06:11:22Z imp $
33 *
34 */
35
36/*
37 * POSIX stdio FILE locking functions. These assume that the locking
38 * is only required at FILE structure level, not at file descriptor
39 * level too.
40 *
41 */
42
43#include "namespace.h"
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <pthread.h>
48#include "un-namespace.h"
49
50/*
51 * Weak symbols for externally visible functions in this file:
52 */
53#pragma weak flockfile=_flockfile
54#pragma weak _flockfile_debug=_flockfile_debug_stub
55#pragma weak ftrylockfile=_ftrylockfile
56#pragma weak funlockfile=_funlockfile
57
58static int init_lock(FILE *);
59
60/*
61 * The FILE lock structure. The FILE *fp is locked when the mutex
62 * is locked.
63 */
64struct __file_lock {
65 pthread_mutex_t fl_mutex;
66 pthread_t fl_owner; /* current owner */
67 int fl_count; /* recursive lock count */
68};
69
70/*
33 *
34 */
35
36/*
37 * POSIX stdio FILE locking functions. These assume that the locking
38 * is only required at FILE structure level, not at file descriptor
39 * level too.
40 *
41 */
42
43#include "namespace.h"
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <pthread.h>
48#include "un-namespace.h"
49
50/*
51 * Weak symbols for externally visible functions in this file:
52 */
53#pragma weak flockfile=_flockfile
54#pragma weak _flockfile_debug=_flockfile_debug_stub
55#pragma weak ftrylockfile=_ftrylockfile
56#pragma weak funlockfile=_funlockfile
57
58static int init_lock(FILE *);
59
60/*
61 * The FILE lock structure. The FILE *fp is locked when the mutex
62 * is locked.
63 */
64struct __file_lock {
65 pthread_mutex_t fl_mutex;
66 pthread_t fl_owner; /* current owner */
67 int fl_count; /* recursive lock count */
68};
69
70/*
71 * We need to retain binary compatibility for a while. So pretend
72 * that _lock is part of FILE * even though it is dereferenced off
73 * _extra now. When we stop encoding the size of FILE into binaries
74 * this can be changed in stdio.h. This will reduce the amount of
75 * code that has to change in the future (just remove this comment
76 * and #define).
77 */
78#define _lock _extra->_mtlock
79
80/*
71 * Allocate and initialize a file lock.
72 */
73static int
74init_lock(FILE *fp)
75{
76 struct __file_lock *p;
77 int ret;
78
79 if ((p = malloc(sizeof(struct __file_lock))) == NULL)
80 ret = -1;
81 else {
82 p->fl_mutex = PTHREAD_MUTEX_INITIALIZER;
83 p->fl_owner = NULL;
84 p->fl_count = 0;
85 fp->_lock = p;
86 ret = 0;
87 }
88 return (ret);
89}
90
91void
92_flockfile(FILE *fp)
93{
94 pthread_t curthread = _pthread_self();
95
96 /*
97 * Check if this is a real file with a valid lock, creating
98 * the lock if needed:
99 */
100 if ((fp->_file >= 0) &&
101 ((fp->_lock != NULL) || (init_lock(fp) == 0))) {
102 if (fp->_lock->fl_owner == curthread)
103 fp->_lock->fl_count++;
104 else {
105 /*
106 * Make sure this mutex is treated as a private
107 * internal mutex:
108 */
109 _pthread_mutex_lock(&fp->_lock->fl_mutex);
110 fp->_lock->fl_owner = curthread;
111 fp->_lock->fl_count = 1;
112 }
113 }
114}
115
116/*
117 * This can be overriden by the threads library if it is linked in.
118 */
119void
120_flockfile_debug_stub(FILE *fp, char *fname, int lineno)
121{
122 _flockfile(fp);
123}
124
125int
126_ftrylockfile(FILE *fp)
127{
128 pthread_t curthread = _pthread_self();
129 int ret = 0;
130
131 /*
132 * Check if this is a real file with a valid lock, creating
133 * the lock if needed:
134 */
135 if ((fp->_file >= 0) &&
136 ((fp->_lock != NULL) || (init_lock(fp) == 0))) {
137 if (fp->_lock->fl_owner == curthread)
138 fp->_lock->fl_count++;
139 /*
140 * Make sure this mutex is treated as a private
141 * internal mutex:
142 */
143 else if (_pthread_mutex_trylock(&fp->_lock->fl_mutex) == 0) {
144 fp->_lock->fl_owner = curthread;
145 fp->_lock->fl_count = 1;
146 }
147 else
148 ret = -1;
149 }
150 else
151 ret = -1;
152 return (ret);
153}
154
155void
156_funlockfile(FILE *fp)
157{
158 pthread_t curthread = _pthread_self();
159
160 /*
161 * Check if this is a real file with a valid lock owned
162 * by the current thread:
163 */
164 if ((fp->_file >= 0) && (fp->_lock != NULL) &&
165 (fp->_lock->fl_owner == curthread)) {
166 /*
167 * Check if this thread has locked the FILE
168 * more than once:
169 */
170 if (fp->_lock->fl_count > 1)
171 /*
172 * Decrement the count of the number of
173 * times the running thread has locked this
174 * file:
175 */
176 fp->_lock->fl_count--;
177 else {
178 /*
179 * The running thread will release the
180 * lock now:
181 */
182 fp->_lock->fl_count = 0;
183 fp->_lock->fl_owner = NULL;
184 _pthread_mutex_unlock(&fp->_lock->fl_mutex);
185 }
186 }
187}
81 * Allocate and initialize a file lock.
82 */
83static int
84init_lock(FILE *fp)
85{
86 struct __file_lock *p;
87 int ret;
88
89 if ((p = malloc(sizeof(struct __file_lock))) == NULL)
90 ret = -1;
91 else {
92 p->fl_mutex = PTHREAD_MUTEX_INITIALIZER;
93 p->fl_owner = NULL;
94 p->fl_count = 0;
95 fp->_lock = p;
96 ret = 0;
97 }
98 return (ret);
99}
100
101void
102_flockfile(FILE *fp)
103{
104 pthread_t curthread = _pthread_self();
105
106 /*
107 * Check if this is a real file with a valid lock, creating
108 * the lock if needed:
109 */
110 if ((fp->_file >= 0) &&
111 ((fp->_lock != NULL) || (init_lock(fp) == 0))) {
112 if (fp->_lock->fl_owner == curthread)
113 fp->_lock->fl_count++;
114 else {
115 /*
116 * Make sure this mutex is treated as a private
117 * internal mutex:
118 */
119 _pthread_mutex_lock(&fp->_lock->fl_mutex);
120 fp->_lock->fl_owner = curthread;
121 fp->_lock->fl_count = 1;
122 }
123 }
124}
125
126/*
127 * This can be overriden by the threads library if it is linked in.
128 */
129void
130_flockfile_debug_stub(FILE *fp, char *fname, int lineno)
131{
132 _flockfile(fp);
133}
134
135int
136_ftrylockfile(FILE *fp)
137{
138 pthread_t curthread = _pthread_self();
139 int ret = 0;
140
141 /*
142 * Check if this is a real file with a valid lock, creating
143 * the lock if needed:
144 */
145 if ((fp->_file >= 0) &&
146 ((fp->_lock != NULL) || (init_lock(fp) == 0))) {
147 if (fp->_lock->fl_owner == curthread)
148 fp->_lock->fl_count++;
149 /*
150 * Make sure this mutex is treated as a private
151 * internal mutex:
152 */
153 else if (_pthread_mutex_trylock(&fp->_lock->fl_mutex) == 0) {
154 fp->_lock->fl_owner = curthread;
155 fp->_lock->fl_count = 1;
156 }
157 else
158 ret = -1;
159 }
160 else
161 ret = -1;
162 return (ret);
163}
164
165void
166_funlockfile(FILE *fp)
167{
168 pthread_t curthread = _pthread_self();
169
170 /*
171 * Check if this is a real file with a valid lock owned
172 * by the current thread:
173 */
174 if ((fp->_file >= 0) && (fp->_lock != NULL) &&
175 (fp->_lock->fl_owner == curthread)) {
176 /*
177 * Check if this thread has locked the FILE
178 * more than once:
179 */
180 if (fp->_lock->fl_count > 1)
181 /*
182 * Decrement the count of the number of
183 * times the running thread has locked this
184 * file:
185 */
186 fp->_lock->fl_count--;
187 else {
188 /*
189 * The running thread will release the
190 * lock now:
191 */
192 fp->_lock->fl_count = 0;
193 fp->_lock->fl_owner = NULL;
194 _pthread_mutex_unlock(&fp->_lock->fl_mutex);
195 }
196 }
197}