* 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>
|
2009-07-21 Eric Blake <ebb9@byu.net>
|
||||||
|
|
||||||
* dtable.cc (dup2): Correct return value for no-op.
|
* dtable.cc (dup2): Correct return value for no-op.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* fhandler.cc. See console.cc for fhandler_console functions.
|
/* fhandler.cc. See console.cc for fhandler_console functions.
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
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.
|
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
|
/* Delete all POSIX locks on the file. Delete all flock locks on the
|
||||||
file if this is the last reference to this file. */
|
file if this is the last reference to this file. */
|
||||||
if (unique_id)
|
if (unique_id)
|
||||||
del_my_locks (false);
|
del_my_locks (on_close);
|
||||||
if (nohandle () || CloseHandle (get_handle ()))
|
if (nohandle () || CloseHandle (get_handle ()))
|
||||||
res = 0;
|
res = 0;
|
||||||
else
|
else
|
||||||
|
@ -1359,7 +1359,7 @@ fhandler_base::fixup_after_fork (HANDLE parent)
|
||||||
setup_overlapped ();
|
setup_overlapped ();
|
||||||
/* POSIX locks are not inherited across fork. */
|
/* POSIX locks are not inherited across fork. */
|
||||||
if (unique_id)
|
if (unique_id)
|
||||||
del_my_locks (true);
|
del_my_locks (after_fork);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1369,7 +1369,7 @@ fhandler_base::fixup_after_exec ()
|
||||||
if (get_overlapped ())
|
if (get_overlapped ())
|
||||||
setup_overlapped ();
|
setup_overlapped ();
|
||||||
if (unique_id && close_on_exec ())
|
if (unique_id && close_on_exec ())
|
||||||
del_my_locks (false);
|
del_my_locks (after_exec);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -93,6 +93,12 @@ enum query_state {
|
||||||
query_write_attributes = 4
|
query_write_attributes = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum del_lock_called_from {
|
||||||
|
on_close,
|
||||||
|
after_fork,
|
||||||
|
after_exec
|
||||||
|
};
|
||||||
|
|
||||||
class fhandler_base
|
class fhandler_base
|
||||||
{
|
{
|
||||||
friend class dtable;
|
friend class dtable;
|
||||||
|
@ -141,7 +147,7 @@ class fhandler_base
|
||||||
|
|
||||||
/* Used for advisory file locking. See flock.cc. */
|
/* Used for advisory file locking. See flock.cc. */
|
||||||
long long unique_id;
|
long long unique_id;
|
||||||
void del_my_locks (bool);
|
void del_my_locks (del_lock_called_from);
|
||||||
|
|
||||||
HANDLE read_state;
|
HANDLE read_state;
|
||||||
int wait_overlapped (bool, bool, DWORD *, DWORD = 0) __attribute__ ((regparm (3)));
|
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
|
case the close_on_exec flag is set. The whole inode is deleted as
|
||||||
soon as no lock exists on it anymore. */
|
soon as no lock exists on it anymore. */
|
||||||
void
|
void
|
||||||
fhandler_base::del_my_locks (bool after_fork)
|
fhandler_base::del_my_locks (del_lock_called_from from)
|
||||||
{
|
{
|
||||||
INODE_LIST_LOCK ();
|
INODE_LIST_LOCK ();
|
||||||
inode_t *node = inode_t::get (get_dev (), get_ino (), false);
|
inode_t *node = inode_t::get (get_dev (), get_ino (), false);
|
||||||
if (node)
|
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 =
|
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)
|
if (no_locks_left)
|
||||||
{
|
{
|
||||||
LIST_REMOVE (node, i_next);
|
LIST_REMOVE (node, i_next);
|
||||||
|
|
Loading…
Reference in New Issue