From 1fc3341a624be096bd6a938e6f9c7d42861a3712 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 21 Mar 2025 13:37:34 +0100 Subject: Fix crash due to crosss-thread list access. 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. --- src/lib/writer.cc | 11 +---------- 1 file changed, 1 insertion(+), 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 (); -- cgit v1.2.3