From 9c9fd167cd5da647595ff38c4b48d81282bc2b1d Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Tue, 24 Oct 2023 18:19:12 -0700 Subject: [PATCH] [Yunq] Clean up codegen issues for client and server. --- lib/glacier/buffer/byte_buffer.h | 3 + lib/glacier/buffer/cap_buffer.h | 13 ++- yunq/client.cpp.jinja | 30 +++---- yunq/client.h.jinja | 12 ++- yunq/example.yunq.client.cpp | 30 +++---- yunq/example.yunq.client.h | 12 ++- yunq/example.yunq.cpp | 8 +- yunq/example.yunq.h | 18 ++--- yunq/example.yunq.server.cpp | 131 ++++++++++++++++++++++--------- yunq/example.yunq.server.h | 7 +- yunq/message.cpp.jinja | 4 +- yunq/message.h.jinja | 6 +- yunq/server.cpp.jinja | 44 +++++++---- yunq/server.h.jinja | 7 +- yunq/yunq.py | 2 +- 15 files changed, 216 insertions(+), 111 deletions(-) diff --git a/lib/glacier/buffer/byte_buffer.h b/lib/glacier/buffer/byte_buffer.h index f627339..bee2476 100644 --- a/lib/glacier/buffer/byte_buffer.h +++ b/lib/glacier/buffer/byte_buffer.h @@ -14,6 +14,9 @@ class ByteBuffer { ~ByteBuffer() { delete[] buffer_; } + uint8_t* RawPtr() { return buffer_; } + const uint8_t* RawPtr() const { return buffer_; } + template void WriteAt(uint64_t offset, const T& object) { // FIXME: Add bounds check here. diff --git a/lib/glacier/buffer/cap_buffer.h b/lib/glacier/buffer/cap_buffer.h index 10dca51..2c391e3 100644 --- a/lib/glacier/buffer/cap_buffer.h +++ b/lib/glacier/buffer/cap_buffer.h @@ -13,12 +13,23 @@ class CapBuffer { ~CapBuffer() { delete[] buffer_; } + uint64_t* RawPtr() { return buffer_; } + + uint64_t UsedSlots() { return used_slots_; } + uint64_t At(uint64_t offset) const { return buffer_[offset]; } - void WriteAt(uint64_t offset, uint64_t cap) { buffer_[offset] = cap; } + void WriteAt(uint64_t offset, uint64_t cap) { + buffer_[offset] = cap; + // This is fairly hacky considering we pass out the raw ptr. + if (used_slots_ < (offset + 1)) { + used_slots_ = offset + 1; + } + } private: uint64_t* buffer_; + uint64_t used_slots_ = 0; }; } // namespace glcr diff --git a/yunq/client.cpp.jinja b/yunq/client.cpp.jinja index 9e520c7..2f3b9b5 100644 --- a/yunq/client.cpp.jinja +++ b/yunq/client.cpp.jinja @@ -3,41 +3,37 @@ #include #include +#include {% for interface in interfaces %} {% for method in interface.methods %} -glcr::ErrorCode {{method.name}}(const {{method.request}}& request, {{method.response}}& response) { - uint64_t buffer_size = 0x1000; - // FIXME: Maybe raise this limit. - uint64_t cap_size = 100; - glcr::ByteBuffer buffer(buffer_size); - glcr::CapBuffer caps(cap_size); +glcr::ErrorCode {{interface.name}}Client::{{method.name}}(const {{method.request}}& request, {{method.response}}& response) { + uint64_t buffer_size = kBufferSize; + uint64_t cap_size = kCapBufferSize; const uint32_t kSentinel = 0xBEEFDEAD; - buffer.WriteAt(0, kSentinel); - buffer.WriteAt(8, {method_number}); + buffer_.WriteAt(0, kSentinel); + buffer_.WriteAt(8, {{loop.index0}}); - uint64_t length = request.SerializeToBytes(buffer, /*offset=*/16, caps); - buffer.WriteAt(4, 16 + length); + uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); + buffer_.WriteAt(4, 16 + length); z_cap_t reply_port_cap; // FIXME: We need to be able to send capabilities via endpoint call. - RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer.RawPtr())); + RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), &reply_port_cap)); // FIXME: Add a way to zero out the first buffer. - glcr::ByteBuffer recv_buffer(buffer_size); - glcr::CapBuffer recv_caps(cap_size); - RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, recv_buffer.RawPtr(), &cap_size, recv_caps.RawPtr())); + RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr())); - if (recv_buffer.At(0) != kSentinel) { + if (buffer_.At(0) != kSentinel) { return glcr::INVALID_RESPONSE; } // Check Response Code. - RET_ERR(recv_buffer.At(8)); + RET_ERR(buffer_.At(8)); - response.ParseFromBytes(recv_buffer, 16, recv_caps); + response.ParseFromBytes(buffer_, 16, cap_buffer_); return glcr::OK; } diff --git a/yunq/client.h.jinja b/yunq/client.h.jinja index 30e3f39..178210e 100644 --- a/yunq/client.h.jinja +++ b/yunq/client.h.jinja @@ -1,6 +1,9 @@ // Generated file - DO NOT MODIFY #pragma once +#include +#include +#include #include #include "{{file}}.h" @@ -10,12 +13,19 @@ class {{interface.name}}Client { public: {{interface.name}}Client(z_cap_t {{interface.name}}_cap) : endpoint_({{interface.name}}_cap) {} {{interface.name}}Client(const {{interface.name}}Client&) = delete; - {{interface.name}}Client({{interface.name}}Client&&) = delete; + {{interface.name}}Client({{interface.name}}Client&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;}; + + z_cap_t Capability() { return endpoint_; } + {% for method in interface.methods %} [[nodiscard]] glcr::ErrorCode {{method.name}}(const {{method.request}}& request, {{method.response}}& response); {% endfor %} private: z_cap_t endpoint_; + uint64_t kBufferSize = 0x1000; + glcr::ByteBuffer buffer_{kBufferSize}; + uint64_t kCapBufferSize = 0x10; + glcr::CapBuffer cap_buffer_{kCapBufferSize}; }; {%- endfor %} diff --git a/yunq/example.yunq.client.cpp b/yunq/example.yunq.client.cpp index 52d0c93..938fd60 100644 --- a/yunq/example.yunq.client.cpp +++ b/yunq/example.yunq.client.cpp @@ -3,41 +3,37 @@ #include #include +#include -glcr::ErrorCode open(const OpenFileRequest& request, File& response) { - uint64_t buffer_size = 0x1000; - // FIXME: Maybe raise this limit. - uint64_t cap_size = 100; - glcr::ByteBuffer buffer(buffer_size); - glcr::CapBuffer caps(cap_size); +glcr::ErrorCode VFSClient::open(const OpenFileRequest& request, File& response) { + uint64_t buffer_size = kBufferSize; + uint64_t cap_size = kCapBufferSize; const uint32_t kSentinel = 0xBEEFDEAD; - buffer.WriteAt(0, kSentinel); - buffer.WriteAt(8, {method_number}); + buffer_.WriteAt(0, kSentinel); + buffer_.WriteAt(8, 0); - uint64_t length = request.SerializeToBytes(buffer, /*offset=*/16, caps); - buffer.WriteAt(4, 16 + length); + uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); + buffer_.WriteAt(4, 16 + length); z_cap_t reply_port_cap; // FIXME: We need to be able to send capabilities via endpoint call. - RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer.RawPtr())); + RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), &reply_port_cap)); // FIXME: Add a way to zero out the first buffer. - glcr::ByteBuffer recv_buffer(buffer_size); - glcr::CapBuffer recv_caps(cap_size); - RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, recv_buffer.RawPtr(), &cap_size, recv_caps.RawPtr())); + RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr())); - if (recv_buffer.At(0) != kSentinel) { + if (buffer_.At(0) != kSentinel) { return glcr::INVALID_RESPONSE; } // Check Response Code. - RET_ERR(recv_buffer.At(8)); + RET_ERR(buffer_.At(8)); - response.ParseFromBytes(recv_buffer, 16, recv_caps); + response.ParseFromBytes(buffer_, 16, cap_buffer_); return glcr::OK; } diff --git a/yunq/example.yunq.client.h b/yunq/example.yunq.client.h index 4769c88..385ff66 100644 --- a/yunq/example.yunq.client.h +++ b/yunq/example.yunq.client.h @@ -1,6 +1,9 @@ // Generated file - DO NOT MODIFY #pragma once +#include +#include +#include #include #include "example.yunq.h" @@ -9,10 +12,17 @@ class VFSClient { public: VFSClient(z_cap_t VFS_cap) : endpoint_(VFS_cap) {} VFSClient(const VFSClient&) = delete; - VFSClient(VFSClient&&) = delete; + VFSClient(VFSClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;}; + + z_cap_t Capability() { return endpoint_; } + [[nodiscard]] glcr::ErrorCode open(const OpenFileRequest& request, File& response); private: z_cap_t endpoint_; + uint64_t kBufferSize = 0x1000; + glcr::ByteBuffer buffer_{kBufferSize}; + uint64_t kCapBufferSize = 0x10; + glcr::CapBuffer cap_buffer_{kCapBufferSize}; }; diff --git a/yunq/example.yunq.cpp b/yunq/example.yunq.cpp index 14a444f..0277829 100644 --- a/yunq/example.yunq.cpp +++ b/yunq/example.yunq.cpp @@ -47,7 +47,7 @@ void OpenFileRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t off set_options(bytes.At(offset + header_size + (8 * 1))); } -uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) { +uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { uint32_t next_extension = header_size + 8 * 2; const uint32_t core_size = next_extension; // Write path. @@ -70,7 +70,7 @@ uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t off return next_extension; } -uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) { +uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { uint32_t next_extension = header_size + 8 * 2; const uint32_t core_size = next_extension; uint64_t next_cap = 0; @@ -120,7 +120,7 @@ void File::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const set_mem_cap(caps.At(mem_cap_ptr)); } -uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) { +uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { uint32_t next_extension = header_size + 8 * 3; const uint32_t core_size = next_extension; // Write path. @@ -146,7 +146,7 @@ uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) { return next_extension; } -uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) { +uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { uint32_t next_extension = header_size + 8 * 3; const uint32_t core_size = next_extension; uint64_t next_cap = 0; diff --git a/yunq/example.yunq.h b/yunq/example.yunq.h index 9313321..8842491 100644 --- a/yunq/example.yunq.h +++ b/yunq/example.yunq.h @@ -14,11 +14,11 @@ class OpenFileRequest { void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset); void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&); - glcr::String path() { return path_; } + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; + glcr::String path() const { return path_; } void set_path(const glcr::String& value) { path_ = value; } - uint64_t options() { return options_; } + uint64_t options() const { return options_; } void set_options(const uint64_t& value) { options_ = value; } private: @@ -35,13 +35,13 @@ class File { void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset); void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&); - glcr::String path() { return path_; } + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; + glcr::String path() const { return path_; } void set_path(const glcr::String& value) { path_ = value; } - uint64_t attrs() { return attrs_; } + uint64_t attrs() const { return attrs_; } void set_attrs(const uint64_t& value) { attrs_ = value; } - z_cap_t mem_cap() { return mem_cap_; } + z_cap_t mem_cap() const { return mem_cap_; } void set_mem_cap(const z_cap_t& value) { mem_cap_ = value; } private: diff --git a/yunq/example.yunq.server.cpp b/yunq/example.yunq.server.cpp index 52d0c93..31d230a 100644 --- a/yunq/example.yunq.server.cpp +++ b/yunq/example.yunq.server.cpp @@ -1,45 +1,102 @@ -// Generated file - DO NOT MODIFY -#include "example.yunq.client.h" +// Generated file -- DO NOT MODIFY. +#include "example.yunq.server.h" -#include -#include +#include +#include +namespace { +const uint32_t kSentinel = 0xBEEFDEAD; +const uint32_t kHeaderSize = 0x10; - -glcr::ErrorCode open(const OpenFileRequest& request, File& response) { - uint64_t buffer_size = 0x1000; - // FIXME: Maybe raise this limit. - uint64_t cap_size = 100; - glcr::ByteBuffer buffer(buffer_size); - glcr::CapBuffer caps(cap_size); - - const uint32_t kSentinel = 0xBEEFDEAD; +void WriteError(glcr::ByteBuffer& buffer, glcr::ErrorCode err) { buffer.WriteAt(0, kSentinel); - buffer.WriteAt(8, {method_number}); - - uint64_t length = request.SerializeToBytes(buffer, /*offset=*/16, caps); - buffer.WriteAt(4, 16 + length); - - z_cap_t reply_port_cap; - // FIXME: We need to be able to send capabilities via endpoint call. - RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer.RawPtr())); - - // FIXME: Add a way to zero out the first buffer. - glcr::ByteBuffer recv_buffer(buffer_size); - glcr::CapBuffer recv_caps(cap_size); - RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, recv_buffer.RawPtr(), &cap_size, recv_caps.RawPtr())); - - if (recv_buffer.At(0) != kSentinel) { - return glcr::INVALID_RESPONSE; - } - - // Check Response Code. - RET_ERR(recv_buffer.At(8)); - - response.ParseFromBytes(recv_buffer, 16, recv_caps); - - return glcr::OK; + buffer.WriteAt(4, kHeaderSize); + buffer.WriteAt(8, err); } +void WriteHeader(glcr::ByteBuffer& buffer, uint64_t message_length) { + buffer.WriteAt(0, kSentinel); + buffer.WriteAt(4, kHeaderSize + message_length); + buffer.WriteAt(8, glcr::OK); +} +} // namespace + + + +void VFSServerBaseThreadBootstrap(void* server_base) { + ((VFSServerBase*)server_base)->ServerThread(); +} + +glcr::ErrorOr VFSServerBase::CreateClient() { + uint64_t client_cap; + // FIXME: Restrict permissions to send-only here. + RET_ERR(ZCapDuplicate(endpoint_, &client_cap)); + return VFSClient(client_cap); +} + +Thread VFSServerBase::RunServer() { + return Thread(VFSServerBaseThreadBootstrap, this); +} + +void VFSServerBase::ServerThread() { + glcr::ByteBuffer recv_buffer(0x1000); + glcr::ByteBuffer resp_buffer(0x1000); + uint64_t resp_cap_size = 0x10; + glcr::CapBuffer resp_cap(resp_cap_size); + z_cap_t reply_port_cap; + + while (true) { + uint64_t recv_buf_size = 0x1000; + glcr::ErrorCode recv_err = ZEndpointRecv(endpoint_, &recv_buf_size, recv_buffer.RawPtr(), &reply_port_cap); + if (recv_err != glcr::OK) { + dbgln("Error in receive: %x", recv_err); + continue; + } + + uint64_t resp_length = 0; + + glcr::ErrorCode reply_err = glcr::OK; + glcr::ErrorCode err = HandleRequest(recv_buffer, resp_buffer, resp_length, resp_cap); + if (err != glcr::OK) { + WriteError(resp_buffer, err); + reply_err = ZReplyPortSend(reply_port_cap, kHeaderSize, resp_buffer.RawPtr(), 0, nullptr); + } else { + WriteHeader(resp_buffer, resp_length); + reply_err = ZReplyPortSend(reply_port_cap, kHeaderSize + resp_length, resp_buffer.RawPtr(), resp_cap.UsedSlots(), resp_cap.RawPtr()); + } + if (reply_err != glcr::OK) { + dbgln("Error in reply: %x", recv_err); + } + } + +} + +glcr::ErrorCode VFSServerBase::HandleRequest(const glcr::ByteBuffer& request, + glcr::ByteBuffer& response, uint64_t& resp_length, + glcr::CapBuffer& resp_caps) { + if (request.At(0) != kSentinel) { + return glcr::INVALID_ARGUMENT; + } + + uint64_t method_select = request.At(8); + + switch(method_select) { + case 0: { + OpenFileRequest yunq_request; + File yunq_response; + + yunq_request.ParseFromBytes(request, kHeaderSize); + + RET_ERR(Handleopen(yunq_request, yunq_response)); + + resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); + break; + } + default: { + return glcr::UNIMPLEMENTED; + } + } + return glcr::OK; +} diff --git a/yunq/example.yunq.server.h b/yunq/example.yunq.server.h index 7ebaacc..e801486 100644 --- a/yunq/example.yunq.server.h +++ b/yunq/example.yunq.server.h @@ -1,19 +1,23 @@ // Generated File -- DO NOT MODIFY. #pragma once +#include #include #include #include "example.yunq.h" +#include "example.yunq.client.h" class VFSServerBase { public: - VFSServerBase(z_cap_t VFS_cap) : {} + VFSServerBase(z_cap_t VFS_cap) : endpoint_(VFS_cap) {} VFSServerBase(const VFSServerBase&) = delete; VFSServerBase(VFSServerBase&&) = delete; + glcr::ErrorOr CreateClient(); + [[nodiscard]] Thread RunServer(); @@ -27,6 +31,7 @@ class VFSServerBase { void ServerThread(); [[nodiscard]] glcr::ErrorCode HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response, + uint64_t& resp_length, glcr::CapBuffer& resp_caps); }; diff --git a/yunq/message.cpp.jinja b/yunq/message.cpp.jinja index 4293708..34abcdd 100644 --- a/yunq/message.cpp.jinja +++ b/yunq/message.cpp.jinja @@ -74,7 +74,7 @@ void {{message.name}}::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t of {%- endfor %} } -uint64_t {{message.name}}::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) { +uint64_t {{message.name}}::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { uint32_t next_extension = header_size + 8 * {{ message.fields | length }}; const uint32_t core_size = next_extension; @@ -109,7 +109,7 @@ uint64_t {{message.name}}::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t of return next_extension; } -uint64_t {{message.name}}::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) { +uint64_t {{message.name}}::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { uint32_t next_extension = header_size + 8 * {{ message.fields | length}}; const uint32_t core_size = next_extension; uint64_t next_cap = 0; diff --git a/yunq/message.h.jinja b/yunq/message.h.jinja index bf684be..68adbfb 100644 --- a/yunq/message.h.jinja +++ b/yunq/message.h.jinja @@ -17,11 +17,11 @@ class {{message.name}} { void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset); void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&); + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; {%- for field in message.fields %} - {{field.cpp_type()}} {{field.name}}() { return {{field.name}}_; } + {{field.cpp_type()}} {{field.name}}() const { return {{field.name}}_; } void set_{{field.name}}(const {{field.cpp_type()}}& value) { {{field.name}}_ = value; } {%- endfor %} diff --git a/yunq/server.cpp.jinja b/yunq/server.cpp.jinja index 57d95e9..04af05d 100644 --- a/yunq/server.cpp.jinja +++ b/yunq/server.cpp.jinja @@ -26,14 +26,21 @@ void WriteHeader(glcr::ByteBuffer& buffer, uint64_t message_length) { {% for interface in interfaces %} void {{interface.name}}ServerBaseThreadBootstrap(void* server_base) { - ({{interface.name}}ServerBase*)(server_base)->ServerThread(); + (({{interface.name}}ServerBase*)server_base)->ServerThread(); } -Thread {{interface.name}}::RunServer() { +glcr::ErrorOr<{{interface.name}}Client> {{interface.name}}ServerBase::CreateClient() { + uint64_t client_cap; + // FIXME: Restrict permissions to send-only here. + RET_ERR(ZCapDuplicate(endpoint_, &client_cap)); + return {{interface.name}}Client(client_cap); +} + +Thread {{interface.name}}ServerBase::RunServer() { return Thread({{interface.name}}ServerBaseThreadBootstrap, this); } -void {{interface.name}}::ServerThread() { +void {{interface.name}}ServerBase::ServerThread() { glcr::ByteBuffer recv_buffer(0x1000); glcr::ByteBuffer resp_buffer(0x1000); uint64_t resp_cap_size = 0x10; @@ -50,37 +57,42 @@ void {{interface.name}}::ServerThread() { uint64_t resp_length = 0; - glcr::ErrorCode err = HandlRequest(recv_buffer, resp_buffer, resp_length, resp_cap); + glcr::ErrorCode reply_err = glcr::OK; + glcr::ErrorCode err = HandleRequest(recv_buffer, resp_buffer, resp_length, resp_cap); if (err != glcr::OK) { WriteError(resp_buffer, err); - ZReplyPortSend(reply_port_cap, kHeaderSize, resp_buffer.RawPtr(), 0, nullptr); + reply_err = ZReplyPortSend(reply_port_cap, kHeaderSize, resp_buffer.RawPtr(), 0, nullptr); } else { WriteHeader(resp_buffer, resp_length); - ZReplyPortSend(reply_port_cap, resp_length, resp_buffer.RawPtr(), resp_cap.UsedSlots(), resp_cap.RawPtr()); + reply_err = ZReplyPortSend(reply_port_cap, kHeaderSize + resp_length, resp_buffer.RawPtr(), resp_cap.UsedSlots(), resp_cap.RawPtr()); + } + if (reply_err != glcr::OK) { + dbgln("Error in reply: %x", recv_err); } } } -glcr::ErrorCode {{interface.name}}::HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response, uint64_t& resp_length - glcr::CapBuffer& resp_caps) { - if (recv_buffer.At(0) != kSentinel) { - return glcr::INVALID_INPUT; +glcr::ErrorCode {{interface.name}}ServerBase::HandleRequest(const glcr::ByteBuffer& request, + glcr::ByteBuffer& response, uint64_t& resp_length, + glcr::CapBuffer& resp_caps) { + if (request.At(0) != kSentinel) { + return glcr::INVALID_ARGUMENT; } - uint64_t method_select = recv_buffer.At(8); + uint64_t method_select = request.At(8); switch(method_select) { {%- for method in interface.methods %} case {{loop.index0}}: { - {{method.request}} request; - {{method.response}} response; + {{method.request}} yunq_request; + {{method.response}} yunq_response; - request.ParseFromBytes(recv_buffer, kHeaderSize); + yunq_request.ParseFromBytes(request, kHeaderSize); - RET_ERR(Handle{{method.name}}(request, response)); + RET_ERR(Handle{{method.name}}(yunq_request, yunq_response)); - resp_length = response.SerializeToBytes(resp_buffer, kHeaderSize, resp_cap); + resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); break; } {%- endfor %} diff --git a/yunq/server.h.jinja b/yunq/server.h.jinja index a50e6ce..a314a69 100644 --- a/yunq/server.h.jinja +++ b/yunq/server.h.jinja @@ -1,19 +1,23 @@ // Generated File -- DO NOT MODIFY. #pragma once +#include #include #include #include "{{file}}.h" +#include "{{file}}.client.h" {% for interface in interfaces %} class {{interface.name}}ServerBase { public: - {{interface.name}}ServerBase(z_cap_t {{interface.name}}_cap) : {} + {{interface.name}}ServerBase(z_cap_t {{interface.name}}_cap) : endpoint_({{interface.name}}_cap) {} {{interface.name}}ServerBase(const {{interface.name}}ServerBase&) = delete; {{interface.name}}ServerBase({{interface.name}}ServerBase&&) = delete; + glcr::ErrorOr<{{interface.name}}Client> CreateClient(); + [[nodiscard]] Thread RunServer(); {% for method in interface.methods %} @@ -27,6 +31,7 @@ class {{interface.name}}ServerBase { void ServerThread(); [[nodiscard]] glcr::ErrorCode HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response, + uint64_t& resp_length, glcr::CapBuffer& resp_caps); }; diff --git a/yunq/yunq.py b/yunq/yunq.py index 874380b..ba83a90 100755 --- a/yunq/yunq.py +++ b/yunq/yunq.py @@ -55,7 +55,7 @@ def main(): server_impl_tmpl = jinja_env.get_template("server.cpp.jinja") with open(filename + '.server.cpp', mode='w') as f: - server_impl = client_impl_tmpl.render(file=filename, interfaces=interfaces) + server_impl = server_impl_tmpl.render(file=filename, interfaces=interfaces) f.write(server_impl) if __name__ == "__main__":