commit cf3a2e38fcc81e0515ea0557c6f837fd3cfdb269
parent 0d6a14bced9838695575c1e112dc3ecbfb299c8c
Author: Dan Callaghan <djc@djc.id.au>
Date: Sat, 10 Oct 2026 20:34:24 +1100
rewrite ThreadIndexMode#multi_kill to work like the other label methods
Avoids race conditions which arise from invoking Index.save_thread
before regen_text.
Fixes #488.
Diffstat:
1 file changed, 28 insertions(+), 27 deletions(-)
diff --git a/lib/sup/modes/thread_index_mode.rb b/lib/sup/modes/thread_index_mode.rb
@@ -494,6 +494,29 @@ EOS
threads.each { |t| Index.save_thread t }
end
+ ## returns an undo lambda
+ def actually_toggle_killed t
+ if t.has_label? :killed
+ t.remove_label :killed
+ add_or_unhide t.first
+ UpdateManager.relay self, :labeled, t.first
+ lambda do
+ t.apply_label :killed
+ hide_thread t
+ UpdateManager.relay self, :labeled, t.first
+ end
+ else
+ t.apply_label :killed
+ hide_thread t
+ UpdateManager.relay self, :labeled, t.first
+ lambda do
+ t.remove_label :killed
+ add_or_unhide t.first
+ UpdateManager.relay self, :labeled, t.first
+ end
+ end
+ end
+
def kill
t = cursor_thread or return
multi_kill [t]
@@ -507,35 +530,13 @@ EOS
## m-m-m-m-MULTI-KILL
def multi_kill threads
- UndoManager.register "killing/unkilling #{threads.size.pluralize 'threads'}" do
- threads.each do |t|
- if t.toggle_label :killed
- add_or_unhide t.first
- else
- hide_thread t
- end
- end.each do |t|
- UpdateManager.relay self, :labeled, t.first
- Index.save_thread t
- end
- regen_text
- end
-
- threads.each do |t|
- if t.toggle_label :killed
- hide_thread t
- else
- add_or_unhide t.first
- end
- end.each do |t|
- # send 'labeled'... this might be more specific
- UpdateManager.relay self, :labeled, t.first
- Index.save_thread t
- end
-
+ undos = threads.map { |t| actually_toggle_killed t }
+ UndoManager.register "killing/unkilling #{threads.size.pluralize 'threads'}", undos,
+ lambda { regen_text }, lambda { threads.each { |t| Index.save_thread t } }
+ regen_text
+ threads.each { |t| Index.save_thread t }
killed, unkilled = threads.partition { |t| t.has_label? :killed }.map(&:size)
BufferManager.flash "#{killed.pluralize 'thread'} killed, #{unkilled} unkilled"
- regen_text
end
def cleanup