From 11628dd9312f355c7ff84e47bd1a0a60eccded80 Mon Sep 17 00:00:00 2001 From: WebFreak001 Date: Sat, 12 Nov 2022 04:49:45 +0100 Subject: [PATCH] make sure all request types await responses On OSX ARM accepting sockets would fail because the sender side (dcd-client) was generating, sending the whole packet and closing the socket faster than phobos was with accepting the socket, causing an exception in setOption inside socket.accept, which is now commented in the code as well. --- src/dcd/client/client.d | 9 ++++++--- src/dcd/server/main.d | 41 ++++++++++++++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/dcd/client/client.d b/src/dcd/client/client.d index 714f6f3..6d7ae01 100644 --- a/src/dcd/client/client.d +++ b/src/dcd/client/client.d @@ -151,7 +151,9 @@ int runClient(string[] args) request.kind = RequestKind.clearCache; Socket socket = createSocket(socketFile, port); scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } - return sendRequest(socket, request) ? 0 : 1; + if (!sendRequest(socket, request)) + return 1; + return getResponse(socket).completionType == "ack" ? 0 : 2; } else if (addedImportPaths.length > 0 || removedImportPaths.length > 0) { @@ -165,7 +167,7 @@ int runClient(string[] args) scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } if (!sendRequest(socket, request)) return 1; - return 0; + return getResponse(socket).completionType == "ack" ? 0 : 2; } } else if (listImports) @@ -173,7 +175,8 @@ int runClient(string[] args) request.kind |= RequestKind.listImports; Socket socket = createSocket(socketFile, port); scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } - sendRequest(socket, request); + if (!sendRequest(socket, request)) + return 1; AutocompleteResponse response = getResponse(socket); printImportList(response); return 0; diff --git a/src/dcd/server/main.d b/src/dcd/server/main.d index 94e19be..bbc29fc 100644 --- a/src/dcd/server/main.d +++ b/src/dcd/server/main.d @@ -197,7 +197,19 @@ int runServer(string[] args) serverLoop: while (true) { - auto s = socket.accept(); + Socket s; + try + { + s = socket.accept(); + } + catch (SocketOSException e) + { + // happens on OSX when remote closes the connection before we finished accepting + // fails internally in phobos with it trying to set socket option SO_NOSIGPIPE with "Invalid argument" + // See https://bugs.gnunet.org/view.php?id=5825 + error("unexpected internal error while acceping"); + continue; + } s.blocking = true; if (useTCP) @@ -224,6 +236,11 @@ int runServer(string[] args) sw.reset(); sw.start(); + scope (exit) + { + sw.stop(); + info("Request processed in ", sw.peek); + } size_t messageLength; // bit magic! @@ -252,26 +269,33 @@ int runServer(string[] args) { info("Clearing cache."); cache.clear(); + s.trySendResponse(AutocompleteResponse.ack, "Could not reply ack"); + continue; } else if (request.kind & RequestKind.shutdown) { info("Shutting down."); + s.trySendResponse(AutocompleteResponse.ack, "Could not reply ack"); break serverLoop; } else if (request.kind & RequestKind.query) { - s.sendResponse(AutocompleteResponse.ack); + s.trySendResponse(AutocompleteResponse.ack, "Could not reply ack"); continue; } + bool needResponse; + if (request.kind & RequestKind.addImport) { cache.addImportPaths(request.importPaths); + needResponse = true; } if (request.kind & RequestKind.removeImport) { cache.removeImportPaths(request.importPaths); + needResponse = true; } if (request.kind & RequestKind.listImports) @@ -279,7 +303,7 @@ int runServer(string[] args) AutocompleteResponse response; response.importPaths = cache.getImportPaths().map!(a => cast() a).array(); info("Returning import path list"); - s.sendResponse(response); + s.trySendResponse(response, "Could not send import path list"); } else { @@ -289,12 +313,12 @@ int runServer(string[] args) && !request.sourceCode.length) { warning("Received a ", request.kind, " request without source code"); - s.sendResponse(AutocompleteResponse.init); + s.trySendResponse(AutocompleteResponse.init, "Could not send error response"); } else if (request.kind & RequestKind.autocomplete) { info("Getting completions"); - s.sendResponse(complete(request, cache)); + s.trySendResponse(complete(request, cache), "Could not get completions"); } else if (request.kind & RequestKind.doc) { @@ -304,13 +328,12 @@ int runServer(string[] args) else if (request.kind & RequestKind.symbolLocation) s.trySendResponse(findDeclaration(request, cache), "Could not get symbol location"); else if (request.kind & RequestKind.search) - s.sendResponse(symbolSearch(request, cache)); + s.trySendResponse(symbolSearch(request, cache), "Could not perform symbol search"); else if (request.kind & RequestKind.localUse) s.trySendResponse(findLocalUse(request, cache), "Couldnot find local usage"); + else if (needResponse) + s.trySendResponse(AutocompleteResponse.ack, "Could not send ack"); } - - sw.stop(); - info("Request processed in ", sw.peek); } return 0; }