From a74869c027033e90b0cc8e15ef96ac0a82ab06eb Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 17 Apr 2009 13:29:08 +0000 Subject: [PATCH] * flock.cc (class inode_t): Add i_wait member and matching methods wait(), unwait(), and waiting(). (inode_t::inode_t): Initialize i_wait to 0. (fhandler_disk_file::lock): Only remove node if no other thread is waiting for a blocking lock. (lf_setlock): Manipulate node->i_wait to signal that a thread is waiting for a blocking lock in this node. (lf_findoverlap): Reinstantiate SELF test as in original code. --- winsup/cygwin/ChangeLog | 11 +++++++++++ winsup/cygwin/flock.cc | 18 ++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 7d834ea04..b81dba3f8 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,14 @@ +2009-04-17 Corinna Vinschen + + * flock.cc (class inode_t): Add i_wait member and matching methods + wait(), unwait(), and waiting(). + (inode_t::inode_t): Initialize i_wait to 0. + (fhandler_disk_file::lock): Only remove node if no other thread is + waiting for a blocking lock. + (lf_setlock): Manipulate node->i_wait to signal that a thread is + waiting for a blocking lock in this node. + (lf_findoverlap): Reinstantiate SELF test as in original code. + 2009-04-16 Corinna Vinschen * dlfcn.cc (get_full_path_of_dll): Just return a bool value. Drop diff --git a/winsup/cygwin/flock.cc b/winsup/cygwin/flock.cc index b194a3f7b..e17166044 100644 --- a/winsup/cygwin/flock.cc +++ b/winsup/cygwin/flock.cc @@ -1,6 +1,6 @@ /* flock.cc. NT specific implementation of advisory file locking. - Copyright 2003, 2008 Red Hat, Inc. + Copyright 2003, 2008, 2009 Red Hat, Inc. This file is part of Cygwin. @@ -267,6 +267,8 @@ class inode_t private: HANDLE i_dir; HANDLE i_mtx; + unsigned long i_wait; /* Number of blocked threads waiting for + a blocking lock. */ public: inode_t (__dev32_t dev, __ino64_t ino); @@ -282,6 +284,10 @@ class inode_t void LOCK () { WaitForSingleObject (i_mtx, INFINITE); } void UNLOCK () { ReleaseMutex (i_mtx); } + void wait () { ++i_wait; } + void unwait () { if (i_wait > 0) --i_wait; } + bool waiting () { return i_wait > 0; } + lockf_t *get_all_locks_list (); bool del_my_locks (long long id, HANDLE fhdl); @@ -427,7 +433,7 @@ inode_t::get (__dev32_t dev, __ino64_t ino, bool create_if_missing) } inode_t::inode_t (__dev32_t dev, __ino64_t ino) -: i_lockf (NULL), i_all_lf (NULL), i_dev (dev), i_ino (ino) +: i_lockf (NULL), i_all_lf (NULL), i_dev (dev), i_ino (ino), i_wait (0L) { HANDLE parent_dir; WCHAR name[48]; @@ -823,7 +829,7 @@ fhandler_disk_file::lock (int a_op, struct __flock64 *fl) delete lock; lock = n; } - if (node->i_lockf == NULL) + if (node->i_lockf == NULL && !node->waiting ()) { INODE_LIST_LOCK (); LIST_REMOVE (node, i_next); @@ -946,6 +952,7 @@ lf_setlock (lockf_t *lock, inode_t *node, lockf_t **clean, HANDLE fhdl) return EDEADLK; } HANDLE w4[3] = { obj, proc, signal_arrived }; + node->wait (); node->UNLOCK (); ret = WaitForMultipleObjects (3, w4, FALSE, INFINITE); CloseHandle (proc); @@ -953,6 +960,7 @@ lf_setlock (lockf_t *lock, inode_t *node, lockf_t **clean, HANDLE fhdl) else { HANDLE w4[2] = { obj, signal_arrived }; + node->wait (); node->UNLOCK (); /* Unfortunately, since BSD flock locks are not attached to a specific process, we can't recognize an abandoned lock by @@ -965,6 +973,7 @@ lf_setlock (lockf_t *lock, inode_t *node, lockf_t **clean, HANDLE fhdl) while (ret == WAIT_TIMEOUT && get_obj_handle_count (obj) > 1); } node->LOCK (); + node->unwait (); NtClose (obj); SetThreadPriority (GetCurrentThread (), old_prio); switch (ret) @@ -1283,7 +1292,8 @@ lf_findoverlap (lockf_t *lf, lockf_t *lock, int type, lockf_t ***prev, end = lock->lf_end; while (lf != NOLOCKF) { - if (((type & OTHERS) && lf->lf_id == lock->lf_id) + if (((type & SELF) && lf->lf_id != lock->lf_id) + || ((type & OTHERS) && lf->lf_id == lock->lf_id) /* As on Linux: POSIX locks and BSD flock locks don't interact. */ || (lf->lf_flags & (F_POSIX | F_FLOCK)) != (lock->lf_flags & (F_POSIX | F_FLOCK))) -- 2.43.5