aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2025-11-13 16:47:21 -0600
committerCraig Jennings <c@cjennings.net>2025-11-13 16:47:21 -0600
commitbe2f11f7b02c5474c03e8574bf66d4033721284c (patch)
tree049e8ae66611fa71fd434f7bc1875852f31038d2
parent2c81096877e99f790de486a588f0c4b0ebdaaad6 (diff)
downloadorg-drill-be2f11f7b02c5474c03e8574bf66d4033721284c.tar.gz
org-drill-be2f11f7b02c5474c03e8574bf66d4033721284c.zip
Fix race condition with timer cleanup and marker leak
Timer cleanup fix: - Wrapped recursive-edit in unwind-protect to ensure org-drill-presentation-timer-cancel is always called - Timer is now cancelled even if recursive-edit exits abnormally Marker leak fix: - Moved org-drill-free-markers outside the (unless (oref session end-pos)) condition - Done-entries markers are now always freed in cleanup, even on error or suspension - Prevents memory leaks in long-running Emacs sessions Fixes two severity B bugs in todo.org
-rw-r--r--org-drill.el29
1 files changed, 16 insertions, 13 deletions
diff --git a/org-drill.el b/org-drill.el
index 221f797..1ac5f8a 100644
--- a/org-drill.el
+++ b/org-drill.el
@@ -1831,17 +1831,19 @@ Consider reformulating the item to make it easier to remember.\n"
#'org-drill-presentation-minibuffer-timer-function
item-start-time full-prompt)
org-drill-presentation-timer-calls 0)
- (save-window-excursion
- (let ((buf
- (org-drill-response-get-buffer-create)))
- (select-window
- (display-buffer-below-selected buf nil))
- ;; Store the current session in a variable, so that it can
- ;; be picked up by the when we leave the buffer
- (setq-local org-drill-current-session session)
- (recursive-edit)
- (org-drill-presentation-timer-cancel)
- (oref session exit-kind)))))
+ (unwind-protect
+ (save-window-excursion
+ (let ((buf
+ (org-drill-response-get-buffer-create)))
+ (select-window
+ (display-buffer-below-selected buf nil))
+ ;; Store the current session in a variable, so that it can
+ ;; be picked up by the when we leave the buffer
+ (setq-local org-drill-current-session session)
+ (recursive-edit)
+ (oref session exit-kind)))
+ ;; Always cancel timer, even if recursive-edit exits abnormally
+ (org-drill-presentation-timer-cancel))))
(cl-defun org-drill-presentation-prompt-for-string (session prompt)
"Create a card prompt with a timer and user-specified menu.
@@ -3094,9 +3096,10 @@ work correctly with older versions of org mode. Your org mode version (%s) appea
;; Cleanup: restore display and run after-session hook
(org-drill--restore-display)
(run-hooks 'org-drill-after-session-hook)
+ ;; Always free done-entries markers, even on error or suspension
+ (org-drill-free-markers session (oref session done-entries))
(unless (oref session end-pos)
- (setf (oref session cram-mode) nil)
- (org-drill-free-markers session (oref session done-entries))))))
+ (setf (oref session cram-mode) nil)))))
(cond
((oref session end-pos)
(when (markerp (oref session end-pos))