GNU bug report logs - #51094
Check if run-with{-idle,}-timer needs to create a timer

Previous Next

Package: emacs;

Reported by: Philip Kaludercic <philipk <at> posteo.net>

Date: Fri, 8 Oct 2021 09:37:02 UTC

Severity: normal

Tags: patch

Done: Philip Kaludercic <philipk <at> posteo.net>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 51094 in the body.
You can then email your comments to 51094 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#51094; Package emacs. (Fri, 08 Oct 2021 09:37:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Philip Kaludercic <philipk <at> posteo.net>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Fri, 08 Oct 2021 09:37:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Philip Kaludercic <philipk <at> posteo.net>
To: bug-gnu-emacs <at> gnu.org
Subject: Check if run-with{-idle,}-timer needs to create a timer
Date: Fri, 08 Oct 2021 09:36:22 +0000
[Message part 1 (text/plain, inline)]
Tags: patch


I have seen a few packages use run-with-timer or run-with-idle-timer,
where the SECS parameter is configurable with a user option. When this
timer doesn't repeat itself and it makes sense to set SECS to 0 when you
want something to run immediately, I don't think it makes sense to
create a timer object.

The following patch would remove this overhead, and calls the function
immediately if it makes sense.

Comparing these two test cases

--8<---------------cut here---------------start------------->8---
(benchmark-run-compiled 10000
  (funcall #'message "Test %s" "case"))

(benchmark-run-compiled 10000
  (run-with-timer 0 nil #'message "Test %s" "case"))
--8<---------------cut here---------------end--------------->8---

it turns out that funcall takes longer, but run-with-timer (or
run-with-idle-timer for that matter) block Emacs for significantly
longer.  Now this is a very forced example, because run-with-timer is
usually not called in a loop, but it do think it demonstrates a general
advantage.

In GNU Emacs 28.0.60 (build 6, x86_64-pc-linux-gnu, X toolkit, cairo version 1.16.0, Xaw scroll bars)
 of 2021-10-05 built on icterid
Repository revision: 1cd1b2835b5e35562c677c48dcf185bb73af4275
Repository branch: emacs-28
Windowing system distributor 'The X.Org Foundation', version 11.0.12011000
System Description: Debian GNU/Linux 11 (bullseye)

Configured using:
 'configure --with-native-compilation --with-x-toolkit=lucid
 --with-imagemagick 'CFLAGS=-O2 -march=native -pipe' LDFLAGS=-flto'

[0001-Avoid-creating-timer-if-possible.patch (text/patch, attachment)]
[Message part 3 (text/plain, inline)]
-- 
	Philip Kaludercic

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#51094; Package emacs. (Fri, 08 Oct 2021 10:47:01 GMT) Full text and rfc822 format available.

Message #8 received at 51094 <at> debbugs.gnu.org (full text, mbox):

From: "Basil L. Contovounesios" <contovob <at> tcd.ie>
To: Philip Kaludercic <philipk <at> posteo.net>
Cc: 51094 <at> debbugs.gnu.org
Subject: Re: bug#51094: Check if run-with{-idle,
 }-timer needs to create a timer
Date: Fri, 08 Oct 2021 11:46:00 +0100
Philip Kaludercic [2021-10-08 09:36 +0000] wrote:

> I have seen a few packages use run-with-timer or run-with-idle-timer,
> where the SECS parameter is configurable with a user option. When this
> timer doesn't repeat itself and it makes sense to set SECS to 0 when you
> want something to run immediately, I don't think it makes sense to
> create a timer object.

IIUC, the semantics of SECS=0 (alias nil) is not the same as eager
funcall, because timer functions are intended to be run asynchronously
in a separate command loop.  So often what is meant by "now" is e.g. "as
soon as I quit the current active minibuffer".

I realise this patch does not touch run-at-time, but it's documented as
being interchangeable with run-with-timer, so the eager funcall sounds
like a breaking change.

If packages indeed want to run something immediately, why create a timer
at all?  Or am I misunderstanding something?

Thanks,

-- 
Basil




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#51094; Package emacs. (Fri, 08 Oct 2021 10:54:02 GMT) Full text and rfc822 format available.

Message #11 received at 51094 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Philip Kaludercic <philipk <at> posteo.net>
Cc: "Basil L. Contovounesios" <contovob <at> tcd.ie>, 51094 <at> debbugs.gnu.org
Subject: Re: bug#51094: Check if run-with{-idle, }-timer needs to create a
 timer
Date: Fri, 08 Oct 2021 12:53:38 +0200
"Basil L. Contovounesios" via "Bug reports for GNU Emacs, the Swiss army
knife of text editors" <bug-gnu-emacs <at> gnu.org> writes:

> IIUC, the semantics of SECS=0 (alias nil) is not the same as eager
> funcall, because timer functions are intended to be run asynchronously
> in a separate command loop.  So often what is meant by "now" is e.g. "as
> soon as I quit the current active minibuffer".

Yes, the semantics of running things from a timer are different from
running them in the normal flow, so we can't transform 0-delay timers
into funcalls.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#51094; Package emacs. (Fri, 08 Oct 2021 11:04:02 GMT) Full text and rfc822 format available.

Message #14 received at 51094 <at> debbugs.gnu.org (full text, mbox):

From: Philip Kaludercic <philipk <at> posteo.net>
To: "Basil L. Contovounesios" <contovob <at> tcd.ie>
Cc: 51094 <at> debbugs.gnu.org
Subject: Re: bug#51094: Check if run-with{-idle,
 }-timer needs to create a timer
Date: Fri, 08 Oct 2021 11:03:18 +0000
"Basil L. Contovounesios" <contovob <at> tcd.ie> writes:


> Philip Kaludercic [2021-10-08 09:36 +0000] wrote:
>
>> I have seen a few packages use run-with-timer or run-with-idle-timer,
>> where the SECS parameter is configurable with a user option. When this
>> timer doesn't repeat itself and it makes sense to set SECS to 0 when you
>> want something to run immediately, I don't think it makes sense to
>> create a timer object.
>
> IIUC, the semantics of SECS=0 (alias nil) is not the same as eager
> funcall, because timer functions are intended to be run asynchronously
> in a separate command loop.  So often what is meant by "now" is e.g. "as
> soon as I quit the current active minibuffer".

I see, it might be necessary to consider examples where this might go
wrong.

> I realise this patch does not touch run-at-time, but it's documented as
> being interchangeable with run-with-timer, so the eager funcall sounds
> like a breaking change.
>
> If packages indeed want to run something immediately, why create a timer
> at all?  Or am I misunderstanding something?

Because you might want to delay certain things, such as highlighting or
completion. It makes sense on older devices, but modern systems can run
a lot of things immediately. Consider lazy-highlight-initial-delay or
the icomplete options. On my desktop I have no issue with setting
lazy-highlight-initial-delay to 0 but on my laptop I keep the default
value.

> Thanks,

-- 
	Philip Kaludercic




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#51094; Package emacs. (Fri, 08 Oct 2021 11:09:02 GMT) Full text and rfc822 format available.

Message #17 received at 51094 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Philip Kaludercic <philipk <at> posteo.net>
Cc: 51094 <at> debbugs.gnu.org
Subject: Re: bug#51094: Check if run-with{-idle,
 }-timer needs to create a timer
Date: Fri, 08 Oct 2021 14:08:03 +0300
> From: Philip Kaludercic <philipk <at> posteo.net>
> Date: Fri, 08 Oct 2021 09:36:22 +0000
> 
> I have seen a few packages use run-with-timer or run-with-idle-timer,
> where the SECS parameter is configurable with a user option. When this
> timer doesn't repeat itself and it makes sense to set SECS to 0 when you
> want something to run immediately, I don't think it makes sense to
> create a timer object.
> 
> The following patch would remove this overhead, and calls the function
> immediately if it makes sense.

I'm not sure we should care, but in any case, what you do there
requires a comment explaining the rationale.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#51094; Package emacs. (Fri, 08 Oct 2021 11:14:02 GMT) Full text and rfc822 format available.

Message #20 received at 51094 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: "Basil L. Contovounesios" <contovob <at> tcd.ie>
Cc: philipk <at> posteo.net, 51094 <at> debbugs.gnu.org
Subject: Re: bug#51094: Check if run-with{-idle,
 }-timer needs to create a timer
