SL-19690 Merge pull request #207 from RyeMutt/shutdown-crash

Fix exceptions during shutdown causing early program termination
master
akleshchev 2023-05-08 18:25:12 +03:00 committed by GitHub
commit db30ffc7cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 38 deletions

View File

@ -516,37 +516,45 @@ namespace LL
// Here we believe target WorkQueue still exists. Post to it a
// lambda that packages our callable, our callback and a weak_ptr
// to this originating WorkQueue.
tptr->post(
[reply = super::getWeak(),
callable = std::move(callable),
callback = std::move(callback)]
() mutable
{
// Use postMaybe() below in case this originating WorkQueue
// has been closed or destroyed. Remember, the outer lambda is
// now running on a thread servicing the target WorkQueue, and
// real time has elapsed since postTo()'s tptr->post() call.
try
try
{
tptr->post(
[reply = super::getWeak(),
callable = std::move(callable),
callback = std::move(callback)]
() mutable
{
// Make a reply lambda to repost to THIS WorkQueue.
// Delegate to makeReplyLambda() so we can partially
// specialize on void return.
postMaybe(reply, makeReplyLambda(std::move(callable), std::move(callback)));
}
catch (...)
{
// Either variant of makeReplyLambda() is responsible for
// calling the caller's callable. If that throws, return
// the exception to the originating thread.
postMaybe(
reply,
// Bind the current exception to transport back to the
// originating WorkQueue. Once there, rethrow it.
[exc = std::current_exception()](){ std::rethrow_exception(exc); });
}
},
// if caller passed a TimePoint, pass it along to post()
std::forward<ARGS>(args)...);
// Use postMaybe() below in case this originating WorkQueue
// has been closed or destroyed. Remember, the outer lambda is
// now running on a thread servicing the target WorkQueue, and
// real time has elapsed since postTo()'s tptr->post() call.
try
{
// Make a reply lambda to repost to THIS WorkQueue.
// Delegate to makeReplyLambda() so we can partially
// specialize on void return.
postMaybe(reply, makeReplyLambda(std::move(callable), std::move(callback)));
}
catch (...)
{
// Either variant of makeReplyLambda() is responsible for
// calling the caller's callable. If that throws, return
// the exception to the originating thread.
postMaybe(
reply,
// Bind the current exception to transport back to the
// originating WorkQueue. Once there, rethrow it.
[exc = std::current_exception()](){ std::rethrow_exception(exc); });
}
},
// if caller passed a TimePoint, pass it along to post()
std::forward<ARGS>(args)...);
}
catch (const Closed&)
{
// target WorkQueue still exists, but is Closed
return false;
}
// looks like we were able to post()
return true;

View File

@ -92,14 +92,21 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Instantiate the ImageRequest right in the lambda, why not?
mThreadPool->getQueue().post(
[req = ImageRequest(image, discard, needs_aux, responder)]
() mutable
{
auto done = req.processRequest();
req.finishRequest(done);
});
try
{
// Instantiate the ImageRequest right in the lambda, why not?
mThreadPool->getQueue().post(
[req = ImageRequest(image, discard, needs_aux, responder)]
() mutable
{
auto done = req.processRequest();
req.finishRequest(done);
});
}
catch (const LLThreadSafeQueueInterrupt&)
{
LL_DEBUGS() << "Tried to start decoding on shutdown" << LL_ENDL;
}
// It's important to our consumer (LLTextureFetchWorker) that we return a
// nonzero handle. It is NOT important that the nonzero handle be unique: