used as a read only into a shared cache. The cache is owned by another process and we peek into the items in the cache based on their offsets.
| 33 | // used as a read only into a shared cache. The cache is owned by another |
| 34 | // process and we peek into the items in the cache based on their offsets. |
| 35 | class ReadOnlySharedCacheView { |
| 36 | public: |
| 37 | // tries to attach to an existing cache with the cacheDir if present under |
| 38 | // the correct shm mode. |
| 39 | // |
| 40 | // @param cacheDir the directory that identifies the cache |
| 41 | // @param usePosix the posix compatbility status of original cache. This |
| 42 | // would be part of the config that was used to |
| 43 | // initialize the cache |
| 44 | // @param addr starting address that this segment should be mapped to |
| 45 | // (exception will be thrown if it is not mounted to the |
| 46 | // given address) |
| 47 | // if nullptr, the segment will be mapped to a random |
| 48 | // address chosen by the kernel |
| 49 | explicit ReadOnlySharedCacheView(const std::string& cacheDir, |
| 50 | bool usePosixShm, |
| 51 | void* addr = nullptr) |
| 52 | : shm_(ShmManager::attachShmReadOnly( |
| 53 | cacheDir, detail::kShmCacheName, usePosixShm, addr)) {} |
| 54 | |
| 55 | // returns the absolute address at which the shared memory mapping is mounted. |
| 56 | // The caller can add a relative offset obtained from |
| 57 | // CacheAllocator::getItemPtrAsOffset to this address in order to compute the |
| 58 | // address at which that item is stored (within the process which manages this |
| 59 | // ReadOnlySharedCacheView). |
| 60 | uintptr_t getShmMappingAddress() const noexcept { |
| 61 | auto mapping = shm_->getCurrentMapping(); |
| 62 | return reinterpret_cast<uintptr_t>(mapping.addr); |
| 63 | } |
| 64 | |
| 65 | // computes an aboslute address in the cache, given a relative offset that |
| 66 | // was obtained from CacheAllocator::getItemPtrAsOffset. It is the caller's |
| 67 | // responsibility to ensure the memory backing the offset corresponds to an |
| 68 | // active ItemHandle in the system. |
| 69 | // |
| 70 | // Returns a valid pointer if the offset is valid. Returns nullptr if no |
| 71 | // shared memory mapping is mounted. Throws if the given offset is invalid. |
| 72 | const void* getItemPtrFromOffset(uintptr_t offset) { |
| 73 | auto mapping = shm_->getCurrentMapping(); |
| 74 | if (mapping.addr == nullptr) { |
| 75 | return nullptr; |
| 76 | } |
| 77 | |
| 78 | if (offset >= mapping.size) { |
| 79 | throw std::invalid_argument(fmt::format( |
| 80 | "Invalid offset {} with mapping of size {}", offset, mapping.size)); |
| 81 | } |
| 82 | return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(mapping.addr) + |
| 83 | offset); |
| 84 | } |
| 85 | |
| 86 | private: |
| 87 | // the segment backing the cache |
| 88 | std::unique_ptr<ShmSegment> shm_; |
| 89 | }; |
| 90 | |
| 91 | } // namespace cachelib |
| 92 | } // namespace facebook |
no outgoing calls