+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.
/* 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.
/* 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
setup_overlapped ();
/* POSIX locks are not inherited across fork. */
if (unique_id)
- del_my_locks (true);
+ del_my_locks (after_fork);
}
void
if (get_overlapped ())
setup_overlapped ();
if (unique_id && close_on_exec ())
- del_my_locks (false);
+ del_my_locks (after_exec);
}
bool
query_write_attributes = 4
};
+enum del_lock_called_from {
+ on_close,
+ after_fork,
+ after_exec
+};
+
class fhandler_base
{
friend class dtable;
/* 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)));
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);