summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/sys/filedesc.h65
1 files changed, 57 insertions, 8 deletions
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index d3cb5e2..fe606e3 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -35,6 +35,7 @@
#include <sys/queue.h>
#include <sys/event.h>
+#include <sys/priority.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
@@ -60,12 +61,13 @@ struct filedesc {
u_short fd_refcnt; /* reference count */
struct mtx fd_mtx; /* protects members of this struct */
+ int fd_locked; /* long lock flag */
+ int fd_wanted; /* "" */
struct kqlist fd_kqlist; /* list of kqueues on this filedesc */
int fd_holdleaderscount; /* block fdfree() for shared close() */
int fd_holdleaderswakeup; /* fdfree() needs wakeup */
};
-
/*
* Structure to keep track of (process leader, struct fildedesc) tuples.
* Each process has a pointer to such a structure when detailed tracking
@@ -93,14 +95,61 @@ struct filedesc_to_leader {
#ifdef _KERNEL
/* Lock a file descriptor table. */
-#define FILEDESC_LOCK(fd) mtx_lock(&(fd)->fd_mtx)
-#define FILEDESC_UNLOCK(fd) mtx_unlock(&(fd)->fd_mtx)
-#define FILEDESC_LOCKED(fd) mtx_owned(&(fd)->fd_mtx)
-#define FILEDESC_LOCK_ASSERT(fd, type) mtx_assert(&(fd)->fd_mtx, (type))
-#define FILEDESC_LOCK_DESC "filedesc structure"
+#define FILEDESC_LOCK(fd) \
+ do { \
+ mtx_lock(&(fd)->fd_mtx); \
+ (fd)->fd_wanted++; \
+ while ((fd)->fd_locked) \
+ msleep(&(fd)->fd_locked, &(fd)->fd_mtx, PLOCK, "fdesc", 0); \
+ (fd)->fd_locked = 2; \
+ (fd)->fd_wanted--; \
+ mtx_unlock(&(fd)->fd_mtx); \
+ } while (0);
+
+#define FILEDESC_UNLOCK(fd) \
+ do { \
+ mtx_lock(&(fd)->fd_mtx); \
+ KASSERT((fd)->fd_locked == 2, \
+ ("fdesc locking mistake %d should be %d", (fd)->fd_locked, 2)); \
+ (fd)->fd_locked = 0; \
+ if ((fd)->fd_wanted) \
+ wakeup(&(fd)->fd_locked); \
+ mtx_unlock(&(fd)->fd_mtx); \
+ } while (0);
+
+#define FILEDESC_LOCK_FAST(fd) \
+ do { \
+ mtx_lock(&(fd)->fd_mtx); \
+ (fd)->fd_wanted++; \
+ while ((fd)->fd_locked) \
+ msleep(&(fd)->fd_locked, &(fd)->fd_mtx, PLOCK, "fdesc", 0); \
+ (fd)->fd_locked = 1; \
+ (fd)->fd_wanted--; \
+ } while (0);
+
+#define FILEDESC_UNLOCK_FAST(fd) \
+ do { \
+ KASSERT((fd)->fd_locked == 1, \
+ ("fdesc locking mistake %d should be %d", (fd)->fd_locked, 1)); \
+ (fd)->fd_locked = 0; \
+ if ((fd)->fd_wanted) \
+ wakeup(&(fd)->fd_locked); \
+ mtx_unlock(&(fd)->fd_mtx); \
+ } while (0);
+
+#ifdef INVARIANT_SUPPORT
+#define FILEDESC_LOCK_ASSERT(fd, arg) \
+ do { \
+ if ((arg) == MA_OWNED) \
+ KASSERT((fd)->fd_locked != 0, ("fdesc locking mistake")); \
+ else \
+ KASSERT((fd)->fd_locked == 0, ("fdesc locking mistake")); \
+ } while (0);
+#else
+#define FILEDESC_LOCK_ASSERT(fd, arg)
+#endif
-#define FILEDESC_LOCK_FAST(fd) FILEDESC_LOCK(fd);
-#define FILEDESC_UNLOCK_FAST(fd) FILEDESC_UNLOCK(fd);
+#define FILEDESC_LOCK_DESC "filedesc structure"
struct thread;
OpenPOWER on IntegriCloud