#pragma once #include #include #include "capability/capability.h" #include "debug/debug.h" #include "object/mutex.h" class CapabilityTable { public: CapabilityTable(); CapabilityTable(CapabilityTable&) = delete; CapabilityTable& operator=(CapabilityTable&) = delete; template z_cap_t AddNewCapability(const glcr::RefPtr& object, uint64_t permissions); template z_cap_t AddNewCapability(const glcr::RefPtr& object) { return AddNewCapability(object, T::DefaultPermissions()); } z_cap_t AddExistingCapability(const glcr::RefPtr& cap); glcr::RefPtr GetCapability(uint64_t id); glcr::RefPtr ReleaseCapability(uint64_t id); void ReleaseAll(); private: glcr::RefPtr lock_ = Mutex::Create(); // TODO: Do some randomization. uint64_t next_cap_id_ = 0x100; // TODO: Consider not holding a uniqueptr here instead of a refptr? glcr::HashMap> capabilities_; }; template uint64_t CapabilityTable::AddNewCapability(const glcr::RefPtr& object, uint64_t permissions) { MutexHolder h(lock_); uint64_t id = next_cap_id_++; if (capabilities_.Insert( id, MakeRefCounted(object, permissions)) != glcr::OK) { panic("Reusing capability id {}", id); } return id; }