// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

//#include <ddk/debug.h>
#include <fbl/intrusive_double_list.h>
//#include <lib/async/cpp/task.h>
//#include <lib/async/dispatcher.h>
#include <lib/async/wait.h>
//#include <lib/fidl-utils/bind.h>
#include <lib/fit/defer.h>
#include <lib/fit/function.h>
#include <lib/zx/channel.h>
#include <zircon/fidl.h>
//#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <stdarg.h>
//#include <memory>

// SimpleBinding
//
// This class helps dispatch messages received on a FIDL channel, with the help
// of FIDL generated C code.
//
// This class can tolerate an async_dispatcher_t that uses more than one thread
// to call wait handlers, but this class will only have one wait in progress on
// the channel at a time, and call-outs to client code (Dispatch() and error
// handler) will only be called on one thread at a time in a serial fashion.
// Dispatch calls will occur in the same order as messages are read from the
// channel.
//
// Method calls to this class must be performed on a serial execution domain
// that's the same serial execution domain on which call-outs from this class
// occur.  Typically this will be a single-threaded async_dispatcher_t.  As long
// as calling in on the same serial execution domain, the calls in don't need to
// be during calls out (as in, on the same stack).  Calls in include running the
// destructor.
//
// Once Bind() succeeds, the error handler will run if the channel sees an error
// such as PEER_CLOSED or any other failure.  If on the other hand the client
// code calls Close() first, the error hander will not run.
//
// After the channel fails (can be detected by error_handler_ running) or
// Close() is called directly or via ~SimpleBinding (error_handler_ won't run in
// these cases), the client code is responsible for dropping ownership
// (~unique_ptr<Txn>) on any in-flight requests (fairly quickly).  In this case,
// calling _reply() on those Txn(s) first is optional.
//
// Client code is permitted to ~SimpleBinding and then attempt late responses
// via _reply() on a Txn without any harm.
//
// If the calling code calls Close() or causes ~SimpleBinding, it's the calling
// code's responsibility to shortly after delete any Txn(s) associated with this
// binding.  Calling _reply() on those Txn(s) first is optional, and not
// harmful.
//
// Calling _reply() on a Txn before ~Txn is required unless
// !Binding::is_bound().  In other words, just deleting a Txn without
// replying is only allowed if !is_bound().
//
// |Stub| A Stub* is passed to each function in the Ops table.  This makes Stub*
// usable with Binder<Stub>::BindMember<&Stub::FunctionImplementation> to
// provide the implementation of a function pointer in ops.  This template
// parameter is just to make the "ops_ctx" parameter of Create() typesafe.
// Note that Binder<Stub>::BindOps() is _not_ to be used with this class, as
// bind_fidl() (called by BindOps()) is replaced with Create()+Bind().
//
// |Ops| is the type of the FIDL dispatch table for the FIDL interface of this
// binding.  This will be something like fuchsia_sysmem_InterfaceName_ops.
//
// |Dispatch| is the generated FIDL dispatch function for the interface.  This
// will be something like fuchsia_sysmem_InterfaceName_dispatch.
template <typename Stub, typename Ops, auto Dispatch>
class SimpleBinding {
public:
    using Binding = SimpleBinding<Stub, Ops, Dispatch>;
    using ErrorHandler = fit::function<void(zx_status_t)>;
    class Txn;
    using TxnPtr = std::unique_ptr<Txn>;

    // A concurrency_cap of std::numeric_limits<uint32_t>::max() is accepted and
    // means unlimited, but an unlimited cap is not recommended.
    SimpleBinding(async_dispatcher_t* dispatcher, Stub* ops_ctx, const Ops* ops,
                  uint32_t concurrency_cap)
        : dispatcher_(dispatcher),
          ops_ctx_(ops_ctx),
          ops_(ops),
          concurrency_cap_(concurrency_cap) {
        static_assert(std::is_same<
                          decltype(Dispatch),
                          zx_status_t (*)(void*, fidl_txn_t*, fidl_msg_t*, const Ops* ops)>::value,
                      "Invalid dispatch function");
        ZX_DEBUG_ASSERT(dispatcher_);
        ZX_DEBUG_ASSERT(ops_ctx_);
        ZX_DEBUG_ASSERT(ops_);
        // A concurrency cap of 0 is invalid, not a special value.
        ZX_DEBUG_ASSERT(concurrency_cap_);
    }

