_flock_stub.c revision 303975
1321369Sdim/* 2234285Sdim * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>. 3353358Sdim * All rights reserved. 4353358Sdim * 5353358Sdim * Redistribution and use in source and binary forms, with or without 6234285Sdim * modification, are permitted provided that the following conditions 7234285Sdim * are met: 8234285Sdim * 1. Redistributions of source code must retain the above copyright 9261991Sdim * notice, this list of conditions and the following disclaimer. 10261991Sdim * 2. Redistributions in binary form must reproduce the above copyright 11261991Sdim * notice, this list of conditions and the following disclaimer in the 12261991Sdim * documentation and/or other materials provided with the distribution. 13261991Sdim * 3. Neither the name of the author nor the names of any co-contributors 14261991Sdim * may be used to endorse or promote products derived from this software 15261991Sdim * without specific prior written permission. 16261991Sdim * 17261991Sdim * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 18261991Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19261991Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20261991Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21261991Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22261991Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23261991Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24261991Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25276479Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26261991Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27261991Sdim * SUCH DAMAGE. 28327952Sdim */ 29261991Sdim 30261991Sdim/* 31261991Sdim * POSIX stdio FILE locking functions. These assume that the locking 32261991Sdim * is only required at FILE structure level, not at file descriptor 33261991Sdim * level too. 34321369Sdim * 35261991Sdim */ 36261991Sdim 37261991Sdim#include <sys/cdefs.h> 38261991Sdim__FBSDID("$FreeBSD: releng/11.0/lib/libc/stdio/_flock_stub.c 288031 2015-09-20 20:26:46Z rodrigc $"); 39261991Sdim 40261991Sdim#include "namespace.h" 41261991Sdim#include <stdio.h> 42261991Sdim#include <stdlib.h> 43261991Sdim#include <string.h> 44314564Sdim#include <pthread.h> 45314564Sdim#include "un-namespace.h" 46261991Sdim 47261991Sdim#include "local.h" 48261991Sdim 49261991Sdim 50261991Sdim/* 51234285Sdim * Weak symbols for externally visible functions in this file: 52234285Sdim */ 53234285Sdim__weak_reference(_flockfile, flockfile); 54234285Sdim__weak_reference(_flockfile_debug_stub, _flockfile_debug); 55234285Sdim__weak_reference(_ftrylockfile, ftrylockfile); 56234285Sdim__weak_reference(_funlockfile, funlockfile); 57234285Sdim 58234285Sdimvoid _flockfile_debug_stub(FILE *, char *, int); 59234285Sdimint _ftrylockfile(FILE *); 60234285Sdim 61261991Sdimvoid 62261991Sdim_flockfile(FILE *fp) 63261991Sdim{ 64261991Sdim pthread_t curthread = _pthread_self(); 65261991Sdim 66261991Sdim if (fp->_fl_owner == curthread) 67261991Sdim fp->_fl_count++; 68261991Sdim else { 69261991Sdim /* 70261991Sdim * Make sure this mutex is treated as a private 71261991Sdim * internal mutex: 72234285Sdim */ 73234285Sdim _pthread_mutex_lock(&fp->_fl_mutex); 74249423Sdim fp->_fl_owner = curthread; 75249423Sdim fp->_fl_count = 1; 76234285Sdim } 77314564Sdim} 78314564Sdim 79314564Sdim/* 80314564Sdim * This can be overriden by the threads library if it is linked in. 81314564Sdim */ 82314564Sdimvoid 83296417Sdim_flockfile_debug_stub(FILE *fp, char *fname, int lineno) 84314564Sdim{ 85234285Sdim _flockfile(fp); 86243830Sdim} 87314564Sdim 88243830Sdimint 89309124Sdim_ftrylockfile(FILE *fp) 90314564Sdim{ 91314564Sdim pthread_t curthread = _pthread_self(); 92314564Sdim int ret = 0; 93314564Sdim 94314564Sdim if (fp->_fl_owner == curthread) 95276479Sdim fp->_fl_count++; 96314564Sdim /* 97314564Sdim * Make sure this mutex is treated as a private 98276479Sdim * internal mutex: 99234285Sdim */ 100234285Sdim else if (_pthread_mutex_trylock(&fp->_fl_mutex) == 0) { 101243830Sdim fp->_fl_owner = curthread; 102243830Sdim fp->_fl_count = 1; 103360784Sdim } 104243830Sdim else 105234285Sdim ret = -1; 106234285Sdim return (ret); 107321369Sdim} 108321369Sdim 109234285Sdimvoid 110239462Sdim_funlockfile(FILE *fp) 111249423Sdim{ 112276479Sdim pthread_t curthread = _pthread_self(); 113321369Sdim 114321369Sdim /* 115321369Sdim * Check if this file is owned by the current thread: 116234285Sdim */ 117234285Sdim if (fp->_fl_owner == curthread) { 118234285Sdim /* 119234285Sdim * Check if this thread has locked the FILE 120321369Sdim * more than once: 121321369Sdim */ 122321369Sdim if (fp->_fl_count > 1) 123321369Sdim /* 124321369Sdim * Decrement the count of the number of 125321369Sdim * times the running thread has locked this 126234285Sdim * file: 127239462Sdim */ 128239462Sdim fp->_fl_count--; 129239462Sdim else { 130239462Sdim /* 131234285Sdim * The running thread will release the 132234285Sdim * lock now: 133234285Sdim */ 134234285Sdim fp->_fl_count = 0; 135344779Sdim fp->_fl_owner = NULL; 136344779Sdim _pthread_mutex_unlock(&fp->_fl_mutex); 137344779Sdim } 138234285Sdim } 139321369Sdim} 140234285Sdim