It looks like I can't provide a "reason" from the Receiver side for the "receiver never bound" case because the objects underlying the
mojo::PendingReceiver type (e.g. MessagePipeHandle) only provide a Close() method. However, I do receive a MOJO_RESULT_FAILED_PRECONDITION value in
Connector::OnHandleReadyInternal when the peer is closed, and this is distinct from the "other fatal errors" mentioned in that method. Can I somehow access this MojoResult value (or related state) from inside my disconnect handler without routing it as an argument via the |connection_error_handler_|?
Here's my current call stack for the disconnect on Windows:
> libcef.dll!CefFrameImpl::OnBrowserFrameDisconnect(unsigned int custom_reason, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & description) Line 548 C++
libcef.dll!base::internal::DecayedFunctorTraits<void (CefFrameImpl::*)(unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &),CefFrameImpl *&&>::Invoke<void (CefFrameImpl::*)(unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &),scoped_refptr<CefFrameImpl>,unsigned int,const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &>(void(CefFrameImpl::*)(unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &) method, scoped_refptr<CefFrameImpl> && receiver_ptr, unsigned int && args, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & args) Line 738 C++
libcef.dll!base::internal::InvokeHelper<0,base::internal::FunctorTraits<void (CefFrameImpl::*&&)(unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &),CefFrameImpl *&&>,void,0>::MakeItSo<void (CefFrameImpl::*)(unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &),std::__Cr::tuple<scoped_refptr<CefFrameImpl>>,unsigned int,const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &>(void(CefFrameImpl::*)(unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &) && functor, std::__Cr::tuple<scoped_refptr<CefFrameImpl>> && bound, unsigned int && args, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & args) Line 930 C++
libcef.dll!base::internal::Invoker<base::internal::FunctorTraits<void (CefFrameImpl::*&&)(unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &),CefFrameImpl *&&>,base::internal::BindState<1,1,0,void (CefFrameImpl::*)(unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &),scoped_refptr<CefFrameImpl>>,void (unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &)>::RunImpl<void (CefFrameImpl::*)(unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &),std::__Cr::tuple<scoped_refptr<CefFrameImpl>>,0>(void(CefFrameImpl::*)(unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &) && functor, std::__Cr::tuple<scoped_refptr<CefFrameImpl>> && bound, std::__Cr::integer_sequence<unsigned long long,0>, unsigned int && unbound_args, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & unbound_args) Line 1067 C++
libcef.dll!base::internal::Invoker<base::internal::FunctorTraits<void (CefFrameImpl::*&&)(unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &),CefFrameImpl *&&>,base::internal::BindState<1,1,0,void (CefFrameImpl::*)(unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &),scoped_refptr<CefFrameImpl>>,void (unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &)>::RunOnce(base::internal::BindStateBase * base, unsigned int unbound_args, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & unbound_args) Line 980 C++
mojo_public_cpp_bindings.dll!base::OnceCallback<void (unsigned int, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> &)>::Run(unsigned int args, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & args) Line 157 C++
mojo_public_cpp_bindings.dll!mojo::InterfaceEndpointClient::NotifyError(const std::__Cr::optional<mojo::DisconnectReason> & reason) Line 768 C++
mojo_public_cpp_bindings.dll!mojo::internal::MultiplexRouter::ProcessNotifyErrorTask(mojo::internal::MultiplexRouter::Task * task, mojo::internal::MultiplexRouter::ClientCallBehavior client_call_behavior, base::SequencedTaskRunner * current_task_runner) Line 1036 C++
mojo_public_cpp_bindings.dll!mojo::internal::MultiplexRouter::ProcessTasks(mojo::internal::MultiplexRouter::ClientCallBehavior client_call_behavior, base::SequencedTaskRunner * current_task_runner) Line 946 C++
mojo_public_cpp_bindings.dll!mojo::internal::MultiplexRouter::OnPipeConnectionError(bool force_async_dispatch) Line 858 C++
mojo_public_cpp_bindings.dll!base::internal::DecayedFunctorTraits<void (mojo::internal::MultiplexRouter::*)(bool),mojo::internal::MultiplexRouter *,bool &&>::Invoke<void (mojo::internal::MultiplexRouter::*)(bool),mojo::internal::MultiplexRouter *,bool>(void(mojo::internal::MultiplexRouter::*)(bool) method, mojo::internal::MultiplexRouter * && receiver_ptr, bool && args) Line 738 C++
mojo_public_cpp_bindings.dll!base::internal::InvokeHelper<0,base::internal::FunctorTraits<void (mojo::internal::MultiplexRouter::*&&)(bool),mojo::internal::MultiplexRouter *,bool &&>,void,0,1>::MakeItSo<void (mojo::internal::MultiplexRouter::*)(bool),std::__Cr::tuple<base::internal::UnretainedWrapper<mojo::internal::MultiplexRouter,base::unretained_traits::MayNotDangle,0>,bool>>(void(mojo::internal::MultiplexRouter::*)(bool) && functor, std::__Cr::tuple<base::internal::UnretainedWrapper<mojo::internal::MultiplexRouter,base::unretained_traits::MayNotDangle,0>,bool> && bound) Line 930 C++
mojo_public_cpp_bindings.dll!base::internal::Invoker<base::internal::FunctorTraits<void (mojo::internal::MultiplexRouter::*&&)(bool),mojo::internal::MultiplexRouter *,bool &&>,base::internal::BindState<1,1,0,void (mojo::internal::MultiplexRouter::*)(bool),base::internal::UnretainedWrapper<mojo::internal::MultiplexRouter,base::unretained_traits::MayNotDangle,0>,bool>,void ()>::RunImpl<void (mojo::internal::MultiplexRouter::*)(bool),std::__Cr::tuple<base::internal::UnretainedWrapper<mojo::internal::MultiplexRouter,base::unretained_traits::MayNotDangle,0>,bool>,0,1>(void(mojo::internal::MultiplexRouter::*)(bool) && functor, std::__Cr::tuple<base::internal::UnretainedWrapper<mojo::internal::MultiplexRouter,base::unretained_traits::MayNotDangle,0>,bool> && bound, std::__Cr::integer_sequence<unsigned long long,0,1>) Line 1067 C++
mojo_public_cpp_bindings.dll!base::internal::Invoker<base::internal::FunctorTraits<void (mojo::internal::MultiplexRouter::*&&)(bool),mojo::internal::MultiplexRouter *,bool &&>,base::internal::BindState<1,1,0,void (mojo::internal::MultiplexRouter::*)(bool),base::internal::UnretainedWrapper<mojo::internal::MultiplexRouter,base::unretained_traits::MayNotDangle,0>,bool>,void ()>::RunOnce(base::internal::BindStateBase * base) Line 980 C++
mojo_public_cpp_bindings.dll!base::OnceCallback<void ()>::Run() Line 157 C++
mojo_public_cpp_bindings.dll!mojo::Connector::HandleError(bool force_pipe_reset, bool force_async_handler) Line 691 C++
mojo_public_cpp_bindings.dll!mojo::Connector::OnHandleReadyInternal(unsigned int result) Line 443 C++
mojo_public_cpp_bindings.dll!mojo::Connector::OnWatcherHandleReady(const char * interface_name, unsigned int result) Line 418 C++
Thanks,
Marshall