    // Client code that wants to clean up all its in-flight txns immediately can
    // choose to Close() the binding, or can choose to ~SimpleBinding.  Either
    // way, ~Txn is then permitted without having called _reply() on that txn.
    ~SimpleBinding() {
        Close();
        while (!txn_list_.is_empty()) {
            // This way, _reply() on this Txn will fail, but no harm done by the
            // _reply().
            txn_list_.pop_front()->binding_ = nullptr;
        }
        if (binding_is_gone_canary_) {
            // This lets the stack frame calling Dispatch() know that ~Binding
            // ran.
            *binding_is_gone_canary_ = true;
        }
    }

    // Required before Bind().
    void SetErrorHandler(ErrorHandler error_handler) {
        // Once only.
        ZX_DEBUG_ASSERT(error_handler);
        ZX_DEBUG_ASSERT(!error_handler_);
        error_handler_ = std::move(error_handler);
    }

    // SetErrorHandler() is required before Bind().
    void Bind(zx::channel server_channel) {
        // SetErrorHandler() is always required before Bind().
        ZX_DEBUG_ASSERT(error_handler_);
        ZX_DEBUG_ASSERT(server_channel.is_valid());
        ZX_DEBUG_ASSERT(!channel_.is_valid());
        channel_ = std::move(server_channel);
        ZX_DEBUG_ASSERT(is_bound());
        wait_.handler = AsyncWaitHandlerRaw;
        wait_.object = channel_.get();
        wait_.trigger = ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED;
        zx_status_t status = async_begin_wait(dispatcher_, &wait_);
        if (status != ZX_OK) {
            RunErrorHandler(status);
            return;
        }
    }

    // Close() is intentionally idempotent.
    ErrorHandler Close() {
        if (!is_bound()) {
            ZX_DEBUG_ASSERT(!error_handler_);
            return nullptr;
        }

        zx_status_t cancel_status = async_cancel_wait(dispatcher_, &wait_);
        // It's fine if async_cancel_wait() returns ZX_ERR_NOT_FOUND, but we
        // don't expect any other errors.
        ZX_DEBUG_ASSERT(cancel_status == ZX_OK || cancel_status == ZX_ERR_NOT_FOUND);
        // Just to keep things tidy - not fundamentally needed.
        wait_.object = ZX_HANDLE_INVALID;
        // Won't be using this any more, so keep things tidy.
        dispatcher_ = nullptr;

        // The error handler will only run if the channel is valid; this
        // prevents the error handler from running if RunErrorHandler() is
        // called later.
        channel_.reset();

        // The caller can run the error_handler if the caller wants to, or the
        // caller can just delete the error handler if the caller prefers the
        // error handler not run when calling Close().
        return std::move(error_handler_);
    }

    bool is_bound() {
        return channel_.is_valid();
    }

    // This class is unique_ptr<>-managed, but there's a trick involved where
    // during _dispatch() we don't know up front if client code will take
    // ownership.  To permit client code to optionally take ownership during
    // _dispatch(), we use a temporary pointer to the unique_ptr<> on the stack
    // of the caller of _dispatch(), which the client code can (indirectly)
    // move to its own unique_ptr<> for async _reply() later.
    class Txn {
        friend Binding;

