From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#70221: [PATCH] New function `funcall-later` Date: Sat, 06 Apr 2024 18:07:04 +0300 Message-ID: <864jce34yv.fsf@gnu.org> References: <86zfu73smn.fsf@gnu.org> Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="35157"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 70221@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Apr 06 17:08:30 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 1rt7ef-0008z7-SM for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 06 Apr 2024 17:08:30 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rt7eL-0003VH-Jo; Sat, 06 Apr 2024 11:08:09 -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 1rt7e9-0003UI-Ey for bug-gnu-emacs@gnu.org; Sat, 06 Apr 2024 11:07:59 -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 1rt7e7-0002SF-VK for bug-gnu-emacs@gnu.org; Sat, 06 Apr 2024 11:07:57 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1rt7eE-00029N-5L for bug-gnu-emacs@gnu.org; Sat, 06 Apr 2024 11:08:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 06 Apr 2024 15:08:02 +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.17124160437959 (code B ref 70221); Sat, 06 Apr 2024 15:08:02 +0000 Original-Received: (at 70221) by debbugs.gnu.org; 6 Apr 2024 15:07:23 +0000 Original-Received: from localhost ([127.0.0.1]:40602 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rt7db-00024J-0X for submit@debbugs.gnu.org; Sat, 06 Apr 2024 11:07:23 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:49436) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rt7dX-00023V-DS for 70221@debbugs.gnu.org; Sat, 06 Apr 2024 11:07:21 -0400 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rt7dL-0002NZ-5H; Sat, 06 Apr 2024 11:07:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=MpdwlovkcWz+gSREVDijjZWcs7lkcJVEhEAZI664f84=; b=g58y6U24mQba udyejqf5KhbOBWRjiBcI5uxre61JDXdg5Swxdqu2Wk2bUhMlLhkiI+Q06rlQmrsNV8amc6AjmBT7M wXeWb1dWV5/BbqlYtMeaIegZwKcQAejAPVF9/zh6k92zB6rcR7vG4EPL1yDTWUuQrTRNxr0hzs9cJ uGANWn8sT146ELjH9PFN3TBD8FtsVwCt7O0Ao9+H7VuhlRtyJ8hJJVGzl+OVtGtQ4YBe5YvK1nbZ1 LECjiwRcg5jmvOhy0Mjjln6+D28NqY5pKfotMUg4bUdhsnYnj5CYVHnBaYATWqqYolSgbQis2gJ1a CP3Jl6i6XXE+E9BFStnh+Q==; In-Reply-To: (message from Stefan Monnier on Sat, 06 Apr 2024 10:33:05 -0400) 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:282799 Archived-At: > From: Stefan Monnier > Cc: 70221@debbugs.gnu.org > Date: Sat, 06 Apr 2024 10:33:05 -0400 > > >> +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. timer-event-handler uses condition-case-unless-debug, so I don't see a problem with timers, and I think your use of safe_call2 was not 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`. Because it will prevent timers from being called? > > 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`? >From my POV, any code that runs from some background facility must inhibit QUIT, because the user can type C-g at any moment. > > 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". I don't think it's a wise approach. You are converting several places to using this new facility, so the prudent thing, in a program as complex and devious as Emacs, is to keep compatibility even if our hubris tempts us to think we are smarter. Bitter experience has taught me that we are not smarter, so I now prefer humility instead. > > -- 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. I mean where we explain the differences between zero-delay timers and funcall-later. We _will_ explain those, right? > >> 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? In the same place, see above, where we compare those two features. > 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`". Not "out of the blue", but in the context of explaining how it is different (which is important for Lisp programmers to decide which one to use in what situations), it is reasonable. > > 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. I don't think I disagree with what you write, but I fail to see how it is relevant to the need to explain better what is that "next convenient time" when the function will run. In particular, I don't see how the different uses of funcall-later affect that "next convenient time".