Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@luhenry
Created January 26, 2018 14:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luhenry/145e9e9d2f8ff881417e456a57021248 to your computer and use it in GitHub Desktop.
Save luhenry/145e9e9d2f8ff881417e456a57021248 to your computer and use it in GitHub Desktop.
diff --git a/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs b/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs
index a7fb500cd3e..a163eb94850 100755
--- a/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs
+++ b/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs
@@ -2879,6 +2879,37 @@ namespace MonoTests.System.Net.Sockets
Assert.IsFalse (CWRReceiving);
}
+ [Test]
+ public void CloseAndOpenWhileReceiving ()
+ {
+ CWRSocket = new Socket (AddressFamily.InterNetwork,
+ SocketType.Dgram,
+ ProtocolType.Udp);
+ CWRSocket.Bind (new IPEndPoint (IPAddress.Loopback,
+ 1256));
+
+ Thread recv_thread = new Thread (new ThreadStart (CWRReceiveThread));
+ CWRReady.Reset ();
+ recv_thread.Start ();
+ Thread.Sleep (250); /* Wait for the thread to be already receiving */
+
+ /* Close the socket and immediately reopen it,
+ * so that the new one is likely to get the
+ * same file descriptor as the old one. */
+ CWRSocket.Close ();
+ CWRSocket = new Socket (AddressFamily.InterNetwork,
+ SocketType.Dgram,
+ ProtocolType.Udp);
+ try {
+ if (CWRReady.WaitOne (2000, false) == false) {
+ Assert.Fail ("CloseAndOpenWhileReceiving wait timed out");
+ }
+ Assert.IsFalse (CWRReceiving);
+ } finally {
+ CWRSocket.Close();
+ }
+ }
+
static bool RRCLastRead = false;
static ManualResetEvent RRCReady = new ManualResetEvent (false);
diff --git a/mono/metadata/w32socket-unix.c b/mono/metadata/w32socket-unix.c
index d675b53e66a..c0e890acd53 100644
--- a/mono/metadata/w32socket-unix.c
+++ b/mono/metadata/w32socket-unix.c
@@ -105,6 +105,8 @@ retry_close:
goto retry_close;
}
+ fprintf (stderr, "0x%lx closed %d\n", pthread_self(), ((MonoFDHandle*) sockethandle)->fd);
+
sockethandle->saved_error = 0;
}
@@ -304,6 +306,7 @@ mono_w32socket_recvfrom (SOCKET sock, char *buf, int len, int flags, struct sock
SocketHandle *sockethandle;
int ret;
MonoThreadInfo *info;
+ pthread_t tid = pthread_self ();
if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
mono_w32error_set_last (WSAENOTSOCK);
@@ -319,11 +322,22 @@ mono_w32socket_recvfrom (SOCKET sock, char *buf, int len, int flags, struct sock
info = mono_thread_info_current ();
do {
+ /*
+ * We're unlucky and the scheduler decides that right
+ * now something else should run :(
+ */
+ fprintf (stderr, "0x%lx sleeping on %d...\n", tid, ((MonoFDHandle*) sockethandle)->fd);
+ usleep(500 * 1000);
+
+ fprintf (stderr, "0x%lx receiving on %d...\n", tid, ((MonoFDHandle*) sockethandle)->fd);
+
MONO_ENTER_GC_SAFE;
ret = recvfrom (((MonoFDHandle*) sockethandle)->fd, buf, len, flags, from, fromlen);
MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR && !mono_thread_info_is_interrupt_state (info));
+ fprintf (stderr, "0x%lx received on %d (%d)\n", tid, ((MonoFDHandle*) sockethandle)->fd, ret);
+
if (ret == 0 && len > 0) {
/* According to the Linux man page, recvfrom only
* returns 0 when the socket has been shut down
@@ -687,6 +701,9 @@ retry_socket:
MONO_ENTER_GC_SAFE;
fd = socket (domain, type, protocol);
MONO_EXIT_GC_SAFE;
+
+ fprintf (stderr, "0x%lx socket %d\n", pthread_self (), fd);
+
if (fd == -1) {
if (domain == AF_INET && type == SOCK_RAW && protocol == 0) {
/* Retry with protocol == 4 (see bug #54565) */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment