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.
This commit is contained in:
parent
6172419ed2
commit
7720ea9679
|
@ -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 ();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue