Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2009-07-22 19:46:36 +0400
committerCorinna Vinschen <corinna@vinschen.de>2009-07-22 19:46:36 +0400
commit4a77aea0714cf0175279fbf65cdb8322a5af958b (patch)
tree6c49ca63adb99610e12ed93645b40c3ee5153672
parent1e497ebd33c2e75d6e2a00d438d8012b3f4ab79c (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog12
-rw-r--r--winsup/cygwin/fhandler.cc8
-rw-r--r--winsup/cygwin/fhandler.h8
-rw-r--r--winsup/cygwin/flock.cc14
4 files changed, 35 insertions, 7 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index e12bd85c9..e82125c1f 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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.
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index ffbd02ffa..9ba286ec0 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -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
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 465924190..4995d15b2 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -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)));
diff --git a/winsup/cygwin/flock.cc b/winsup/cygwin/flock.cc
index 72b9ef447..92b03d51e 100644
--- a/winsup/cygwin/flock.cc
+++ b/winsup/cygwin/flock.cc
@@ -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);