    public:
        ~Txn() {
            // It's not allowed to just delete an in-flight txn without
            // responding, unless the channel is already !is_bound() or the
            // channel is gone.
            //
            // However, the FIDL C _dispatch() mechanism doesn't seem to offer
            // any way to tell whether a Txn was really needed vs. just ignored
            // by a one-way message.
            //
            // The !binding_ part of the condition allows for:
            //   * deletion of stack-based moved-out Txn instances whose
            //     heap-based replacment (move target) will complete separately.
            //   * deleteion of any Txn instance whose binding_ has already been
            //     deleted - ~Binding() clears binding_.
            //
            // We don't intend for the logical Txn to ever be moved outside the
            // up-to-one move from stack to heap.
            ZX_DEBUG_ASSERT_COND(!is_moved_out_ || !binding_);
            ZX_DEBUG_ASSERT_COND(!(is_moved_out_ && is_moved_in_));
            ZX_DEBUG_ASSERT(!is_recognized_ ||
                            is_completed_ ||
                            (!binding_ || !binding_->is_bound()));
            if (binding_) {
                binding_->txn_list_.erase(*this);
                // If there's no binding_, it means either Txn was moved out in
                // which case the heap-based Txn will decrement concurrency_, or
                // the Binding has been deleted so doesn't need its concurrency_
                // decremented.
                ZX_DEBUG_ASSERT(binding_->concurrency_ != 0);
                --binding_->concurrency_;
            }
        }

        // Let the dispatcher know that this txn ended up at a handler that takes a txn.
        static void RecognizeTxn(fidl_txn_t* raw_txn) {
            ZX_DEBUG_ASSERT(raw_txn);
            Txn* stack_txn = reinterpret_cast<Txn*>(
                reinterpret_cast<uint8_t*>(raw_txn) - offsetof(Txn, raw_txn_));
            ZX_DEBUG_ASSERT(&stack_txn->raw_txn_ == raw_txn);
            // Shouldn't be moved out yet - recognize should be done extremely
            // near the start of any dispatch method with a fidl_txn_t*
            // parameter.
            ZX_DEBUG_ASSERT_COND(!stack_txn->is_moved_out_);
            // Needs to be a stack-based Txn not a heap-based Txn.
            ZX_DEBUG_ASSERT_COND(!stack_txn->is_moved_in_);
            // RecognizeTxn() is only valid during initial dispatch of this txn,
            // and only valid on stack-based Txn instances not heap-based Txn
            // instances.
            ZX_DEBUG_ASSERT_COND(stack_txn->binding_ &&
                                 stack_txn->binding_->stack_txn_during_dispatch_ &&
                                 stack_txn->binding_->stack_txn_during_dispatch_ == stack_txn);
            // A Txn should only be recognized once, since it's easy enough to
            // just call RecognizeTxn() at the start of every handler that takes
            // a fidl_txn_t* parameter.
            ZX_DEBUG_ASSERT(!stack_txn->is_recognized_);
            // All Txn(s) must be recognized before being completed, to help
            // ensure we're able to detect a (recognized) Txn that's deleted
            // without being completed.
            stack_txn->is_recognized_ = true;
        }

        // Client code will be called via Dispatch().  The client code method
        // will be passed a fidl_txn_t _if_ the message needs a reply.  Because
        // there's no way for Dispatch() to report back whether txn ownership
        // ended up with the client code, TakeTxn() uses a stashed pointer to
        // a unique_ptr<Txn> held by the stack frame calling Dispatch(), to
        // ensure that unless client code explicitly calls TakeTxn(), the frame
        // calling Dispatch() will ~Txn.
        static TxnPtr TakeTxn(fidl_txn_t* raw_txn) {
            ZX_DEBUG_ASSERT(raw_txn);
            Txn* stack_txn = reinterpret_cast<Txn*>(
                reinterpret_cast<uint8_t*>(raw_txn) - offsetof(Txn, raw_txn_));
            ZX_DEBUG_ASSERT(&stack_txn->raw_txn_ == raw_txn);
            // Needs to be a stack-based Txn not a heap-based Txn.
            ZX_DEBUG_ASSERT_COND(!stack_txn->is_moved_in_);
            // TakeTxn() is only valid during initial dispatch of this txn.
            ZX_DEBUG_ASSERT_COND(stack_txn->binding_ &&
                                 stack_txn->binding_->stack_txn_during_dispatch_ &&
                                 stack_txn->binding_->stack_txn_during_dispatch_ == stack_txn);
            // Move the stack-based Txn to the heap, managed by a
            // unique_ptr<Txn>. By allocating on the stack initially, and moving
            // here, we can complete a request sync without any heap allocation.
            // The caller of TakeTxn() wants a heap-based Txn to complete
            // potentially async (sync completion of the Txn returned from this
            // method is still allowed, but is less efficient than completing
            // the stack-based Txn sync by not calling TakeTxn() and just
            // completing the raw_txn instead (only if the caller isn't trying
            // to process the Txn async)).
            return TxnPtr(new Txn(std::move(*stack_txn)));
        }

        // Client code can use this to be able to call the relevant _reply().
        // After return from _reply(), the client code will delete its
        // unique_ptr<Txn>.
        fidl_txn_t& raw_txn() {
            ZX_DEBUG_ASSERT_COND(!is_moved_out_);
            return raw_txn_;
        }

    private:
        // This is used to create on the stack, which is where all logical
        // Txn(s) are initially created.
        Txn(Binding* binding, uint32_t txid)
            : binding_(binding),
              raw_txn_({.reply = FidlReplyRaw}),
              txid_(txid) {
            binding_->txn_list_.push_front(this);
        }

        // This move is only meant to be used to move a logical Txn from the
        // stack to the heap up to once.
        //
        // If client code calls TakeTxn(), the logical Txn is moved from the
        // stack to the heap, with the caller of TakeTxn() getting a
        // unique_ptr<Txn> to allow completing the Txn async.  The stack frame
        // running Dispatch() will run ~Txn on the move source (to_move), but
        // that ~Txn doesn't matter - the logical Txn is the move destination.
        //
        // One-way messages to the server don't give the client code a
        // fidl_txn_t*, so for those the stack-based Txn is never moved.  For
        // two-way requests to the server, the client may _reply() synchronously
        // in which case no move ever occurs, or the client may move the Txn
        // from stack to heap and _reply() later using the move target
        // Txn.raw_txn().
        //
        // In all cases, it's permitted to just ~Txn if the binding_ is gone or
        // no longer bound.
        Txn(Txn&& to_move)
            : binding_(to_move.binding_),
              // struct copy
              raw_txn_(to_move.raw_txn_),
              txid_(to_move.txid_),
              is_recognized_(to_move.is_recognized_),
              is_completed_(to_move.is_completed_) {
#if ZX_DEBUG_ASSERT_IMPLEMENTED
            ZX_DEBUG_ASSERT(!to_move.is_moved_out_);
            // The intent of having this move constructor is to allow up to one
            // move from the stack to the heap, not multiple moves.
            ZX_DEBUG_ASSERT(!to_move.is_moved_in_);
            is_moved_in_ = true;
            to_move.is_moved_out_ = true;
#endif
            if (binding_) {
                // The binding_ being non-nullptr means the binding_ still
                // exists and as long as binding_ exists it'll contain all the
                // Txn(s) that were created by incoming messages of the bidning_
                // that haven't been destructed yet.
                ZX_DEBUG_ASSERT(to_move.txn_list_node_state_.InContainer());
                // This un-links to_move from binding_.txn_list_ and links in
                // this instead.
                binding_->txn_list_.replace(to_move, this);
                // This prevents ~Txn from complaining about ~Txn of to_move
                // without to_move.is_completed_.
                to_move.binding_ = nullptr;
            }
            ZX_DEBUG_ASSERT(!to_move.binding_);
            // We leave the rest of the fields of to_move as-is.  The ~to_move
            // (when destructing the stack-based move source) will not assert
            // because to_move.binding_ is nullptr.  If an attempt to .reply()
            // using to_move is made, that'll assert because
            // to_move.is_moved_out_.
        }

        // intentionally move-only
        Txn(const Txn& to_copy) = delete;
        Txn& operator=(const Txn& to_copy) = delete;

        // This function is our fidl_txn_t.reply() function.
        static zx_status_t FidlReplyRaw(fidl_txn_t* raw_txn, const fidl_msg_t* msg) {
            Txn* txn = reinterpret_cast<Txn*>(
                reinterpret_cast<uint8_t*>(raw_txn) - offsetof(Txn, raw_txn_));
            ZX_DEBUG_ASSERT(&txn->raw_txn_ == raw_txn);
            return txn->FidlReplyCooked(msg);
        }

        zx_status_t FidlReplyCooked(const fidl_msg_t* msg) {
            // Client code must not pass in nullptr.
            ZX_DEBUG_ASSERT(msg);
            // Client code must be sending a message that isn't broken.
            ZX_DEBUG_ASSERT(msg->num_bytes >= sizeof(fidl_message_header_t));
            // To complete a Txn, the Txn must be recognized first.  This helps
            // ensure that all handlers that take a fidl_txn_t remember to
            // recognize their Txn.
            ZX_DEBUG_ASSERT(is_recognized_);
            // The txn being completed must not be a stack-based Txn that has
            // been logically moved to the heap.  Complete the heap-based
            // Txn.raw_txn() instead.
            ZX_DEBUG_ASSERT_COND(!is_moved_out_);
            // Each txn can be completed a maximum of 1 time.
            ZX_DEBUG_ASSERT(!is_completed_);
            // Regardless of what this method does, this method is completing
            // the txn.
            is_completed_ = true;

            // This method ensures that the handles sent in here are closed
            // unless successfully transferred into the channel.
            auto close_handles = fit::defer([msg] {
                zx_status_t close_status =
                    zx_handle_close_many(msg->handles, msg->num_handles);
                ZX_DEBUG_ASSERT(close_status == ZX_OK);
            });

            if (!binding_ || !binding_->is_bound()) {
                // Can't zx_channel_write(), so don't try.  It's legal for
                // client code to _reply() after Close() and/or ~Binding.  The
                // caller may ignore this return value depending on the caller's
                // overall strategy for discovering that the channel has failed.
                return ZX_ERR_BAD_STATE;
            }

            // The caller should ensure this is true.  It's a bug in the caller
            // if not.
            ZX_DEBUG_ASSERT(msg->num_bytes >= sizeof(fidl_message_header_t));
            fidl_message_header_t* hdr = (fidl_message_header_t*)msg->bytes;
            // The caller shouldn't attempt to fill out the txid, as the txid is
            // private to Txn.
            ZX_DEBUG_ASSERT(hdr->txid == 0u);
            // Best-effort attempt to detect double-reply.  Since |this| is soon
            // to be deleted, this is only best-effort.
            ZX_DEBUG_ASSERT(txid_ != 0u);
            hdr->txid = txid_;
            // Part of best-effort attempt to detect double-reply.
            txid_ = 0;
            // zx_channel_write() will close all the handles on any failure, and
            // will transfer them on success.  So this method shouldn't close
            // the handles.
            close_handles.cancel();
            return zx_channel_write(binding_->channel(), 0, msg->bytes, msg->num_bytes,
                                    msg->handles, msg->num_handles);
            // ~self_delete
        }

        // This will be set to nullptr during ~Binding, which allows client
        // code to safely attempt _reply() on a txn after ~Binding.  The
        // _reply() will fail in that case, but no harm will be done.  See
        // futher comment on txn_list_node_state_.
        Binding* binding_ = nullptr;
        fidl_txn_t raw_txn_{};
        uint32_t txid_ = 0;
        // Becomes true when _dispatch() calls a handler that actually takes a
        // fidl_txn_t as an input parameter, via that handler calling
        // RecognizeTxn().
        bool is_recognized_ = false;
        bool is_completed_ = false;

#if ZX_DEBUG_ASSERT_IMPLEMENTED
        // This instance has been moved in from another instance.
        bool is_moved_in_ = false;
        // This instance is no longer valid because it was moved out.
        bool is_moved_out_ = false;
#endif

