From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#12447: 24.1.50; Stuck in garbage collection on OS X Date: Tue, 18 Sep 2012 18:05:31 +0300 Message-ID: <837grr1idg.fsf@gnu.org> References: <505598C8.8070904@yandex.ru> <834nmys1ht.fsf@gnu.org> <5055AD8E.5020309@yandex.ru> <83zk4qqj4d.fsf@gnu.org> <5055C0EB.3040908@yandex.ru> <83wqzuqgzr.fsf@gnu.org> <5055D34F.1040800@yandex.ru> <83txuyqdtv.fsf@gnu.org> <5055E16E.1070604@yandex.ru> <83sjaiqaqb.fsf@gnu.org> <5055F69B.4020004@yandex.ru> Reply-To: Eli Zaretskii NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Trace: ger.gmane.org 1347980823 11263 80.91.229.3 (18 Sep 2012 15:07:03 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 18 Sep 2012 15:07:03 +0000 (UTC) Cc: 12447@debbugs.gnu.org, hanche@math.ntnu.no To: Dmitry Gutov , Jan =?UTF-8?Q?Dj=C3=A4rv?= Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Sep 18 17:07:03 2012 Return-path: Envelope-to: geb-bug-gnu-emacs@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 1TDzO8-00019Y-BX for geb-bug-gnu-emacs@m.gmane.org; Tue, 18 Sep 2012 17:07:00 +0200 Original-Received: from localhost ([::1]:60660 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TDzO3-0002iQ-Vu for geb-bug-gnu-emacs@m.gmane.org; Tue, 18 Sep 2012 11:06:55 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:51518) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TDzO0-0002az-8r for bug-gnu-emacs@gnu.org; Tue, 18 Sep 2012 11:06:53 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TDzNq-0002LZ-Cw for bug-gnu-emacs@gnu.org; Tue, 18 Sep 2012 11:06:52 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:60669) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TDzNq-0002LT-8v for bug-gnu-emacs@gnu.org; Tue, 18 Sep 2012 11:06:42 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1TDzP8-0001k8-Gg for bug-gnu-emacs@gnu.org; Tue, 18 Sep 2012 11:08:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 18 Sep 2012 15:08:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 12447 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 12447-submit@debbugs.gnu.org id=B12447.13479808596622 (code B ref 12447); Tue, 18 Sep 2012 15:08:02 +0000 Original-Received: (at 12447) by debbugs.gnu.org; 18 Sep 2012 15:07:39 +0000 Original-Received: from localhost ([127.0.0.1]:41981 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TDzOk-0001ii-Fk for submit@debbugs.gnu.org; Tue, 18 Sep 2012 11:07:38 -0400 Original-Received: from mtaout20.012.net.il ([80.179.55.166]:52690) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TDzOg-0001iS-JQ for 12447@debbugs.gnu.org; Tue, 18 Sep 2012 11:07:36 -0400 Original-Received: from conversion-daemon.a-mtaout20.012.net.il by a-mtaout20.012.net.il (HyperSendmail v2007.08) id <0MAJ00A00W928W00@a-mtaout20.012.net.il> for 12447@debbugs.gnu.org; Tue, 18 Sep 2012 18:05:22 +0300 (IDT) Original-Received: from HOME-C4E4A596F7 ([87.69.4.28]) by a-mtaout20.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0MAJ00ABPWKY1IC0@a-mtaout20.012.net.il>; Tue, 18 Sep 2012 18:05:22 +0300 (IDT) In-reply-to: <5055F69B.4020004@yandex.ru> X-012-Sender: halo1@inter.net.il X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 140.186.70.43 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.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:64554 Archived-At: > Date: Sun, 16 Sep 2012 19:56:11 +0400 > From: Dmitry Gutov > Cc: 12447@debbugs.gnu.org, hanche@math.ntnu.no > > On 16.09.2012 18:54, Eli Zaretskii wrote: > >> Date: Sun, 16 Sep 2012 18:25:50 +0400 > >> From: Dmitry Gutov > >> CC: hanche@math.ntnu.no, 12447@debbugs.gnu.org > >> > >>> Perhaps the problem is that the value of 'difference' is not > >>> initialized: > >>> > >>> while (CONSP (timers) || CONSP (idle_timers)) > >>> { > >>> Lisp_Object timer = Qnil, idle_timer = Qnil; > >>> EMACS_TIME timer_time, idle_timer_time; > >>> EMACS_TIME difference; <<<<<<<<<<<<<<<<<<<<<<<<<<<< > >>> > >>> and then never set to any specific value, until here: > >>> > >>> else > >>> /* When we encounter a timer that is still waiting, > >>> return the amount of time to wait before it is ripe. */ > >>> { > >>> UNGCPRO; > >>> return difference; > >>> } > >>> > >>> which causes us return garbage, potentially zero, to timer_check. > >> > >> It's assigned to, though. When we encounter a timer that's not yet ripe. > > > > What if all of them are ripe? > > I don't see the problem. The first timer is ripe? Fire it and return > 'nexttime'. Otherwise, return 'difference', which now has been assigned > a value. > If we've reached the end of the list, again return 'nexttime', which is > initialized with invalid_emacs_time () at the beginning of timer_check_2. > > Anyway, I think the immediate problem is that the newly created timer > can be considered ripe. The patch below makes your simplified recipe, viz.: (defvar counter 0) (defun foo () (message (format "foo %s" counter)) (setq counter (1+ counter)) (run-with-idle-timer 1 nil #'foo)) (foo) "work" without locking up Emacs. "Work" in the sense that the timer is run and increments the counter, but keyboard input is still accepted, and causes 1-sec break in the idle timer invocation. What does NOT happen is the once-per-second invocation of the idle timer: as long as there's no other input, the idle timer runs much more frequently. But I think this is expected, since the call to run-with-idle-timer above explicitly asks to be run immediately. Can you see if these changes also make js2-mode work as expected? Jan, can you test whether this patch still keeps your two-timers recipe working? If it does, I think I should commit the changes below, because they avoid locking up Emacs by a timer that repeatedly reinvokes itself. === modified file 'src/keyboard.c' --- src/keyboard.c 2012-09-16 21:43:55 +0000 +++ src/keyboard.c 2012-09-18 14:58:24 +0000 @@ -4334,25 +4334,18 @@ decode_timer (Lisp_Object timer, EMACS_T should be done. */ static EMACS_TIME -timer_check_2 (void) +timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) { EMACS_TIME nexttime; EMACS_TIME now; EMACS_TIME idleness_now; - Lisp_Object timers, idle_timers, chosen_timer; - struct gcpro gcpro1, gcpro2, gcpro3; + Lisp_Object chosen_timer; + struct gcpro gcpro1; nexttime = invalid_emacs_time (); - /* Always consider the ordinary timers. */ - timers = Vtimer_list; - /* Consider the idle timers only if Emacs is idle. */ - if (EMACS_TIME_VALID_P (timer_idleness_start_time)) - idle_timers = Vtimer_idle_list; - else - idle_timers = Qnil; chosen_timer = Qnil; - GCPRO3 (timers, idle_timers, chosen_timer); + GCPRO1 (chosen_timer); /* First run the code that was delayed. */ while (CONSP (pending_funcalls)) @@ -4501,13 +4494,30 @@ EMACS_TIME timer_check (void) { EMACS_TIME nexttime; + Lisp_Object timers, idle_timers; + struct gcpro gcpro1, gcpro2; + + /* We use copies of the timers' lists to allow a timer to add itself + again, without locking up Emacs if the newly added timer is + already ripe when added. */ + + /* Always consider the ordinary timers. */ + timers = Fcopy_sequence (Vtimer_list); + /* Consider the idle timers only if Emacs is idle. */ + if (EMACS_TIME_VALID_P (timer_idleness_start_time)) + idle_timers = Fcopy_sequence (Vtimer_idle_list); + else + idle_timers = Qnil; + + GCPRO2 (timers, idle_timers); do { - nexttime = timer_check_2 (); + nexttime = timer_check_2 (timers, idle_timers); } while (EMACS_SECS (nexttime) == 0 && EMACS_NSECS (nexttime) == 0); + UNGCPRO; return nexttime; }