summaryrefslogtreecommitdiff
path: root/libfshelp
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1994-02-07 21:12:59 +0000
committerMichael I. Bushnell <mib@gnu.org>1994-02-07 21:12:59 +0000
commit617af1a3c77626b88595f4d0918e23d35b4dce9e (patch)
tree46491911be10002c907984b439c4b08d6eeefa42 /libfshelp
parent421d342d4db902e888af9ac7a81368af47bc308c (diff)
Initial revision
Diffstat (limited to 'libfshelp')
-rw-r--r--libfshelp/lock-acquire.c128
-rw-r--r--libfshelp/lock-init.c30
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;
+}