diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-03-21 13:37:34 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-03-22 13:29:59 +0100 |
| commit | e93b66f4236ec25dbd0603bbe74c904b53180e91 (patch) | |
| tree | 55437a5fa20bed100ac842c48d0c80fe166381d2 | |
| parent | 3f1cffe8a0afe23577fe7351c05f1aa1dc492032 (diff) | |
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.
| -rw-r--r-- | src/lib/writer.cc | 11 |
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 (); |
