Package: emacs;
Reported by: Sullivan Beck <sulbeck <at> ufl.edu>
Date: Wed, 18 Nov 2009 15:50:04 UTC
Severity: normal
Tags: moreinfo
Done: Lars Ingebrigtsen <larsi <at> gnus.org>
Bug is archived. No further changes may be made.
Message #5 received at submit <at> emacsbugs.donarmstrong.com (full text, mbox):
From: Sullivan Beck <sulbeck <at> ufl.edu> To: bug-gnu-emacs <at> gnu.org Subject: 23.1; Emacs hangs when two run-at-time calls in effect Date: Wed, 18 Nov 2009 10:41:48 -0500
I wrote two simple emacs extensions, both of which use the run-at-time function periodically write some information to a file. When one or the other is loaded, emacs works fine. When both are loaded, emacs will work fine for a while, and then suddently start behaving very sluggishly. Keyboard input will not be printed on the screen for 2-4 seconds. It never seems to recover (though the periodic work should only take a fraction of a second) and eventually, I have to kill emacs and restart. I'll include both extensions below, though I don't believe that either of them are directly related to the cause of the problem... it just happened that they both use run-at-time. The first is to make the scratch buffer persistent. I (perhaps unwisely... but it's a habit I've gotten into) use the scratch buffer almost like a post-it note where I just jot things down and I don't want to lose it if my emacs gets shut down (either due to a system crash, power outage, or whatever). For safety, I save the buffer to a file every 5 minutes. ##### scratch.el #################################### ;; This makes the scratch buffer persistent. It will preserve the ;; contents of the buffer in a file stored in the variable scratch-file. ;; Whenever the scratch buffer is killed, it will automatically be ;; recreated with the old contents. If emacs is killed, the contents ;; will be placed in the scratch buffer the next time it is started. ;; The name of the file to preserve the scratch buffer in. (if (not (boundp 'scratch-file)) (setq scratch-file "~/.emacs.scratch")) (if (not (boundp 'scratch-autosave-interval)) (setq scratch-autosave-interval 300)) ;; If the *scratch* buffer is killed, recreate it automatically and ;; preserve the contents. (add-hook 'after-init-hook 'init-scratch-buffer) (add-hook 'after-init-hook 'init-scratch-autosave) (add-hook 'kill-emacs-hook 'kill-scratch-buffer) (defun init-scratch-buffer () (set-buffer (get-buffer-create "*scratch*")) (if (file-exists-p scratch-file) (insert-file-contents scratch-file)) (lisp-interaction-mode) (make-local-variable 'kill-buffer-query-functions) (add-hook 'kill-buffer-query-functions 'restart-scratch-buffer)) ;; This is called when we kill emacs. ;; Save *scratch*, kill *scratch*, don't restart it ;; (defun kill-scratch-buffer () (save-scratch-buffer) (save-current-buffer (set-buffer "*scratch*") (remove-hook 'kill-buffer-query-functions 'restart-scratch-buffer)) (kill-buffer "*scratch*")) ;; This saves the scratch buffer. ;; (defun save-scratch-buffer () (save-current-buffer (set-buffer "*scratch*") (write-region nil nil scratch-file))) ;; This restarts the scratch buffer. If we're currently in the scratch ;; buffer, come back to it. Otherwise, preserve the current buffer. ;; (defun restart-scratch-buffer () (setq currbuf (buffer-name)) (save-current-buffer ;; Kill the current (*scratch*) buffer (kill-scratch-buffer) ;; Make a brand new *scratch* buffer (init-scratch-buffer)) (if (string= currbuf "*scratch*") (switch-to-buffer "*scratch*")) ;; Since we killed it, don't let caller do that. nil) (defun init-scratch-autosave () (run-at-time t scratch-autosave-interval 'save-scratch-buffer)) ##### scratch.el #################################### The second, which is much less important (and it may be that there is an extension for doing this already) is that when I start up emacs, I like to automatically load the buffers that were loaded when emacs stopped. For safety, I also periodically saved the buffer list. Because I wanted the functionality of both, but couldn't deal with the hangs, I added an option to disable the periodic save of the buffer list (so it only gets saved when emacs is shut down nicely) and after that change was made, emacs worked fine. ##### bufferlist.el #################################### ;; This will store the list of open files when emacs is closed. When it ;; is restarted, it will attempt to reopen them. ;; The name of the file to preserve the buffer list in. (if (not (boundp 'bufferlist-file)) (setq bufferlist-file "~/.emacs.bufferlist")) (if (not (boundp 'bufferlist-autosave-interval)) (setq bufferlist-autosave-interval 300)) (add-hook 'after-init-hook 'init-bufferlist) (if (> bufferlist-autosave-interval 0) (add-hook 'after-init-hook 'init-bufferlist-autosave)) (add-hook 'kill-emacs-hook 'save-bufferlist) ;; This reads in the given buffer from the point to the end ;; of the line AND moves the point to the start of the next line. (defun read-text-line (buffer) ;; Switch to the buffer, and start a line at the current point. (setq line "") (save-current-buffer (set-buffer buffer) ;; Read characters until we get to EOL or EOB (while (and (not (eobp)) (not (eolp))) (setq c (following-char)) (setq line (concat line (char-to-string c))) (forward-char)) ;; If we're at EOL, move to the start of the next line (if (not (eobp)) (forward-char))) ;; Return line line) (defun eobp-buffer (buffer) (save-current-buffer (set-buffer buffer) (eobp))) (defun eolp-buffer (buffer) (save-current-buffer (set-buffer buffer) (eolp))) (defun save-bufferlist () ;; Create the bufferlist buffer (setq buflist "") (setq buflistbuf (generate-new-buffer "*bufferlist*")) ;; Insert the buffername and filename for all open files into this buffer (dolist (buffer (buffer-list)) (setq bufname (buffer-name buffer)) (save-current-buffer (set-buffer buffer) (setq filname buffer-file-name) (if buffer-file-name (progn (set-buffer buflistbuf) (insert bufname) (insert "\C-j") (insert filname) (insert "\C-j"))))) ;; Save the buffer to the file (save-current-buffer (set-buffer buflistbuf) (write-file bufferlist-file)) (kill-buffer buflistbuf)) (defun init-bufferlist () ;; Create the bufferlist buffer and insert the file into it. (save-current-buffer (setq buflistbuf (generate-new-buffer "*bufferlist*")) (set-buffer buflistbuf) (insert-file-contents-literally bufferlist-file)) ;; Load each buffer/file name (while (not (eobp-buffer buflistbuf)) (setq bufname (read-text-line buflistbuf)) (setq filname (read-text-line buflistbuf)) ;; Create the buffer. If it's different then it used to be, ;; rename it. (if (file-readable-p filname) (save-current-buffer (switch-to-buffer (find-file-noselect filname t nil nil)) (setq name (buffer-name)) (if (not (string= bufname name)) (rename-buffer bufname))))) ;; Clean up (kill-buffer buflistbuf)) (defun init-bufferlist-autosave () (run-at-time t bufferlist-autosave-interval 'save-bufferlist)) ##### bufferlist.el #################################### I'm sure there are other options available for both options... but these work for me, and I believe both should work without causing emacs to hang. They are loaded from my init.el file as: ##### init.el #################################### (setq scratch-file "~/..emacs/.scratch.") (load "scratch.elc" t t t) (setq bufferlist-autosave-interval 0) (setq bufferlist-file "~/..emacs/.bufferlist.") (load "bufferlist.elc" t t t) ##### init.el #################################### If I don't set bufferlist-autosave-interval to 0 (and use the default 5 minutes), emacs will hang. If I set it to 0 (which disables the autosave functionaity), everything works fine. Emacs doesn't crash, and I'm able to continue using it (though painfully). Thanks In GNU Emacs 23.1.1 (x86_64-suse-linux-gnu, GTK+ Version 2.18.1) of 2009-10-24 on build24 Windowing system distributor `The X.Org Foundation', version 11.0.10605000 configured using `configure '--with-pop' '--without-hesiod' '--with-kerberos' '--with-kerberos5' '--with-xim' '--prefix=/usr' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--datadir=/usr/share' '--localstatedir=/var' '--sharedstatedir=/var/lib' '--libexecdir=/usr/lib' '--with-x' '--with-sound' '--with-sync-input' '--with-xpm' '--with-jpeg' '--with-tiff' '--with-gif' '--with-png' '--with-rsvg' '--with-dbus' '--without-gpm' '--with-x-toolkit=gtk' '--x-includes=/usr/include' '--x-libraries=/usr/lib64:/usr/share/X11' '--with-xft' '--with-libotf' '--with-m17n-flt' '--build=x86_64-suse-linux' 'build_alias=x86_64-suse-linux' 'CC=gcc' 'CFLAGS=-fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -g -D_GNU_SOURCE -std=gnu89 -pipe -Wno-pointer-sign -Wno-unused-variable -Wno-unused-label -Wno-unprototyped-calls -DSYSTEM_PURESIZE_EXTRA=55000 -DSITELOAD_PURESIZE_EXTRA=10000 ' 'LDFLAGS=-Wl,-O2 -Wl,--hash-size=65521'' Important settings: value of $LC_ALL: C value of $LC_COLLATE: nil value of $LC_CTYPE: nil value of $LC_MESSAGES: nil value of $LC_MONETARY: nil value of $LC_NUMERIC: nil value of $LC_TIME: nil value of $LANG: en_US.UTF-8 value of $XMODIFIERS: @im=local locale-coding-system: nil default-enable-multibyte-characters: t Major mode: CSS Minor modes in effect: show-paren-mode: t tooltip-mode: t mouse-wheel-mode: t menu-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t global-auto-composition-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t line-number-mode: t transient-mark-mode: t Recent input: <down> <down> <down> <down> <down> <down> <down> <down> <down> <down> <down> <down> <down> <down> <down> C-y <up> <right> <right> <right> <right> <right> C-x r k <up> <up> <up> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <down-mouse-1> <mouse-1> C-SPC <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <escape> w <down-mouse-1> <mouse-1> C-y <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> C-SPC <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> <right> C-w C-x C-s <down-mouse-1> <mouse-1> <down-mouse-1> <mouse-1> C-a C-SPC <down> <down> <down> <down> <down> <down> <down> <down> <up> C-w C-x C-s <down-mouse-1> <mouse-1> C-a C-SPC <down> <down> <down> <down> C-w C-x C-s <switch-frame> C-x C-f ~ / p e r s / p a s s w d <return> C-s m o z i l l a C-s C-s C-s <switch-frame> <switch-frame> <down-mouse-1> <mouse-movement> <mouse-movement> <drag-mouse-1> <switch-frame> <down-mouse-1> <drag-mouse-1> <switch-frame> <down-mouse-1> <drag-mouse-1> <switch-frame> <down-mouse-1> <drag-mouse-1> <switch-frame> <down-mouse-1> <drag-mouse-1> <switch-frame> <down-mouse-1> <drag-mouse-1> <switch-frame> <up> <switch-frame> <up> <up> C-e <return> g e t s a t i s f a c t i o n . c o m C-x C-s <switch-frame> <down-mouse-4> <mouse-4> <double-down-mouse-4> <double-mouse-4> <triple-down-mouse-4> <triple-mouse-4> <triple-down-mouse-4> <triple-mouse-4> <down-mouse-1> <mouse-movement> <mouse-movement> <drag-mouse-1> <down-mouse-1> <mouse-movement> <mouse-movement> <drag-mouse-1> <down-mouse-1> <mouse-movement> <mouse-movement> <drag-mouse-1> <down-mouse-1> <mouse-1> <switch-frame> C-x k <return> <switch-frame> <switch-frame> <switch-frame> <escape> x r e p o r t SPC e m <tab> <return> Recent messages: Saving file /home/sulbeck/.thunderbird/3crazqn6.default/chrome/userChrome.css... Wrote /home/sulbeck/.thunderbird/3crazqn6.default/chrome/userChrome.css Mark set Saving file /home/sulbeck/.thunderbird/3crazqn6.default/chrome/userChrome.css... Wrote /home/sulbeck/.thunderbird/3crazqn6.default/chrome/userChrome.css Wrote /home/sulbeck/..emacs/.scratch. [12 times] Mark saved where search started Saving file /home/sulbeck/pers/passwd... Wrote /home/sulbeck/pers/passwd Wrote /home/sulbeck/..emacs/.scratch. [18 times] -- --------------------------| Sullivan Beck |--------------------------- Email : sulbeck <at> ufl.edu | University of Florida Work Phone : (352) 273-1367 | Computing and Networking Services | 301 SSRB | Gainesville, FL 32611 ------------------------------------------------------------------------ For non-work related matters, please contact by email instead of phone ------------------------------------------------------------------------
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.