Digging into the code (without being able to reproduce) the likeliest cause seems to be incorrect error handling in mir::compositor::CompositingFunctor::operator()().
In Mir 0.18 this function can plausibly terminate via an exception before setting the promise (on line 116) - it has a catch block, but this does not set an exception on the promise. I can't identify all the threads from the error tracker, but I don't see this one, so I suspect this is what has happened.
In Mir 0.19 this function has been modified to set the exception on the promise, which should change the behaviour. But as the future not read (just waited on) the behaviour is still suspect. The current failure detected in wait_until_started() should go and the problem will be ignored by the Compositor. However, as mir::terminate_with_current_exception() is called the server should close down and we'll end up with a different failure mode. Maybe that will give us a little more information on the underlying error condition?
In my travels I also noticed some hard-to-validate logic in MultiThreadedCompositor::start()/stop() - which, while it does successfully use atomic for synchronization, has the questionable behaviour of simply ignoring both start() and stop() requests while in state CompositorState::starting or CompositorState::stopping.
Likewise in usc::MirScreen the locking conventions around "_l" functions are not followed consistently.
Digging into the code (without being able to reproduce) the likeliest cause seems to be incorrect error handling in mir::compositor ::CompositingFu nctor:: operator( )().
In Mir 0.18 this function can plausibly terminate via an exception before setting the promise (on line 116) - it has a catch block, but this does not set an exception on the promise. I can't identify all the threads from the error tracker, but I don't see this one, so I suspect this is what has happened.
In Mir 0.19 this function has been modified to set the exception on the promise, which should change the behaviour. But as the future not read (just waited on) the behaviour is still suspect. The current failure detected in wait_until_ started( ) should go and the problem will be ignored by the Compositor. However, as mir::terminate_ with_current_ exception( ) is called the server should close down and we'll end up with a different failure mode. Maybe that will give us a little more information on the underlying error condition?
In my travels I also noticed some hard-to-validate logic in MultiThreadedCo mpositor: :start( )/stop( ) - which, while it does successfully use atomic for synchronization, has the questionable behaviour of simply ignoring both start() and stop() requests while in state CompositorState ::starting or CompositorState ::stopping.
Likewise in usc::MirScreen the locking conventions around "_l" functions are not followed consistently.