        // Membership in this list allows for binding_ to act similar to a
        // weak_ptr<Binding>, but without forcing use of
        // shared_ptr<Binding>.
        fbl::DoublyLinkedListNodeState<Txn*> txn_list_node_state_;
    };

private:
    zx_handle_t channel() {
        ZX_DEBUG_ASSERT(channel_.is_valid());
        return channel_.get();
    }

    // In general, deletes |this|.
    void RunErrorHandler(zx_status_t status) {
        // If the channel_ is already !is_valid(), then skip calling the
        // error_handler because this only happens if the client code calls
        // Close() (or ~Binding) before the error, in which case we don't
        // call the error handler.
        if (!is_bound()) {
            return;
        }
        // The error_handler_ is only meant to run up to once.  The client code
        // is expected to always set an error handler before calling Bind().
        ZX_DEBUG_ASSERT(error_handler_);
        // Clean up the channel before calling the error handler, in case the
        // error handling triggers any calls to _reply().
        ErrorHandler error_handler = Close();
        ZX_DEBUG_ASSERT(!is_bound());
        ZX_DEBUG_ASSERT(!error_handler_);
        error_handler(status);
        // in general, |this| is gone now
    }

    // async_wait_handler_t
    static void AsyncWaitHandlerRaw(async_dispatcher_t* dispatcher, async_wait_t* wait,
                                    zx_status_t status, const zx_packet_signal_t* signal) {
        auto binding = reinterpret_cast<Binding*>(reinterpret_cast<uint8_t*>(wait) - offsetof(Binding, wait_));
        ZX_DEBUG_ASSERT(&binding->wait_ == wait);
        binding->AsyncWaitHandlerCooked(dispatcher, status, signal);
    }

