Files
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

180 lines
3.5 KiB
C
Executable File

/* Copyright (c) 1992 Sun Microsystems, Inc. */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "@(#)flockf.c 1.18 95/08/28 SMI" /* SVr4.0 1.2 */
#ifdef __STDC__
#pragma weak flockfile = _flockfile
#pragma weak ftrylockfile = _ftrylockfile
#pragma weak funlockfile = _funlockfile
#endif /* __STDC__ */
#include "synonyms.h"
#include <stdio.h>
#include <thread.h>
#include <synch.h>
#include <mtlib.h>
#include "stdiom.h"
/*
* we move the threads check out of the
* The _rmutex_lock/_rmutex_unlock routines are only called (within libc !)
* by _flockget, _flockfile, and _flockrel, _funlockfile, respectively.
* _flockget and _flockrel are only called by the FLOCKFILE/FUNLOCKFILE
* macros in mtlib.h. We place the "if (_thr_main() == -1)" check for
* threads there, and remove it from:
* _rmutex_lock(rm)
* _rmutex_unlock(rm)
* _flockget(FILE *iop)
* _ftrylockfile(FILE *iop)
* No change is made to _funlockfile(iop) as it makes no additional thread
* check.
*
* No such change is made to
* _rmutex_trylock(rl) since it is called by _findiop
* _flockfile(iop) since we don't know who uses it
*/
static void
_rmutex_lock(rm)
rmutex_t *rm;
{
register thread_t self = _thr_self();
register mutex_t *lk = &rm->_mutex;
_mutex_lock(lk);
if (rm->_owner != 0 && rm->_owner != self) {
rm->_wait_cnt++;
do {
_cond_wait(&rm->_cond, lk);
} while (rm->_owner != 0 && rm->_owner != self);
rm->_wait_cnt--;
}
/* lock is now available to this thread */
rm->_owner = self;
rm->_lock_cnt++;
_mutex_unlock(lk);
}
int
_rmutex_trylock(rm)
rmutex_t *rm;
{
register thread_t self = _thr_self();
register mutex_t *lk = &rm->_mutex;
/*
* Treat like a stub if not linked with libthread as
* indicated by _thr_main() returning -1.
*/
if (_thr_main() == -1)
return (0);
_mutex_lock(lk);
if (rm->_owner != 0 && rm->_owner != self) {
_mutex_unlock(lk);
return (-1);
}
/* lock is now available to this thread */
rm->_owner = self;
rm->_lock_cnt++;
_mutex_unlock(lk);
return (0);
}
/*
* recursive mutex unlock function
*/
static void
_rmutex_unlock(rm)
rmutex_t *rm;
{
register thread_t self = _thr_self();
register mutex_t *lk = &rm->_mutex;
_mutex_lock(lk);
if (rm->_owner == self) {
rm->_lock_cnt--;
if (rm->_lock_cnt == 0) {
rm->_owner = 0;
if (rm->_wait_cnt)
_cond_signal(&rm->_cond);
}
} else {
char msg[] =
"libc internal error: _rmutex_unlock: rmutex not held.\n";
(void) write(2, msg, sizeof (msg));
abort();
}
_mutex_unlock(lk);
}
/*
* compute the lock's position, acquire it and return its pointer
*/
rmutex_t *
_flockget(FILE *iop)
{
register rmutex_t *rl = 0;
rl = IOB_LCK(iop);
/*
* IOB_LCK may return a NULL pointer which means that
* the iop does not require locking, and does not have
* a lock associated with it.
*/
if (rl != NULL)
_rmutex_lock(rl);
return (rl);
}
/*
* POSIX.1c version of ftrylockfile().
* It returns 0 if it gets the lock else returns -1 to indicate the error.
*/
int
_ftrylockfile(FILE *iop)
{
return (_rmutex_trylock(IOB_LCK(iop)));
}
void
_flockrel(rmutex_t *rl)
{
/*
* may be called with a NULL pointer which means that the
* associated iop had no lock. see comments in flockget()
* on how lock could be NULL.
*/
if (rl != NULL)
_rmutex_unlock(rl);
}
void
_flockfile(iop)
FILE *iop;
{
_rmutex_lock(IOB_LCK(iop));
}
void
_funlockfile(iop)
FILE *iop;
{
_rmutex_unlock(IOB_LCK(iop));
}