summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-03-21 13:37:34 +0100
committerCarl Hetherington <cth@carlh.net>2025-03-21 13:37:34 +0100
commit1fc3341a624be096bd6a938e6f9c7d42861a3712 (patch)
tree634327d17a683e230ff3d3e38087e488b1adc812 /src/lib
parentadfadddbee2ff9222eba69bd976f93af6508ce29 (diff)
Fix crash due to crosss-thread list access.2997-arch
I've seen it happen that item points to a different QueueItem after the lock was unlocked here, which I didn't think was possible. Backtraces suggest that when problems happen _queue is being sorted in another thread, and perhaps this is not allowed (I couldn't find any conclusive proof in any documentation). There is also a potential problem with the newly-added zombify() method, which takes the lock and clears the list.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/writer.cc11
1 files changed, 1 insertions, 10 deletions
diff --git a/src/lib/writer.cc b/src/lib/writer.cc
index 90c5a54cf..7a933724c 100644
--- a/src/lib/writer.cc
+++ b/src/lib/writer.cc
@@ -471,23 +471,14 @@ try
DCPOMATIC_ASSERT(item != _queue.rend());
++_pushed_to_disk;
- /* For the log message below */
- int const awaiting = _last_written[_queue.front().reel].frame() + 1;
- lock.unlock ();
-
- /* i is valid here, even though we don't hold a lock on the mutex,
- since list iterators are unaffected by insertion and only this
- thread could erase the last item in the list.
- */
- LOG_GENERAL("Writer full; pushes %1 to disk while awaiting %2", item->frame, awaiting);
+ LOG_GENERAL("Writer full; pushes %1 to disk while awaiting %2", item->frame, _last_written[_queue.front().reel].frame() + 1);
item->encoded->write_via_temp(
film()->j2c_path(item->reel, item->frame, item->eyes, true),
film()->j2c_path(item->reel, item->frame, item->eyes, false)
);
- lock.lock ();
item->encoded.reset();
--_queued_full_in_memory;
_full_condition.notify_all ();