diff options
author | Michael I. Bushnell <mib@gnu.org> | 1994-02-07 21:12:59 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1994-02-07 21:12:59 +0000 |
commit | 617af1a3c77626b88595f4d0918e23d35b4dce9e (patch) | |
tree | 46491911be10002c907984b439c4b08d6eeefa42 /libfshelp | |
parent | 421d342d4db902e888af9ac7a81368af47bc308c (diff) |
Initial revision
Diffstat (limited to 'libfshelp')
-rw-r--r-- | libfshelp/lock-acquire.c | 128 | ||||
-rw-r--r-- | libfshelp/lock-init.c | 30 |
2 files changed, 158 insertions, 0 deletions
diff --git a/libfshelp/lock-acquire.c b/libfshelp/lock-acquire.c new file mode 100644 index 00000000..0c1bb788 --- /dev/null +++ b/libfshelp/lock-acquire.c @@ -0,0 +1,128 @@ +/* + Copyright (C) 1993, 1994 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Written by Michael I. Bushnell. */ + +#include "fshelp.h" + +error_t +fshelp_acquire_lock (struct lock_box *box, int *user, struct mutex *mut, + int flags) +{ + if (!(flags & (LOCK_UN | LOCK_EX | LOCK_SH))) + return 0; + + if ((flags & LOCK_UN) + && (flags & (LOCK_SH | LOCK_EX))) + return EINVAL; + + if (flags & LOCK_EX) + flags &= ~LOCK_SH; + + /* flags now contains exactly one of LOCK_UN, LOCK_SH, or LOCK_EX. */ + + if (flags & LOCK_UN) + { + if (*user & LOCK_UN) + return EBADF; + assert (*user == box->type); + assert (*user == LOCK_SH || *user == LOCK_EX); + if (*user == LOCK_SH) + { + if (!--box->shcount) + box->lock_type == LOCK_UN; + } + else if (*user == LOCK_EX) + box->lock_type == LOCK_UN; + + if (box->lock_type == LOCK_UN && box->waiting) + { + box->waiting = 0; + condition_broadcast (&box->wait); + } + *user = LOCK_UN; + } + else + { + /* If we have an exclusive lock, release it. */ + if (*user == LOCK_EX) + { + *user = LOCK_UN; + box->type = LOCK_UN; + if (box->waiting) + { + box->waiting = 0; + condition_broadcast (&box->wait); + } + } + + /* If there is an exclusive lock, wait for it to end. */ + while (lock->type == LOCK_EX) + { + if (flags & LOCK_NB) + return EWOULDBLOCK; + box->waiting = 1; + condition_wait (&box->wait, mut); + } + + /* If we have a shared lock, release it. */ + if (*user == LOCK_SH) + { + *user = LOCK_UN; + if (!--box->shcount) + { + box->type = LOCK_UN; + if (box->waiting) + { + box->waiting = 0; + condition_broadcast (&box->wait); + } + } + } + + assert ((flags & LOCK_SH) || (flags & LOCK_EX)); + if (flags & LOCK_SH) + { + assert (box->type != LOCK_EX); + *user = LOCK_SH; + box->type = LOCK_SH; + box->shcount++; + } + else if (flags & LOCK_EX) + { + /* Wait for any shared locks to finish. */ + while (box->type == LOCK_SH) + { + if (flags & LOCK_NB) + return EWOULDBLOCK; + else + { + box->waiting = 1; + condition_wait (&box->wait, mut); + } + } + box->type = LOCK_EX; + *user = LOCK_EX; + } + } + return 0; +} + + + diff --git a/libfshelp/lock-init.c b/libfshelp/lock-init.c new file mode 100644 index 00000000..f32dfae8 --- /dev/null +++ b/libfshelp/lock-init.c @@ -0,0 +1,30 @@ +/* + Copyright (C) 1993, 1994 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Written by Michael I. Bushnell. */ + +/* Initialize a lock box. */ +void +fshelp_lock_init (struct lock_box *box) +{ + box->type = LOCK_UN; + condition_init (&box->wait); + box->waiting = 0; + box->shcount = 0; +} |