diff --git a/google/cloud/completion_queue.h b/google/cloud/completion_queue.h index d6e781cfed0d3..436afcceb6255 100644 --- a/google/cloud/completion_queue.h +++ b/google/cloud/completion_queue.h @@ -177,14 +177,17 @@ class CompletionQueue { typename std::enable_if< internal::CheckRunAsyncCallback::value, int>::type = 0> void RunAsync(Functor&& functor) { + auto impl = impl_; MakeRelativeTimer(std::chrono::seconds(0)) - .then([this, functor]( - future>) { - // We intentionally ignore the status here; the functor is always - // called, even after a call to `CancelAll`. - CompletionQueue cq(impl_); - functor(cq); - }); + .then( + [impl, functor]( + future< + StatusOr>) mutable { + // We intentionally ignore the status here; the functor is always + // called, even after a call to `CancelAll`. + CompletionQueue cq(impl); + functor(cq); + }); } private: diff --git a/google/cloud/completion_queue_test.cc b/google/cloud/completion_queue_test.cc index a313c5cd75090..184d9780fbe38 100644 --- a/google/cloud/completion_queue_test.cc +++ b/google/cloud/completion_queue_test.cc @@ -328,6 +328,22 @@ TEST(CompletionQueueTest, RunAsync) { runner.join(); } +TEST(CompletionQueueTest, RunAsyncCompletionQueueDestroyed) { + auto cq_impl = std::make_shared(); + + std::promise done_promise; + { + CompletionQueue cq(cq_impl); + cq.RunAsync([&done_promise](CompletionQueue& cq) { + done_promise.set_value(); + cq.Shutdown(); + }); + } + cq_impl->SimulateCompletion(true); + + done_promise.get_future().get(); +} + // Sets up a timer that reschedules itself and verifies we can shut down // cleanly whether we call `CancelAll()` on the queue first or not. namespace {