[mammoth] Move EndpointClient to move-only semantics.

This commit is contained in:
Drew Galbraith 2023-06-26 11:54:36 -07:00
parent 2e89aee5a3
commit 90f33f31c5
15 changed files with 44 additions and 30 deletions

View File

@ -17,6 +17,7 @@ class UniquePtr {
T* temp = ptr_; T* temp = ptr_;
ptr_ = other.ptr_; ptr_ = other.ptr_;
other.ptr_ = temp; other.ptr_ = temp;
return *this;
} }
~UniquePtr() { ~UniquePtr() {
@ -45,7 +46,7 @@ class UniquePtr {
template <typename T, typename... Args> template <typename T, typename... Args>
UniquePtr<T> MakeUnique(Args... args) { UniquePtr<T> MakeUnique(Args... args) {
return UniquePtr(new T(args...)); return UniquePtr<T>(new T(args...));
} }
} // namespace glcr } // namespace glcr

View File

@ -1,13 +1,18 @@
#pragma once #pragma once
#include <glacier/container/pair.h> #include <glacier/container/pair.h>
#include <glacier/memory/unique_ptr.h>
#include <glacier/status/error_or.h> #include <glacier/status/error_or.h>
#include <zcall.h> #include <zcall.h>
#include <ztypes.h> #include <ztypes.h>
class EndpointClient { class EndpointClient {
public: public:
static EndpointClient AdoptEndpoint(z_cap_t cap); EndpointClient() = delete;
EndpointClient(const EndpointClient&) = delete;
EndpointClient& operator=(const EndpointClient&) = delete;
static glcr::UniquePtr<EndpointClient> AdoptEndpoint(z_cap_t cap);
template <typename Req, typename Resp> template <typename Req, typename Resp>
glcr::ErrorOr<glcr::Pair<Resp, z_cap_t>> CallEndpoint(const Req& req); glcr::ErrorOr<glcr::Pair<Resp, z_cap_t>> CallEndpoint(const Req& req);

View File

@ -15,7 +15,7 @@ class EndpointServer {
static glcr::ErrorOr<glcr::UniquePtr<EndpointServer>> Create(); static glcr::ErrorOr<glcr::UniquePtr<EndpointServer>> Create();
static glcr::UniquePtr<EndpointServer> Adopt(z_cap_t endpoint_cap); static glcr::UniquePtr<EndpointServer> Adopt(z_cap_t endpoint_cap);
glcr::ErrorOr<EndpointClient> CreateClient(); glcr::ErrorOr<glcr::UniquePtr<EndpointClient>> CreateClient();
// FIXME: Release Cap here. // FIXME: Release Cap here.
z_cap_t GetCap() { return endpoint_cap_; } z_cap_t GetCap() { return endpoint_cap_; }

View File

@ -5,5 +5,5 @@
#include "mammoth/endpoint_client.h" #include "mammoth/endpoint_client.h"
glcr::ErrorCode SpawnProcessFromElfRegion(uint64_t program, glcr::ErrorCode SpawnProcessFromElfRegion(
EndpointClient client); uint64_t program, glcr::UniquePtr<EndpointClient> client);

View File

@ -1,3 +1,5 @@
#include "mammoth/endpoint_server.h" #include "mammoth/endpoint_server.h"
EndpointClient EndpointClient::AdoptEndpoint(z_cap_t cap) { return {cap}; } glcr::UniquePtr<EndpointClient> EndpointClient::AdoptEndpoint(z_cap_t cap) {
return glcr::UniquePtr<EndpointClient>(new EndpointClient(cap));
}

View File

@ -10,7 +10,7 @@ glcr::UniquePtr<EndpointServer> EndpointServer::Adopt(z_cap_t endpoint_cap) {
return glcr::UniquePtr<EndpointServer>(new EndpointServer(endpoint_cap)); return glcr::UniquePtr<EndpointServer>(new EndpointServer(endpoint_cap));
} }
glcr::ErrorOr<EndpointClient> EndpointServer::CreateClient() { glcr::ErrorOr<glcr::UniquePtr<EndpointClient>> EndpointServer::CreateClient() {
uint64_t client_cap; uint64_t client_cap;
// FIXME: Restrict permissions to send-only here. // FIXME: Restrict permissions to send-only here.
RET_ERR(ZCapDuplicate(endpoint_cap_, &client_cap)); RET_ERR(ZCapDuplicate(endpoint_cap_, &client_cap));

View File

@ -96,8 +96,8 @@ uint64_t LoadElfProgram(uint64_t base, uint64_t as_cap) {
} // namespace } // namespace
glcr::ErrorCode SpawnProcessFromElfRegion(uint64_t program, glcr::ErrorCode SpawnProcessFromElfRegion(
EndpointClient client) { uint64_t program, glcr::UniquePtr<EndpointClient> client) {
uint64_t proc_cap; uint64_t proc_cap;
uint64_t as_cap; uint64_t as_cap;
uint64_t foreign_port_id; uint64_t foreign_port_id;
@ -125,7 +125,7 @@ glcr::ErrorCode SpawnProcessFromElfRegion(uint64_t program,
RET_ERR(pclient.WriteMessage<uint64_t>(Z_INIT_SELF_PROC, proc_cap)); RET_ERR(pclient.WriteMessage<uint64_t>(Z_INIT_SELF_PROC, proc_cap));
RET_ERR(pclient.WriteMessage<uint64_t>(Z_INIT_SELF_VMAS, as_cap)); RET_ERR(pclient.WriteMessage<uint64_t>(Z_INIT_SELF_VMAS, as_cap));
RET_ERR(pclient.WriteMessage<uint64_t>(Z_INIT_ENDPOINT, client.GetCap())); RET_ERR(pclient.WriteMessage<uint64_t>(Z_INIT_ENDPOINT, client->GetCap()));
#if MAM_PROC_DEBUG #if MAM_PROC_DEBUG
dbgln("Thread start"); dbgln("Thread start");

View File

@ -11,7 +11,7 @@ glcr::ErrorOr<MappedMemoryRegion> DenaliClient::ReadSectors(
.lba = lba, .lba = lba,
.size = num_sectors, .size = num_sectors,
}; };
auto pair_or = endpoint_.CallEndpoint<DenaliRead, DenaliReadResponse>(read); auto pair_or = endpoint_->CallEndpoint<DenaliRead, DenaliReadResponse>(read);
if (!pair_or) { if (!pair_or) {
return pair_or.error(); return pair_or.error();
} }

View File

@ -14,13 +14,15 @@ uint64_t main(uint64_t init_port_cap) {
AhciDriver driver; AhciDriver driver;
RET_ERR(driver.Init()); RET_ERR(driver.Init());
EndpointClient yellowstone = EndpointClient::AdoptEndpoint(gInitEndpointCap); glcr::UniquePtr<EndpointClient> yellowstone =
EndpointClient::AdoptEndpoint(gInitEndpointCap);
YellowstoneGetReq req{ YellowstoneGetReq req{
.type = kYellowstoneGetRegistration, .type = kYellowstoneGetRegistration,
}; };
auto resp_cap_or = auto resp_cap_or =
yellowstone yellowstone
.CallEndpoint<YellowstoneGetReq, YellowstoneGetRegistrationResp>(req); ->CallEndpoint<YellowstoneGetReq, YellowstoneGetRegistrationResp>(
req);
if (!resp_cap_or.ok()) { if (!resp_cap_or.ok()) {
dbgln("Bad call"); dbgln("Bad call");
check(resp_cap_or.error()); check(resp_cap_or.error());
@ -30,8 +32,9 @@ uint64_t main(uint64_t init_port_cap) {
ASSIGN_OR_RETURN(glcr::UniquePtr<EndpointServer> endpoint, ASSIGN_OR_RETURN(glcr::UniquePtr<EndpointServer> endpoint,
EndpointServer::Create()); EndpointServer::Create());
ASSIGN_OR_RETURN(EndpointClient client, endpoint->CreateClient()); ASSIGN_OR_RETURN(glcr::UniquePtr<EndpointClient> client,
notify.WriteMessage("denali", client.GetCap()); endpoint->CreateClient());
notify.WriteMessage("denali", client->GetCap());
DenaliServer server(glcr::Move(endpoint), driver); DenaliServer server(glcr::Move(endpoint), driver);
RET_ERR(server.RunServer()); RET_ERR(server.RunServer());

View File

@ -6,12 +6,13 @@
class DenaliClient { class DenaliClient {
public: public:
DenaliClient(const EndpointClient& endpoint) : endpoint_(endpoint) {} DenaliClient(glcr::UniquePtr<EndpointClient> endpoint)
: endpoint_(glcr::Move(endpoint)) {}
glcr::ErrorOr<MappedMemoryRegion> ReadSectors(uint64_t device_id, glcr::ErrorOr<MappedMemoryRegion> ReadSectors(uint64_t device_id,
uint64_t lba, uint64_t lba,
uint64_t num_sectors); uint64_t num_sectors);
private: private:
EndpointClient endpoint_; glcr::UniquePtr<EndpointClient> endpoint_;
}; };

View File

@ -47,11 +47,12 @@ struct PartitionEntry {
char partition_name[72]; char partition_name[72];
} __attribute__((packed)); } __attribute__((packed));
GptReader::GptReader(const DenaliClient& client) : denali_(client) {} GptReader::GptReader(glcr::UniquePtr<DenaliClient> denali)
: denali_(glcr::Move(denali)) {}
glcr::ErrorCode GptReader::ParsePartitionTables() { glcr::ErrorCode GptReader::ParsePartitionTables() {
ASSIGN_OR_RETURN(MappedMemoryRegion lba_1_and_2, ASSIGN_OR_RETURN(MappedMemoryRegion lba_1_and_2,
denali_.ReadSectors(0, 0, 2)); denali_->ReadSectors(0, 0, 2));
uint16_t* mbr_sig = reinterpret_cast<uint16_t*>(lba_1_and_2.vaddr() + 0x1FE); uint16_t* mbr_sig = reinterpret_cast<uint16_t*>(lba_1_and_2.vaddr() + 0x1FE);
if (*mbr_sig != 0xAA55) { if (*mbr_sig != 0xAA55) {
return glcr::FAILED_PRECONDITION; return glcr::FAILED_PRECONDITION;
@ -86,7 +87,7 @@ glcr::ErrorCode GptReader::ParsePartitionTables() {
ASSIGN_OR_RETURN( ASSIGN_OR_RETURN(
MappedMemoryRegion part_table, MappedMemoryRegion part_table,
denali_.ReadSectors(0, header->lba_partition_entries, num_blocks)); denali_->ReadSectors(0, header->lba_partition_entries, num_blocks));
dbgln("Entries"); dbgln("Entries");
for (uint64_t i = 0; i < num_partitions; i++) { for (uint64_t i = 0; i < num_partitions; i++) {
PartitionEntry* entry = reinterpret_cast<PartitionEntry*>( PartitionEntry* entry = reinterpret_cast<PartitionEntry*>(

View File

@ -6,10 +6,10 @@
class GptReader { class GptReader {
public: public:
GptReader(const DenaliClient&); GptReader(glcr::UniquePtr<DenaliClient> denali);
glcr::ErrorCode ParsePartitionTables(); glcr::ErrorCode ParsePartitionTables();
private: private:
DenaliClient denali_; glcr::UniquePtr<DenaliClient> denali_;
}; };

View File

@ -19,12 +19,13 @@ uint64_t main(uint64_t port_cap) {
uint64_t vaddr; uint64_t vaddr;
check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootDenaliVmmoCap, &vaddr)); check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootDenaliVmmoCap, &vaddr));
ASSIGN_OR_RETURN(EndpointClient client, server->GetServerClient()); ASSIGN_OR_RETURN(glcr::UniquePtr<EndpointClient> client,
check(SpawnProcessFromElfRegion(vaddr, client)); server->GetServerClient());
check(SpawnProcessFromElfRegion(vaddr, glcr::Move(client)));
check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootVictoriaFallsVmmoCap, &vaddr)); check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootVictoriaFallsVmmoCap, &vaddr));
ASSIGN_OR_RETURN(client, server->GetServerClient()); ASSIGN_OR_RETURN(client, server->GetServerClient());
check(SpawnProcessFromElfRegion(vaddr, client)); check(SpawnProcessFromElfRegion(vaddr, glcr::Move(client)));
check(server_thread.Join()); check(server_thread.Join());
check(registration_thread.Join()); check(registration_thread.Join());

View File

@ -21,9 +21,8 @@ void RegistrationThreadBootstrap(void* yellowstone) {
} }
glcr::ErrorCode HandleDenaliRegistration(z_cap_t endpoint_cap) { glcr::ErrorCode HandleDenaliRegistration(z_cap_t endpoint_cap) {
EndpointClient endpoint = EndpointClient::AdoptEndpoint(endpoint_cap); GptReader reader(glcr::UniquePtr<DenaliClient>(
DenaliClient client(endpoint); new DenaliClient(EndpointClient::AdoptEndpoint(endpoint_cap))));
GptReader reader(client);
return reader.ParsePartitionTables(); return reader.ParsePartitionTables();
} }
@ -103,6 +102,7 @@ void YellowstoneServer::RegistrationThread() {
} }
} }
glcr::ErrorOr<EndpointClient> YellowstoneServer::GetServerClient() { glcr::ErrorOr<glcr::UniquePtr<EndpointClient>>
YellowstoneServer::GetServerClient() {
return server_->CreateClient(); return server_->CreateClient();
} }

View File

@ -16,7 +16,7 @@ class YellowstoneServer {
void ServerThread(); void ServerThread();
void RegistrationThread(); void RegistrationThread();
glcr::ErrorOr<EndpointClient> GetServerClient(); glcr::ErrorOr<glcr::UniquePtr<EndpointClient>> GetServerClient();
private: private:
glcr::UniquePtr<EndpointServer> server_; glcr::UniquePtr<EndpointServer> server_;