mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-28 03:27:46 +08:00
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 _so_passcred; /* SO_PASSCRED */
|
||||||
LONG _reuseaddr; /* dummy */
|
LONG _reuseaddr; /* dummy */
|
||||||
int _type; /* socket type */
|
int _type; /* socket type */
|
||||||
|
LONG _ndesc; /* number of open descriptors */
|
||||||
sun_name_t _sun_path;
|
sun_name_t _sun_path;
|
||||||
sun_name_t _peer_sun_path;
|
sun_name_t _peer_sun_path;
|
||||||
struct ucred _sock_cred; /* filled at listen time */
|
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; }
|
void set_socket_type (int val) { _type = val; }
|
||||||
int get_socket_type () const { return _type; }
|
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)
|
void sun_path (struct sockaddr_un *un, __socklen_t unlen)
|
||||||
{ _sun_path.set (un, unlen); }
|
{ _sun_path.set (un, unlen); }
|
||||||
void peer_sun_path (struct sockaddr_un *un, __socklen_t 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 (); }
|
int reuseaddr () const { return shmem->reuseaddr (); }
|
||||||
void set_socket_type (int val) { shmem->set_socket_type (val); }
|
void set_socket_type (int val) { shmem->set_socket_type (val); }
|
||||||
int get_socket_type () const { return shmem->get_socket_type (); }
|
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 create_shmem ();
|
||||||
int reopen_shmem ();
|
int reopen_shmem ();
|
||||||
|
@ -1122,6 +1122,7 @@ fhandler_socket_unix::fixup_helper ()
|
|||||||
connect_wait_thr = NULL;
|
connect_wait_thr = NULL;
|
||||||
cwt_termination_evt = NULL;
|
cwt_termination_evt = NULL;
|
||||||
cwt_param = NULL;
|
cwt_param = NULL;
|
||||||
|
inc_ndesc ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== public methods ========================= */
|
/* ========================== public methods ========================= */
|
||||||
@ -1209,6 +1210,7 @@ fhandler_socket_unix::dup (fhandler_base *child, int flags)
|
|||||||
fhs->connect_wait_thr = NULL;
|
fhs->connect_wait_thr = NULL;
|
||||||
fhs->cwt_termination_evt = NULL;
|
fhs->cwt_termination_evt = NULL;
|
||||||
fhs->cwt_param = NULL;
|
fhs->cwt_param = NULL;
|
||||||
|
inc_ndesc ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1285,6 +1287,7 @@ fhandler_socket_unix::socket (int af, int type, int protocol, int flags)
|
|||||||
set_handle (NULL);
|
set_handle (NULL);
|
||||||
set_unique_id ();
|
set_unique_id ();
|
||||||
set_ino (get_unique_id ());
|
set_ino (get_unique_id ());
|
||||||
|
inc_ndesc ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1753,10 +1756,11 @@ fhandler_socket_unix::close ()
|
|||||||
ret = mq_close (get_mqd_in ());
|
ret = mq_close (get_mqd_in ());
|
||||||
if (get_mqd_out () != (mqd_t) -1)
|
if (get_mqd_out () != (mqd_t) -1)
|
||||||
ret |= mq_close (get_mqd_out ());
|
ret |= mq_close (get_mqd_out ());
|
||||||
/* FIXME: Maybe we should keep a reference count on the mqueues and
|
if (dec_ndesc () <= 0)
|
||||||
unlink it after the last one is close. OTOH, this will become
|
{
|
||||||
unnecessary if the mqueue implementation is changed to use
|
shutdown (SHUT_RDWR);
|
||||||
Windows shared memory. */
|
mq_unlink (get_mqueue_name ());
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user