Date: Fri, 08 Oct 2021 14:13:10 +0300
> Cc: 51094 <at> debbugs.gnu.org
> Date: Fri, 08 Oct 2021 11:46:00 +0100
> From:  "Basil L. Contovounesios" via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> 
> Philip Kaludercic [2021-10-08 09:36 +0000] wrote:
> 
> > I have seen a few packages use run-with-timer or run-with-idle-timer,
> > where the SECS parameter is configurable with a user option. When this
> > timer doesn't repeat itself and it makes sense to set SECS to 0 when you
> > want something to run immediately, I don't think it makes sense to
> > create a timer object.
> 
> IIUC, the semantics of SECS=0 (alias nil) is not the same as eager
> funcall, because timer functions are intended to be run asynchronously
> in a separate command loop.  So often what is meant by "now" is e.g. "as
> soon as I quit the current active minibuffer".

Right, and that's one more aspect of this change to consider.  It
could very well change the behavior in incompatible ways, so I wonder
whether we really should make this change.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#51094; Package emacs. (Fri, 08 Oct 2021 11:15:02 GMT) Full text and rfc822 format available.

Message #23 received at 51094 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Philip Kaludercic <philipk <at> posteo.net>
Cc: "Basil L. Contovounesios" <contovob <at> tcd.ie>, 51094 <at> debbugs.gnu.org
Subject: Re: bug#51094: Check if run-with{-idle,
 }-timer needs to create a timer
Date: Fri, 08 Oct 2021 13:14:44 +0200
Lars Ingebrigtsen <larsi <at> gnus.org> writes:

> Yes, the semantics of running things from a timer are different from
> running them in the normal flow, so we can't transform 0-delay timers
> into funcalls.

