From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alain Schneble Newsgroups: gmane.emacs.devel Subject: Re: Asynchronous DNS Date: Mon, 15 Feb 2016 01:02:07 +0100 Message-ID: <86oabi6dts.fsf@realize.ch> References: <86mvrdmk8p.fsf@realize.ch> <877fihjo4m.fsf@gnus.org> <86io20n3xn.fsf@realize.ch> <8760y055l1.fsf@gnus.org> <8660xzmyyr.fsf@realize.ch> <87pow7ocyw.fsf@gnus.org> <861t8nmxlj.fsf@realize.ch> <87y4auiurw.fsf@gnus.org> <86k2me8dee.fsf@realize.ch> <83a8n9ddk5.fsf@gnu.org> <864mdh8vj5.fsf@realize.ch> <87pow579kt.fsf@gnus.org> <86ziv87st0.fsf@realize.ch> <87vb5u4qtq.fsf@gnus.org> <86egci6xvk.fsf@realize.ch> <87twldgsrv.fsf@gnus.org> <8637sw7w4m.fsf@realize.ch> <87vb5sdod6.fsf@gnus.org> <83lh6nzvfp.fsf@gnu.org> <87fuwv6ai4.fsf@gnus.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: ger.gmane.org 1455494606 11980 80.91.229.3 (15 Feb 2016 00:03:26 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 15 Feb 2016 00:03:26 +0000 (UTC) Cc: Eli Zaretskii , emacs-devel@gnu.org To: Lars Ingebrigtsen Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Feb 15 01:03:20 2016 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1aV6dM-0003ww-F6 for ged-emacs-devel@m.gmane.org; Mon, 15 Feb 2016 01:03:20 +0100 Original-Received: from localhost ([::1]:54651 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aV6dL-0002fF-Lq for ged-emacs-devel@m.gmane.org; Sun, 14 Feb 2016 19:03:19 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:44662) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aV6d2-0002dX-Tg for emacs-devel@gnu.org; Sun, 14 Feb 2016 19:03:04 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aV6cy-0005KK-RQ for emacs-devel@gnu.org; Sun, 14 Feb 2016 19:03:00 -0500 Original-Received: from clientmail.realize.ch ([46.140.89.53]:3134) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1aV6ct-0005Jr-8B; Sun, 14 Feb 2016 19:02:51 -0500 Original-Received: from rintintin.hq.realize.ch.lan.rit ([192.168.0.105]) by clientmail.realize.ch ; Mon, 15 Feb 2016 01:02:41 +0100 Original-Received: from MYNGB (192.168.66.64) by rintintin.hq.realize.ch.lan.rit (192.168.0.105) with Microsoft SMTP Server (TLS) id 15.0.516.32; Mon, 15 Feb 2016 01:02:16 +0100 In-Reply-To: <87fuwv6ai4.fsf@gnus.org> (Lars Ingebrigtsen's message of "Sun, 14 Feb 2016 18:01:39 +1100") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (windows-nt) X-ClientProxiedBy: rintintin.hq.realize.ch.lan.rit (192.168.0.105) To rintintin.hq.realize.ch.lan.rit (192.168.0.105) X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] X-Received-From: 46.140.89.53 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:199943 Archived-At: --=-=-= Content-Type: text/plain Lars Ingebrigtsen writes: > The issue is losing asynchronicity. A function that previously called > > (progn > (make-network-stream ... :nowait t) > (set-process-coding-system ...)) > > would not block. With the proposed blockers (unless we add fine-grained > code to all the process function to only block if we haven't even done > DNS yet), this code will block. And that's a regression. By the way, I tried it out with the fine-grained approach. See patch below. The majority of the functions touched will block if DNS requests are still pending. process-send-* functions block while process is in "connect" state. I didn't have time to verify it with TLS connections though, and also just very quickly with http connections and some hand crafted scenarios... > But, I mean, we could examine all these process functions and only have > them block where we need them to, and things would work fine. I don't > really have much confidence in us being able to do so completely > transparently, though. There is potential to refactor at least two functions, set-process-coding-system and set-process-window-size, to not require blocking at all. The former will require adaptions in set_network_socket_coding_system, to check whether coding systems have already been set, so that they do not get overwritten, e.g. in this scenario: (progn (make-network-stream ... :nowait t) (set-process-coding-system ...)) And set-process-coding-system could just jump over the call to setup_process_coding_systems in case of a network process with pending DNS requests (i.e. socket not yet available). While with set-process-window-size, I asked myself if this one makes any sense with network processes at all. Should it signal an error or what would be the use case to call this for a network process? And here is the small patch I used: --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename="0001-Make-process-functions-wait-for-DNS-completion.patch" Content-Description: Patch -- Make-process-functions-wait-for-DNS-completion >From 1ceb2e58aa1a7d688439aa9e4c0ed11fb0e50534 Mon Sep 17 00:00:00 2001 From: Alain Schneble Date: Mon, 15 Feb 2016 00:11:06 +0100 Subject: [PATCH] Make process functions wait for DNS completion * src/process.c (set-process-filter, set-process-window-size, process-contact, process-datagram-address, set-process-datagram-address, set-network-process-option): make functions wait (block) on network process until pending DNS requests have been processed and associated socket initialized. * src/process.c (process-send-region, process-send-string, process-send-eof): make functions wait (block) while network process is in connect state. --- src/process.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 7 deletions(-) diff --git a/src/process.c b/src/process.c index 497b069..9816e93 100644 --- a/src/process.c +++ b/src/process.c @@ -284,6 +284,7 @@ static Lisp_Object chan_process[FD_SETSIZE]; #ifdef HAVE_GETADDRINFO_A /* Pending DNS requests. */ static Lisp_Object dns_processes; +static void wait_for_socket_fds (Lisp_Object process); #endif /* Alist of elements (NAME . PROCESS). */ @@ -1029,6 +1030,12 @@ The string argument is normally a multibyte string, except: struct Lisp_Process *p; CHECK_PROCESS (process); + +#ifdef HAVE_GETADDRINFO_A + if (NETCONN_P (process)) + wait_for_socket_fds (process); +#endif + p = XPROCESS (process); /* Don't signal an error if the process's input file descriptor @@ -1113,6 +1120,11 @@ DEFUN ("set-process-window-size", Fset_process_window_size, { CHECK_PROCESS (process); +#ifdef HAVE_GETADDRINFO_A + if (NETCONN_P (process)) + wait_for_socket_fds (process); +#endif + /* All known platforms store window sizes as 'unsigned short'. */ CHECK_RANGED_INTEGER (height, 0, USHRT_MAX); CHECK_RANGED_INTEGER (width, 0, USHRT_MAX); @@ -1194,6 +1206,12 @@ list of keywords. */) contact = XPROCESS (process)->childp; #ifdef DATAGRAM_SOCKETS + +#ifdef HAVE_GETADDRINFO_A + if (NETCONN_P (process)) + wait_for_socket_fds (process); +#endif + if (DATAGRAM_CONN_P (process) && (EQ (key, Qt) || EQ (key, QCremote))) contact = Fplist_put (contact, QCremote, @@ -2423,6 +2441,11 @@ DEFUN ("process-datagram-address", Fprocess_datagram_address, Sprocess_datagram_ CHECK_PROCESS (process); +#ifdef HAVE_GETADDRINFO_A + if (NETCONN_P (process)) + wait_for_socket_fds (process); +#endif + if (!DATAGRAM_CONN_P (process)) return Qnil; @@ -2442,6 +2465,11 @@ Returns nil upon error setting address, ADDRESS otherwise. */) CHECK_PROCESS (process); +#ifdef HAVE_GETADDRINFO_A + if (NETCONN_P (process)) + wait_for_socket_fds (process); +#endif + if (!DATAGRAM_CONN_P (process)) return Qnil; @@ -2610,6 +2638,10 @@ OPTION is not a supported option, return nil instead; otherwise return t. */) if (!NETCONN1_P (p)) error ("Process is not a network process"); +#ifdef HAVE_GETADDRINFO_A + wait_for_socket_fds (process); +#endif + s = p->infd; if (s < 0) error ("Process is not running"); @@ -3693,7 +3725,7 @@ usage: (make-network-process &rest ARGS) */) #endif #ifdef HAVE_GETADDRINFO_A - if (EQ (Fplist_get (contact, QCnowait), Qdns) && + if (EQ (Fplist_get (contact, QCnowait), Qt) && !NILP (host)) { int ret; @@ -4650,6 +4682,24 @@ check_for_dns (Lisp_Object proc) return ip_addresses; } + +static void +wait_for_socket_fds(Lisp_Object process) +{ + while (XPROCESS(process)->dns_requests) + { + wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0); + } +} + +static void +wait_while_connecting(Lisp_Object process) +{ + while (EQ (Qconnect, XPROCESS(process)->status)) + { + wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0); + } +} #endif /* HAVE_GETADDRINFO_A */ /* This variable is different from waiting_for_input in keyboard.c. @@ -6143,6 +6193,11 @@ Output from processes can arrive in between bunches. */) if (XINT (start) < GPT && XINT (end) > GPT) move_gap_both (XINT (start), start_byte); +#ifdef HAVE_GETADDRINFO_A + if (NETCONN_P (proc)) + wait_while_connecting (proc); +#endif + send_process (proc, (char *) BYTE_POS_ADDR (start_byte), end_byte - start_byte, Fcurrent_buffer ()); @@ -6162,6 +6217,12 @@ Output from processes can arrive in between bunches. */) Lisp_Object proc; CHECK_STRING (string); proc = get_process (process); + +#ifdef HAVE_GETADDRINFO_A + if (NETCONN_P (proc)) + wait_while_connecting (proc); +#endif + send_process (proc, SSDATA (string), SBYTES (string), string); return Qnil; @@ -6576,10 +6637,17 @@ process has been transmitted to the serial port. */) struct coding_system *coding = NULL; int outfd; - if (DATAGRAM_CONN_P (process)) + proc = get_process (process); + +#ifdef HAVE_GETADDRINFO_A + if (NETCONN_P (proc)) + wait_while_connecting (proc); +#endif + + if (DATAGRAM_CONN_P (proc)) return process; - proc = get_process (process); + outfd = XPROCESS (proc)->outfd; if (outfd >= 0) coding = proc_encode_coding_system[outfd]; @@ -7030,7 +7098,14 @@ encode subprocess input. */) register struct Lisp_Process *p; CHECK_PROCESS (process); + +#ifdef HAVE_GETADDRINFO_A + if (NETCONN_P (process)) + wait_for_socket_fds (process); +#endif + p = XPROCESS (process); + if (p->infd < 0) error ("Input file descriptor of %s closed", SDATA (p->name)); if (p->outfd < 0) @@ -7067,6 +7142,12 @@ suppressed. */) register struct Lisp_Process *p; CHECK_PROCESS (process); + +#ifdef HAVE_GETADDRINFO_A + if (NETCONN_P (process)) + wait_for_socket_fds (process); +#endif + p = XPROCESS (process); if (NILP (flag)) pset_decode_coding_system @@ -7757,7 +7838,6 @@ syms_of_process (void) DEFSYM (QCcoding, ":coding"); DEFSYM (QCserver, ":server"); DEFSYM (QCnowait, ":nowait"); - DEFSYM (Qdns, "dns"); DEFSYM (QCsentinel, ":sentinel"); DEFSYM (QCtls_parameters, ":tls-parameters"); DEFSYM (QClog, ":log"); @@ -7921,9 +8001,6 @@ The variable takes effect when `start-process' is called. */); #ifdef NON_BLOCKING_CONNECT ADD_SUBFEATURE (QCnowait, Qt); -#ifdef HAVE_GETADDRINFO_A - ADD_SUBFEATURE (QCnowait, Qdns); -#endif #endif #ifdef DATAGRAM_SOCKETS ADD_SUBFEATURE (QCtype, Qdatagram); -- 2.6.2.windows.1 --=-=-=--