* 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.
This commit is contained in:
parent
5bbd5ae0bb
commit
a74869c027
@ -1,3 +1,14 @@
|
||||
2009-04-17 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* 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 <corinna@vinschen.de>
|
||||
|
||||
* dlfcn.cc (get_full_path_of_dll): Just return a bool value. Drop
|
||||
|
@ -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)))
|
||||
|
Loading…
Reference in New Issue
Block a user