* 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>
|
2009-04-16 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* dlfcn.cc (get_full_path_of_dll): Just return a bool value. Drop
|
* 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.
|
/* 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.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -267,6 +267,8 @@ class inode_t
|
|||||||
private:
|
private:
|
||||||
HANDLE i_dir;
|
HANDLE i_dir;
|
||||||
HANDLE i_mtx;
|
HANDLE i_mtx;
|
||||||
|
unsigned long i_wait; /* Number of blocked threads waiting for
|
||||||
|
a blocking lock. */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inode_t (__dev32_t dev, __ino64_t ino);
|
inode_t (__dev32_t dev, __ino64_t ino);
|
||||||
@ -282,6 +284,10 @@ class inode_t
|
|||||||
void LOCK () { WaitForSingleObject (i_mtx, INFINITE); }
|
void LOCK () { WaitForSingleObject (i_mtx, INFINITE); }
|
||||||
void UNLOCK () { ReleaseMutex (i_mtx); }
|
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 ();
|
lockf_t *get_all_locks_list ();
|
||||||
|
|
||||||
bool del_my_locks (long long id, HANDLE fhdl);
|
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)
|
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;
|
HANDLE parent_dir;
|
||||||
WCHAR name[48];
|
WCHAR name[48];
|
||||||
@ -823,7 +829,7 @@ fhandler_disk_file::lock (int a_op, struct __flock64 *fl)
|
|||||||
delete lock;
|
delete lock;
|
||||||
lock = n;
|
lock = n;
|
||||||
}
|
}
|
||||||
if (node->i_lockf == NULL)
|
if (node->i_lockf == NULL && !node->waiting ())
|
||||||
{
|
{
|
||||||
INODE_LIST_LOCK ();
|
INODE_LIST_LOCK ();
|
||||||
LIST_REMOVE (node, i_next);
|
LIST_REMOVE (node, i_next);
|
||||||
@ -946,6 +952,7 @@ lf_setlock (lockf_t *lock, inode_t *node, lockf_t **clean, HANDLE fhdl)
|
|||||||
return EDEADLK;
|
return EDEADLK;
|
||||||
}
|
}
|
||||||
HANDLE w4[3] = { obj, proc, signal_arrived };
|
HANDLE w4[3] = { obj, proc, signal_arrived };
|
||||||
|
node->wait ();
|
||||||
node->UNLOCK ();
|
node->UNLOCK ();
|
||||||
ret = WaitForMultipleObjects (3, w4, FALSE, INFINITE);
|
ret = WaitForMultipleObjects (3, w4, FALSE, INFINITE);
|
||||||
CloseHandle (proc);
|
CloseHandle (proc);
|
||||||
@ -953,6 +960,7 @@ lf_setlock (lockf_t *lock, inode_t *node, lockf_t **clean, HANDLE fhdl)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
HANDLE w4[2] = { obj, signal_arrived };
|
HANDLE w4[2] = { obj, signal_arrived };
|
||||||
|
node->wait ();
|
||||||
node->UNLOCK ();
|
node->UNLOCK ();
|
||||||
/* Unfortunately, since BSD flock locks are not attached to a
|
/* Unfortunately, since BSD flock locks are not attached to a
|
||||||
specific process, we can't recognize an abandoned lock by
|
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);
|
while (ret == WAIT_TIMEOUT && get_obj_handle_count (obj) > 1);
|
||||||
}
|
}
|
||||||
node->LOCK ();
|
node->LOCK ();
|
||||||
|
node->unwait ();
|
||||||
NtClose (obj);
|
NtClose (obj);
|
||||||
SetThreadPriority (GetCurrentThread (), old_prio);
|
SetThreadPriority (GetCurrentThread (), old_prio);
|
||||||
switch (ret)
|
switch (ret)
|
||||||
@ -1283,7 +1292,8 @@ lf_findoverlap (lockf_t *lf, lockf_t *lock, int type, lockf_t ***prev,
|
|||||||
end = lock->lf_end;
|
end = lock->lf_end;
|
||||||
while (lf != NOLOCKF)
|
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. */
|
/* As on Linux: POSIX locks and BSD flock locks don't interact. */
|
||||||
|| (lf->lf_flags & (F_POSIX | F_FLOCK))
|
|| (lf->lf_flags & (F_POSIX | F_FLOCK))
|
||||||
!= (lock->lf_flags & (F_POSIX | F_FLOCK)))
|
!= (lock->lf_flags & (F_POSIX | F_FLOCK)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user