See for instance:

  (when (> (minibuffer-depth) 0)
    ;; We're inside a minibuffer already, so if the emacs-client is trying
    ;; to open a frame on a new display, we might end up with an unusable
    ;; frame because input from that display will be blocked (until exiting
    ;; the minibuffer).  Better exit this minibuffer right away.
    (run-with-timer 0 nil (lambda () (server-execute-continuation proc)))

So this change is a no go.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#51094; Package emacs. (Fri, 08 Oct 2021 11:30:01 GMT) Full text and rfc822 format available.

Message #26 received at 51094 <at> debbugs.gnu.org (full text, mbox):

From: "Basil L. Contovounesios" <contovob <at> tcd.ie>
To: Philip Kaludercic <philipk <at> posteo.net>
Cc: 51094 <at> debbugs.gnu.org
Subject: Re: bug#51094: Check if run-with{-idle,
 }-timer needs to create a timer
Date: Fri, 08 Oct 2021 12:29:05 +0100
Philip Kaludercic [2021-10-08 11:03 +0000] wrote:

> "Basil L. Contovounesios" <contovob <at> tcd.ie> writes:
>> Philip Kaludercic [2021-10-08 09:36 +0000] wrote:
>>
>>> I have seen a few packages use run-with-timer or run-with-idle-timer,
>>> where the SECS parameter is configurable with a user option. When this
>>> timer doesn't repeat itself and it makes sense to set SECS to 0 when you
>>> want something to run immediately, I don't think it makes sense to
>>> create a timer object.
>>
>> IIUC, the semantics of SECS=0 (alias nil) is not the same as eager
>> funcall, because timer functions are intended to be run asynchronously
>> in a separate command loop.  So often what is meant by "now" is e.g. "as
>> soon as I quit the current active minibuffer".
>
> I see, it might be necessary to consider examples where this might go
> wrong.

Off the top of my head there's also ivy-quit-and-run in the ivy package,
but Lars pointed to effectively the same idiom.

>> I realise this patch does not touch run-at-time, but it's documented as
>> being interchangeable with run-with-timer, so the eager funcall sounds
>> like a breaking change.
>>
>> If packages indeed want to run something immediately, why create a timer
>> at all?  Or am I misunderstanding something?
>
> Because you might want to delay certain things, such as highlighting or
> completion.

What I meant is, the choice whether to run-with-timer or funcall can be
left to the calling package, since it knows better what it wants to do.

Thanks,

-- 
Basil




Reply sent to Philip Kaludercic <philipk <at> posteo.net>:
You have taken responsibility. (Fri, 08 Oct 2021 11:34:02 GMT) Full text and rfc822 format available.

Notification sent to Philip Kaludercic <philipk <at> posteo.net>:
bug acknowledged by developer. (Fri, 08 Oct 2021 11:34:02 GMT) Full text and rfc822 format available.

Message #31 received at 51094-close <at> debbugs.gnu.org (full text, mbox):

From: Philip Kaludercic <philipk <at> posteo.net>
To: Lars Ingebrigtsen <larsi <at> gnus.org>
Cc: "Basil L. Contovounesios" <contovob <at> tcd.ie>, 51094-close <at> debbugs.gnu.org
Subject: Re: bug#51094: Check if run-with{-idle,
 }-timer needs to create a timer
Date: Fri, 08 Oct 2021 11:33:27 +0000
Lars Ingebrigtsen <larsi <at> gnus.org> writes:

> Lars Ingebrigtsen <larsi <at> gnus.org> writes:
>
>> Yes, the semantics of running things from a timer are different from
>> running them in the normal flow, so we can't transform 0-delay timers
>> into funcalls.
>
> See for instance:
>
>   (when (> (minibuffer-depth) 0)
>     ;; We're inside a minibuffer already, so if the emacs-client is trying
>     ;; to open a frame on a new display, we might end up with an unusable
>     ;; frame because input from that display will be blocked (until exiting
>     ;; the minibuffer).  Better exit this minibuffer right away.
>     (run-with-timer 0 nil (lambda () (server-execute-continuation proc)))
>
> So this change is a no go.

Ok, that makes sense.

One last question, would it make sense to provide a function like
run-with-timer that would work like my patch?

-- 
	Philip Kaludercic




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#51094; Package emacs. (Fri, 08 Oct 2021 12:30:02 GMT) Full text and rfc822 format available.

Message #34 received at 51094 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Philip Kaludercic <philipk <at> posteo.net>
Cc: "Basil L. Contovounesios" <contovob <at> tcd.ie>, 51094 <at> debbugs.gnu.org
Subject: Re: bug#51094: Check if run-with{-idle,
 }-timer needs to create a timer
Date: Fri, 08 Oct 2021 14:29:23 +0200
Philip Kaludercic <philipk <at> posteo.net> writes:

> One last question, would it make sense to provide a function like
> run-with-timer that would work like my patch?

It sounds really specialised -- I don't think there'd be much point.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 06 Nov 2021 11:24:07 GMT) Full text and rfc822 format available.

This bug report was last modified 2 years and 169 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.