libphobos: Merge phobos upstream 6c9fb28b0
authorIain Buclaw <ibuclaw@gcc.gnu.org>
Sun, 10 Feb 2019 14:27:17 +0000 (14:27 +0000)
committerIain Buclaw <ibuclaw@gcc.gnu.org>
Sun, 10 Feb 2019 14:27:17 +0000 (14:27 +0000)
Fixes a thread deadlock that occurs in the test runner if libcurl is
missing.

Library fix for https://gcc.gnu.org/PR88654

Reviewed-on: https://github.com/dlang/phobos/pull/6824

From-SVN: r268746

libphobos/src/MERGE
libphobos/src/std/net/curl.d

index eee413903c013a9175b1ccf2ce8837cce2a0ef9f..aef240e0722db29f96f84f35838d2991e6acfcd2 100644 (file)
@@ -1,4 +1,4 @@
-d4933a90b1e8446c04d64cd044658f2b33250bd3
+6c9fb28b0f8813d41798202a9d19c6b37ba5da5f
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/phobos repository.
index 9d751411705e68f70be3d78fdd9dc91906fef7db..e3ce527c30314d1dd0d4d2717bed8107348943ea 100644 (file)
@@ -178,7 +178,7 @@ version (unittest)
     import std.range;
     import std.stdio;
 
-    import std.socket : Address, INADDR_LOOPBACK, Socket, TcpSocket;
+    import std.socket : Address, INADDR_LOOPBACK, Socket, SocketShutdown, TcpSocket;
 
     private struct TestServer
     {
@@ -192,6 +192,7 @@ version (unittest)
     private:
         string _addr;
         Tid tid;
+        TcpSocket sock;
 
         static void loop(shared TcpSocket listener)
         {
@@ -215,20 +216,34 @@ version (unittest)
 
     private TestServer startServer()
     {
+        tlsInit = true;
         auto sock = new TcpSocket;
         sock.bind(new InternetAddress(INADDR_LOOPBACK, InternetAddress.PORT_ANY));
         sock.listen(1);
         auto addr = sock.localAddress.toString();
         auto tid = spawn(&TestServer.loop, cast(shared) sock);
-        return TestServer(addr, tid);
+        return TestServer(addr, tid, sock);
     }
 
+    __gshared TestServer server;
+    bool tlsInit;
+
     private ref TestServer testServer()
     {
-        __gshared TestServer server;
         return initOnce!server(startServer());
     }
 
+    static ~this()
+    {
+        // terminate server from a thread local dtor of the thread that started it,
+        //  because thread_joinall is called before shared module dtors
+        if (tlsInit && server.sock)
+        {
+            server.sock.shutdown(SocketShutdown.RECEIVE);
+            server.sock.close();
+        }
+    }
+
     private struct Request(T)
     {
         string hdrs;
@@ -429,7 +444,11 @@ if (isCurlConn!Conn)
             s.send(httpOK("Hello world"));
         });
         auto fn = std.file.deleteme;
-        scope (exit) std.file.remove(fn);
+        scope (exit)
+        {
+            if (std.file.exists(fn))
+                std.file.remove(fn);
+        }
         download(host, fn);
         assert(std.file.readText(fn) == "Hello world");
     }
@@ -491,7 +510,11 @@ if (isCurlConn!Conn)
     foreach (host; [testServer.addr, "http://"~testServer.addr])
     {
         auto fn = std.file.deleteme;
-        scope (exit) std.file.remove(fn);
+        scope (exit)
+        {
+            if (std.file.exists(fn))
+                std.file.remove(fn);
+        }
         std.file.write(fn, "upload data\n");
         testServer.handle((s) {
             auto req = s.recvReq;