    void AsyncWaitHandlerCooked(async_dispatcher_t* dispatcher, zx_status_t status, const zx_packet_signal_t* signal) {
        if (status != ZX_OK) {
            goto error;
        }

        // We want to do all the reading before any closing due to peer closed.
        if (signal->observed & ZX_CHANNEL_READABLE) {
            for (uint64_t i = 0; i < signal->count; i++) {
                fidl_msg_t msg = {
                    .bytes = bytes_,
                    .handles = handles_,
                    .num_bytes = 0u,
                    .num_handles = 0u,
                };
                status = zx_channel_read(wait_.object, 0, bytes_, handles_,
                                         ZX_CHANNEL_MAX_MSG_BYTES,
                                         ZX_CHANNEL_MAX_MSG_HANDLES,
                                         &msg.num_bytes, &msg.num_handles);
                if (status != ZX_OK) {
                    goto error;
                }
                if (msg.num_bytes < sizeof(fidl_message_header_t)) {
                    status = ZX_ERR_BUFFER_TOO_SMALL;
                    goto error;
                }
                fidl_message_header_t* hdr = (fidl_message_header_t*)msg.bytes;

                // The request's txid flows into the future response's txid.
                Txn stack_txn(this, hdr->txid);
                ZX_DEBUG_ASSERT(concurrency_ <= concurrency_cap_);
                ++concurrency_;
                if (concurrency_ > concurrency_cap_) {
                    status = ZX_ERR_NO_RESOURCES;
                    goto error;
                }

                // If ~Binding is run during Dispatch(), we find out via
                // binding_is_gone_canary.
                bool binding_is_gone_canary = false;
                binding_is_gone_canary_ = &binding_is_gone_canary;
#if ZX_DEBUG_ASSERT_IMPLEMENTED
                stack_txn_during_dispatch_ = &stack_txn;
#endif
                auto cleanup_after_dispatch = fit::defer([this, &binding_is_gone_canary] {
                    // Set binding_is_gone_canary_ back to nullptr before
                    // binding_is_gone_canary leaves the stack, but only if
                    // |this| binding still exists.
                    //
                    // Same for stack_txn_during_dispatch_.
                    if (!binding_is_gone_canary) {
                        this->binding_is_gone_canary_ = nullptr;
#if ZX_DEBUG_ASSERT_IMPLEMENTED
                        this->stack_txn_during_dispatch_ = nullptr;
#endif
                    }
                });

                // The callee methods in Stub are each required to copy out
                // anything needed from msg during this call if the
                // txn.raw_txn().reply() will be called later after this
                // Dispatch() has returned.
                //
                // A Dispatch() that deletes |this| can return ZX_OK or a
                // failure status, so we can't use that to determine whether
                // |this| still exists after Dispatch().
                status = Dispatch(ops_ctx_, &stack_txn.raw_txn(), &msg, ops_);

                // The Dispatch() call is permitted to run ~Binding, so we need
                // to check if |this| is still valid as part of determining
                // whether to wait again.
                if (binding_is_gone_canary) {
                    // |this| binding is gone, so just return.
                    return;
                }

                // We permit ZX_ERR_ASYNC, but given this dispatching code it's
                // equivalent to ZX_OK.  So we just convert to ZX_OK here.
                //
                // We still permit _dispatch() to return ZX_ERR_ASYNC for
                // convenience and (inbound) compatibility for porting (in)
                // handlers that used to use be called by fidl-async dispatching
                // code, but ... we don't require ZX_ERR_ASYNC.
                if (status == ZX_ERR_ASYNC) {
                    status = ZX_OK;
                }
                if (status != ZX_OK) {
                    goto error;
                }

                // If the binding still exists but the channel_ was closed
                // using Close(), the client code is responsible for running
                // ~Binding and ~Txn for all associated txns (in any order), so
                // just return without starting another wait.
                if (!is_bound()) {
                    return;
                }

                // keep going with the next message, until done reading messages
            }

            // |this| binding still exists, so wait again.  If ~Binding runs
            // later outside of wait completion, ~Binding will cancel the wait.
            status = async_begin_wait(dispatcher, &wait_);
            if (status != ZX_OK) {
                goto error;
            }

            // Now that new wait is started, return.  We intentionally choose to
            // not handle PEER_CLOSED until we're done reading messages.  This
            // choice essentially preserves ordering of send and close (in that
            // order).
            return;
        }

        // We don't notify an error until we've drained all the messages out of
        // the channel.  We run the error handler with ZX_ERR_PEER_CLOSED for
        // consistency with message_reader.cc.
        ZX_DEBUG_ASSERT(signal->observed & ZX_CHANNEL_PEER_CLOSED);
        status = ZX_ERR_PEER_CLOSED;

    error:;
        RunErrorHandler(status);
        return;
    }

    async_dispatcher_t* dispatcher_ = nullptr;
    Stub* ops_ctx_ = nullptr;
    const Ops* ops_ = nullptr;
    const uint32_t concurrency_cap_ = 0;
    uint32_t concurrency_ = 0;
    ErrorHandler error_handler_;
    zx::channel channel_;
    async_wait_t wait_{};

    struct TxnListTraits {
        inline static fbl::DoublyLinkedListNodeState<Txn*>& node_state(Txn& obj) {
            return obj.txn_list_node_state_;
        }
    };
    using TxnList = fbl::DoublyLinkedList<Txn*, TxnListTraits>;
    TxnList txn_list_;

    // Only non-nullptr during Dispatch().  When not nullptr, this points at a
    // canary bool on the stack that's calling Dispatch(), so the stack frame
    // calling Dispatch() can determine whether ~Binding ran during Dispatch().
    bool* binding_is_gone_canary_ = nullptr;

#if ZX_DEBUG_ASSERT_IMPLEMENTED
    Txn* stack_txn_during_dispatch_ = nullptr;
#endif

    // These are a bit large for the stack, so we pre-allocate them as part of
    // the connection.  Only one thread (per connection) is ever actively
    // starting the processing of a server request.  These get overwritten on
    // each zx_channel_read() for this connection.  Note that each _reply()
    // function will still put similarly-sized arrays on the stack.
    char bytes_[ZX_CHANNEL_MAX_MSG_BYTES];
    zx_handle_t handles_[ZX_CHANNEL_MAX_MSG_HANDLES];
};
