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:
authorKen Brown <kbrown@cornell.edu>2021-05-18 00:18:45 +0300
committerKen Brown <kbrown@cornell.edu>2021-06-04 19:36:46 +0300
commit7720ea9679e9c0952edee5aaa3bd4d77e4cbbd33 (patch)
treeed9516745c380f3f96681e56295cd230b94d1f21
parent6172419ed2bc64c6ac3972ab05f17ac3d2952baf (diff)
Cygwin: AF_UNIX: keep a reference count of open descriptors
Add a data member _ndesc to the af_unix_shmem_t class, along with methods to increment and decrement it. Increment it during socket/fork/exec/dup, and decrement it during close. When the last descriptor is closed, call shutdown (SHUT_RDWR) and unlink the socket's message queue. The shutdown call will make the socket's peer see EPIPE if it tries to write.
-rw-r--r--winsup/cygwin/fhandler.h6
-rw-r--r--winsup/cygwin/fhandler_socket_unix.cc12
2 files changed, 14 insertions, 4 deletions
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index e608551b3..45d622deb 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -956,6 +956,7 @@ class af_unix_shmem_t
LONG _so_passcred; /* SO_PASSCRED */
LONG _reuseaddr; /* dummy */
int _type; /* socket type */
+ LONG _ndesc; /* number of open descriptors */
sun_name_t _sun_path;
sun_name_t _peer_sun_path;
struct ucred _sock_cred; /* filled at listen time */
@@ -997,6 +998,9 @@ class af_unix_shmem_t
void set_socket_type (int val) { _type = val; }
int get_socket_type () const { return _type; }
+ LONG inc_ndesc () { return InterlockedIncrement (&_ndesc); }
+ LONG dec_ndesc () { return InterlockedDecrement (&_ndesc); }
+
void sun_path (struct sockaddr_un *un, __socklen_t unlen)
{ _sun_path.set (un, unlen); }
void peer_sun_path (struct sockaddr_un *un, __socklen_t unlen)
@@ -1076,6 +1080,8 @@ class fhandler_socket_unix : public fhandler_socket
int reuseaddr () const { return shmem->reuseaddr (); }
void set_socket_type (int val) { shmem->set_socket_type (val); }
int get_socket_type () const { return shmem->get_socket_type (); }
+ LONG inc_ndesc () { return shmem->inc_ndesc (); }
+ LONG dec_ndesc () { return shmem->dec_ndesc (); }
int create_shmem ();
int reopen_shmem ();
diff --git a/winsup/cygwin/fhandler_socket_unix.cc b/winsup/cygwin/fhandler_socket_unix.cc
index 109cad4ba..6071061af 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -1122,6 +1122,7 @@ fhandler_socket_unix::fixup_helper ()
connect_wait_thr = NULL;
cwt_termination_evt = NULL;
cwt_param = NULL;
+ inc_ndesc ();
}
/* ========================== public methods ========================= */
@@ -1209,6 +1210,7 @@ fhandler_socket_unix::dup (fhandler_base *child, int flags)
fhs->connect_wait_thr = NULL;
fhs->cwt_termination_evt = NULL;
fhs->cwt_param = NULL;
+ inc_ndesc ();
return 0;
}
@@ -1285,6 +1287,7 @@ fhandler_socket_unix::socket (int af, int type, int protocol, int flags)
set_handle (NULL);
set_unique_id ();
set_ino (get_unique_id ());
+ inc_ndesc ();
return 0;
}
@@ -1753,10 +1756,11 @@ fhandler_socket_unix::close ()
ret = mq_close (get_mqd_in ());
if (get_mqd_out () != (mqd_t) -1)
ret |= mq_close (get_mqd_out ());
- /* FIXME: Maybe we should keep a reference count on the mqueues and
- unlink it after the last one is close. OTOH, this will become
- unnecessary if the mqueue implementation is changed to use
- Windows shared memory. */
+ if (dec_ndesc () <= 0)
+ {
+ shutdown (SHUT_RDWR);
+ mq_unlink (get_mqueue_name ());
+ }
return ret;
}