@@ -609,59 +609,61 @@ void clientInvoke(ProxyClient& proxy_client, const GetRequest& get_request, Fiel
609
609
<< " {" << g_thread_context.thread_name
610
610
<< " } IPC client first request from current thread, constructing waiter" ;
611
611
}
612
- ClientInvokeContext invoke_context{*proxy_client.m_context .connection , g_thread_context};
612
+ ThreadContext& thread_context{g_thread_context};
613
+ std::optional<ClientInvokeContext> invoke_context; // Must outlive waiter->wait() call below
613
614
std::exception_ptr exception;
614
615
std::string kj_exception;
615
616
bool done = false ;
616
617
const char * disconnected = nullptr ;
617
618
proxy_client.m_context .loop ->sync ([&]() {
618
619
if (!proxy_client.m_context .connection ) {
619
- const std::unique_lock<std::mutex> lock (invoke_context. thread_context .waiter ->m_mutex );
620
+ const std::unique_lock<std::mutex> lock (thread_context.waiter ->m_mutex );
620
621
done = true ;
621
622
disconnected = " IPC client method called after disconnect." ;
622
- invoke_context. thread_context .waiter ->m_cv .notify_all ();
623
+ thread_context.waiter ->m_cv .notify_all ();
623
624
return ;
624
625
}
625
626
626
627
auto request = (proxy_client.m_client .*get_request)(nullptr );
627
628
using Request = CapRequestTraits<decltype (request)>;
628
629
using FieldList = typename ProxyClientMethodTraits<typename Request::Params>::Fields;
629
- IterateFields ().handleChain (invoke_context, request, FieldList (), typename FieldObjs::BuildParams{&fields}...);
630
+ invoke_context.emplace (*proxy_client.m_context .connection , thread_context);
631
+ IterateFields ().handleChain (*invoke_context, request, FieldList (), typename FieldObjs::BuildParams{&fields}...);
630
632
proxy_client.m_context .loop ->logPlain ()
631
- << " {" << invoke_context. thread_context .thread_name << " } IPC client send "
633
+ << " {" << thread_context.thread_name << " } IPC client send "
632
634
<< TypeName<typename Request::Params>() << " " << LogEscape (request.toString ());
633
635
634
636
proxy_client.m_context .loop ->m_task_set ->add (request.send ().then (
635
637
[&](::capnp::Response<typename Request::Results>&& response) {
636
638
proxy_client.m_context .loop ->logPlain ()
637
- << " {" << invoke_context. thread_context .thread_name << " } IPC client recv "
639
+ << " {" << thread_context.thread_name << " } IPC client recv "
638
640
<< TypeName<typename Request::Results>() << " " << LogEscape (response.toString ());
639
641
try {
640
642
IterateFields ().handleChain (
641
- invoke_context, response, FieldList (), typename FieldObjs::ReadResults{&fields}...);
643
+ * invoke_context, response, FieldList (), typename FieldObjs::ReadResults{&fields}...);
642
644
} catch (...) {
643
645
exception = std::current_exception ();
644
646
}
645
- const std::unique_lock<std::mutex> lock (invoke_context. thread_context .waiter ->m_mutex );
647
+ const std::unique_lock<std::mutex> lock (thread_context.waiter ->m_mutex );
646
648
done = true ;
647
- invoke_context. thread_context .waiter ->m_cv .notify_all ();
649
+ thread_context.waiter ->m_cv .notify_all ();
648
650
},
649
651
[&](const ::kj::Exception& e) {
650
652
if (e.getType () == ::kj::Exception::Type::DISCONNECTED) {
651
653
disconnected = " IPC client method call interrupted by disconnect." ;
652
654
} else {
653
655
kj_exception = kj::str (" kj::Exception: " , e).cStr ();
654
656
proxy_client.m_context .loop ->logPlain ()
655
- << " {" << invoke_context. thread_context .thread_name << " } IPC client exception " << kj_exception;
657
+ << " {" << thread_context.thread_name << " } IPC client exception " << kj_exception;
656
658
}
657
- const std::unique_lock<std::mutex> lock (invoke_context. thread_context .waiter ->m_mutex );
659
+ const std::unique_lock<std::mutex> lock (thread_context.waiter ->m_mutex );
658
660
done = true ;
659
- invoke_context. thread_context .waiter ->m_cv .notify_all ();
661
+ thread_context.waiter ->m_cv .notify_all ();
660
662
}));
661
663
});
662
664
663
- std::unique_lock<std::mutex> lock (invoke_context. thread_context .waiter ->m_mutex );
664
- invoke_context. thread_context .waiter ->wait (lock, [&done]() { return done; });
665
+ std::unique_lock<std::mutex> lock (thread_context.waiter ->m_mutex );
666
+ thread_context.waiter ->wait (lock, [&done]() { return done; });
665
667
if (exception) std::rethrow_exception (exception);
666
668
if (!kj_exception.empty ()) proxy_client.m_context .loop ->raise () << kj_exception;
667
669
if (disconnected) proxy_client.m_context .loop ->raise () << disconnected;
0 commit comments