* fhandler.h (enum del_lock_called_from): New enumeration.
(fhandler_base::del_my_locks): Declare taking a del_lock_called_from as argument. * fhandler.cc (fhandler_base::close): Call del_my_locks with "on_close". (fhandler_base::fixup_after_fork): Call del_my_locks with "after_fork". (fhandler_base::fixup_after_exec): Call del_my_locks with "after_exec". * flock.cc (fhandler_base::del_my_locks): Take del_lock_called_from as argument. Call node->del_my_locks with NULL handle in after_exec case. Explain why.
This commit is contained in:
parent
1e497ebd33
commit
4a77aea071
|
@ -1,3 +1,15 @@
|
|||
2009-07-21 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler.h (enum del_lock_called_from): New enumeration.
|
||||
(fhandler_base::del_my_locks): Declare taking a del_lock_called_from
|
||||
as argument.
|
||||
* fhandler.cc (fhandler_base::close): Call del_my_locks with "on_close".
|
||||
(fhandler_base::fixup_after_fork): Call del_my_locks with "after_fork".
|
||||
(fhandler_base::fixup_after_exec): Call del_my_locks with "after_exec".
|
||||
* flock.cc (fhandler_base::del_my_locks): Take del_lock_called_from
|
||||
as argument. Call node->del_my_locks with NULL handle in after_exec
|
||||
case. Explain why.
|
||||
|
||||
2009-07-21 Eric Blake <ebb9@byu.net>
|
||||
|
||||
* dtable.cc (dup2): Correct return value for no-op.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* fhandler.cc. See console.cc for fhandler_console functions.
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
2005, 2006, 2007, 2008 Red Hat, Inc.
|
||||
2005, 2006, 2007, 2008, 2009 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -1034,7 +1034,7 @@ fhandler_base::close ()
|
|||
/* Delete all POSIX locks on the file. Delete all flock locks on the
|
||||
file if this is the last reference to this file. */
|
||||
if (unique_id)
|
||||
del_my_locks (false);
|
||||
del_my_locks (on_close);
|
||||
if (nohandle () || CloseHandle (get_handle ()))
|
||||
res = 0;
|
||||
else
|
||||
|
@ -1359,7 +1359,7 @@ fhandler_base::fixup_after_fork (HANDLE parent)
|
|||
setup_overlapped ();
|
||||
/* POSIX locks are not inherited across fork. */
|
||||
if (unique_id)
|
||||
del_my_locks (true);
|
||||
del_my_locks (after_fork);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1369,7 +1369,7 @@ fhandler_base::fixup_after_exec ()
|
|||
if (get_overlapped ())
|
||||
setup_overlapped ();
|
||||
if (unique_id && close_on_exec ())
|
||||
del_my_locks (false);
|
||||
del_my_locks (after_exec);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -93,6 +93,12 @@ enum query_state {
|
|||
query_write_attributes = 4
|
||||
};
|
||||
|
||||
enum del_lock_called_from {
|
||||
on_close,
|
||||
after_fork,
|
||||
after_exec
|
||||
};
|
||||
|
||||
class fhandler_base
|
||||
{
|
||||
friend class dtable;
|
||||
|
@ -141,7 +147,7 @@ class fhandler_base
|
|||
|
||||
/* Used for advisory file locking. See flock.cc. */
|
||||
long long unique_id;
|
||||
void del_my_locks (bool);
|
||||
void del_my_locks (del_lock_called_from);
|
||||
|
||||
HANDLE read_state;
|
||||
int wait_overlapped (bool, bool, DWORD *, DWORD = 0) __attribute__ ((regparm (3)));
|
||||
|
|
|
@ -344,14 +344,24 @@ inode_t::del_my_locks (long long id, HANDLE fhdl)
|
|||
case the close_on_exec flag is set. The whole inode is deleted as
|
||||
soon as no lock exists on it anymore. */
|
||||
void
|
||||
fhandler_base::del_my_locks (bool after_fork)
|
||||
fhandler_base::del_my_locks (del_lock_called_from from)
|
||||
{
|
||||
INODE_LIST_LOCK ();
|
||||
inode_t *node = inode_t::get (get_dev (), get_ino (), false);
|
||||
if (node)
|
||||
{
|
||||
/* When we're called from fixup_after_exec, the fhandler is a
|
||||
close-on-exec fhandler. In this case our io handle is already
|
||||
invalid. We can't use it to test for the object reference count.
|
||||
However, that shouldn't be necessary for the following reason.
|
||||
After exec, there are no threads in the current process waiting for
|
||||
the lock. So, either we're the only process accessing the file table
|
||||
entry and there are no threads which require signalling, or we have
|
||||
a parent process still accessing the file object and signalling the
|
||||
lock event would be premature. */
|
||||
bool no_locks_left =
|
||||
node->del_my_locks (after_fork ? 0 : get_unique_id (), get_handle ());
|
||||
node->del_my_locks (from == after_fork ? 0 : get_unique_id (),
|
||||
from == after_exec ? NULL : get_handle ());
|
||||
if (no_locks_left)
|
||||
{
|
||||
LIST_REMOVE (node, i_next);
|
||||
|
|
Loading…
Reference in New Issue