From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Stefan Monnier via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#70221: [PATCH] New function `funcall-later` Date: Sat, 06 Apr 2024 10:33:05 -0400 Message-ID: References: <86zfu73smn.fsf@gnu.org> Reply-To: Stefan Monnier Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="12440"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: 70221@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Apr 06 16:34:19 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1rt77a-0002yt-R3 for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 06 Apr 2024 16:34:19 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rt77H-0006AE-49; Sat, 06 Apr 2024 10:33:59 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rt77G-000699-20 for bug-gnu-emacs@gnu.org; Sat, 06 Apr 2024 10:33:58 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rt77F-000153-Ph for bug-gnu-emacs@gnu.org; Sat, 06 Apr 2024 10:33:57 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1rt77L-0004kd-SD for bug-gnu-emacs@gnu.org; Sat, 06 Apr 2024 10:34:03 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Stefan Monnier Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 06 Apr 2024 14:34:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 70221 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 70221-submit@debbugs.gnu.org id=B70221.171241400518018 (code B ref 70221); Sat, 06 Apr 2024 14:34:03 +0000 Original-Received: (at 70221) by debbugs.gnu.org; 6 Apr 2024 14:33:25 +0000 Original-Received: from localhost ([127.0.0.1]:40550 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rt76j-0004gY-4T for submit@debbugs.gnu.org; Sat, 06 Apr 2024 10:33:25 -0400 Original-Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:62992) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rt76e-0004gH-Gi for 70221@debbugs.gnu.org; Sat, 06 Apr 2024 10:33:23 -0400 Original-Received: from pmg2.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id CC9A180C88; Sat, 6 Apr 2024 10:33:07 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1712413986; bh=Tf9qkDR88okm5en8tBQXr2tHGDNFn3qZ6GJOiOAkXAc=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=h7gHLNl6rNdvBHOoNx5rkEUa4xCtGqbEHqeoYfo0lmJjduQXMpP2sHiCmSgnNmMlh LtqWKszPjatcPqunftQ2Nt8wG1xyTsQdVxDAwXYgCJYAMtkVO84pLkFOI6PjkJi655 WZfLiNOTQsIimV7qy4c3ZyDkWfhh/pdhapjNrBtrwolU8LRLLhhw3PIdUmAxDw7xKx lfsIuhprqSL2zhSK/hXzN8WSVML59xttowztpLT8uFGvoSGLW7szF9IFS2SgcDJg2X SST5vVe6XutapWqCvPXgNAgFdshuPoq1Z0lVxcayN3gMl05fBrYaeiNyJChsKN4Kjy h31dSIW5x3ykw== Original-Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id 8C2DF8009D; Sat, 6 Apr 2024 10:33:06 -0400 (EDT) Original-Received: from pastel (unknown [45.72.201.215]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 634EC120568; Sat, 6 Apr 2024 10:33:06 -0400 (EDT) In-Reply-To: <86zfu73smn.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 06 Apr 2024 09:36:00 +0300") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:282797 Archived-At: >> +DEFUN ("internal--run-pending-funcalls", Frun_pending_funcalls, Srun_pending_funcalls, 0, 0, 0, >> + doc: /* Run the still pending `funcall-later'. */) >> + (void) >> +{ >> + while (CONSP (pending_funcalls) || CONSP (pending_funcalls_r)) >> + if (CONSP (pending_funcalls)) >> + { >> + Lisp_Object funcall = XCAR (pending_funcalls); >> + pending_funcalls = XCDR (pending_funcalls); >> + CALLN (Fapply, funcall); >> + } >> + else > > You are using CALLN here, whereas the previous implementation used > safe_calln. Is that intended? Calling Lisp in unsafe ways in that > place might not be a good idea. I found it annoying that the debugger isn't brought up when a bug occurs in such delayed evaluations. Note also the subsequent call to `timer-event-handler` uses `calln` rather than `safe_calln`, so I think my original use of `safe_call2` in commit 58555d8187f3425 was a mistake. I can't see any good reason why we'd need to protect the C code from non-local exits in `timer_check_2`. > You didn't even inhibit QUIT. I'm torn on this one: OT1H while the time at which the code is run is loosely specified, it's not really asynchronous: it's run the next time Emacs "waits", which is usually about the same time as `post-command-hook` (which does use `inhibit-quit`), so there doesn't seem to be a good justification for `inhibit-quit`. OTOH when the `funcall-later` is performed from asynchronous code (e.g. from a timer), then running the delayed function call without `inhibit-quit` ends up "hoisting" that code outside of its original `inhibit-quit` context. For users such as `track-changes.el`, `inhibit-quit` is not needed/desired. But indeed when I use it in `futur.el` it's common to call `funcall-later` from process filters and timers. Usually part of the purpose of `funcall-later` is to run the code in a different (dynamic) context, but maybe `funcall-later` should preserve `inhibit-quit`? > As another difference between run-with-time and this mechanism, the > former took care of preserving deactivate-mark around the call, wheres > funcall-later doesn't This is again because `run-with-time` is designed for the general case where the delay is not 0s, so the code will be run asynchronously, wheres `funcall-later` is designed for "different time but not async". > -- this is at least one difference that we > should document (assuming we want it). AFAICT we don't document anywhere that `deactive-mark` is bound around timers, so I guess fixing that would be the best way to document the difference. >> No: beside the fact that they are run at slightly different times >> (which might be OK), `funcall-later` doesn't return a handle you can >> then use to cancel the call. > This should be mentioned in the documentation. How/where? Maybe the doc can just say that it returns nil? Other than that, it would seem odd to write something like "There is no `cancel-funcall-later`". > Thanks. We should document this in the ELisp manual, and should > explain there the meaning of "at the next convenient time". (I think > "convenient" here is very much misleading and thus inappropriate.) That's the big question, really. E.g. I currently use `funcall-later` in `track-changes.el` and in `futur.el`. I use it because it's handy. But fundamentally those two need different things: - `track-changes.el` uses `funcall-later` because it wants to delay the execution in order to combine the current buffer modification with potential soon-to-come buffer modifications. - `futur.el` uses `funcall-later` to "wake up" a piece of code that was waiting for the current event. In this case it uses `funcall-later` not because it wants to delay execution but because it wants that execution to be unaffected by the current dynamic scoping and it doesn't want that execution to block the current execution. So, if we were to change `funcall-later` so that the code gets run more promptly (e.g. via true concurrency [ let's pretend that this was actually possible and that the race-condition problems were magically solved somehow ]), it would be great for `futur.el` but would defeat the purpose for `track-changes.el`. Current users of `funcall-later` (well: of its underlying mechanism): - We use it in `comp.c` to launch the "jit" compilation of a package. - We use it in `frame.c` and `terminal.c` to run `(after-)delete-frame-functions` and `delete-terminal-functions` when the current context does not allow running ELisp. These are more like `futur.el` in the sense that the main purpose is to run the code in a different context, without blocking the current execution. Stefan