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 *
|
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 * 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}
|