blob: 79d3c0e43a65d1e50f704aa93eb2a148f8b9739c [file] [log] [blame]
// Copyright 2020 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.
#include "message-group.h"
#include <zircon/status.h>
#include <ddk/debug.h>
#include <fbl/auto_lock.h>
#include "server.h"
zx_status_t MessageGroup::ExpectResponses(int response_count, int request_count,
std::optional<reqid_t> request_id) {
fbl::AutoLock guard(&lock_);
zx_status_t status = ZX_OK;
if (pending_ && request_count != 0) {
response_.status = ZX_ERR_IO;
zxlogf(WARNING,
"Attempted to add more requests to finalised transaction group: req=%d group=%d",
response_.reqid, response_.group);
status = ZX_ERR_IO;
}
if (response_.status != ZX_OK) {
// The operation failed already, don't bother with any more transactions.
status = ZX_ERR_IO;
}
op_count_ += response_count;
response_.count += request_count;
if (request_id != std::nullopt) {
response_.reqid = *request_id;
pending_ = true;
}
return status;
}
void MessageGroup::Complete(const zx_status_t status) {
fbl::AutoLock guard(&lock_);
if (status != ZX_OK && response_.status == ZX_OK) {
zxlogf(WARNING, "Transaction completed with error status: %s", zx_status_get_string(status));
response_.status = status;
}
if (--op_count_ == 0 && pending_) {
server_.SendResponse(response_);
if (response_.group == kNoGroup) {
delete this;
} else {
pending_ = false;
response_.count = 0;
response_.reqid = 0;
response_.status = ZX_OK;
}
}
}