X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/94b0b3e5b9dbe5ce24c4606fc22a961a41ebb088..b44af625f87066e90b1815ddcc84ee43c5bbce71:/Cytore.hpp diff --git a/Cytore.hpp b/Cytore.hpp index 62e956c0..168f2ef5 100644 --- a/Cytore.hpp +++ b/Cytore.hpp @@ -52,9 +52,6 @@ struct Header { uint32_t reserved_; }; -struct Block { -}; - template class Offset { private: @@ -85,6 +82,10 @@ class Offset { } }; +struct Block { + Cytore::Offset reserved_; +}; + template static _finline Type_ Round(Type_ value, Type_ size) { Type_ mask(size - 1); @@ -100,7 +101,23 @@ class File { private: int file_; - std::vector blocks_; + + typedef std::vector BlockVector_; + BlockVector_ blocks_; + + struct Mapping_ { + uint8_t *data_; + size_t size_; + + Mapping_(uint8_t *data, size_t size) : + data_(data), + size_(size) + { + } + }; + + typedef std::vector MappingVector_; + MappingVector_ maps_; Header &Header_() { return *reinterpret_cast
(blocks_[0]); @@ -115,14 +132,23 @@ class File { size_t extend(size - before); void *data(mmap(NULL, extend, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, file_, before)); + _assert(data != MAP_FAILED); + uint8_t *bytes(reinterpret_cast(data)); + + maps_.push_back(Mapping_(bytes, extend)); for (size_t i(0); i != extend >> Shift_; ++i) - blocks_.push_back(reinterpret_cast(data) + Block_ * i); + blocks_.push_back(bytes + Block_ * i); } - void Truncate_(size_t capacity) { + bool Truncate_(size_t capacity) { capacity = Round(capacity, Block_); - ftruncate(file_, capacity); + + int error(ftruncate(file_, capacity)); + if (error != 0) + return false; + Map_(capacity); + return true; } public: @@ -138,10 +164,16 @@ class File { } ~File() { - // XXX: this object is never deconstructed. if it were, this should unmap the memory + for (typename MappingVector_::const_iterator map(maps_.begin()); map != maps_.end(); ++map) + munmap(map->data_, map->size_); close(file_); } + void Sync() { + for (typename MappingVector_::const_iterator map(maps_.begin()); map != maps_.end(); ++map) + msync(map->data_, map->size_, MS_SYNC); + } + size_t Capacity() const { return blocks_.size() * Block_; } @@ -149,35 +181,45 @@ class File { void Open(const char *path) { _assert(file_ == -1); file_ = open(path, O_RDWR | O_CREAT | O_EXLOCK, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + _assert(file_ != -1); struct stat stat; - fstat(file_, &stat); + _assert(fstat(file_, &stat) == 0); size_t core(sizeof(Header) + sizeof(Base_)); size_t size(stat.st_size); if (size == 0) { - Truncate_(core); + _assert(Truncate_(core)); Header_().magic_ = Magic; Size_() = core; } else { _assert(size >= core); - Truncate_(size); + // XXX: this involves an unneccessary call to ftruncate() + _assert(Truncate_(size)); _assert(Header_().magic_ == Magic); _assert(Header_().version_ == 0); } } - void Reserve(size_t capacity) { + bool Reserve(size_t capacity) { if (capacity <= Capacity()) - return; + return true; + + uint8_t *block(blocks_.back()); blocks_.pop_back(); - Truncate_(capacity); + + if (Truncate_(capacity)) + return true; + else { + blocks_.push_back(block); + return false; + } } template Target_ &Get(uint32_t offset) { - return *reinterpret_cast(blocks_[offset >> Shift_] + (offset & Mask_)); + return *reinterpret_cast(offset == 0 ? NULL : blocks_[offset >> Shift_] + (offset & Mask_)); } template @@ -193,9 +235,15 @@ class File { Offset New(size_t extra = 0) { size_t size(sizeof(Target_) + extra); size = Round(size, sizeof(uintptr_t)); - Reserve(Size_() + size); - uint32_t offset(Size_()); - Size_() += size; + + uint32_t offset; + if (!Reserve(Size_() + size)) + offset = 0; + else { + offset = Size_(); + Size_() += size; + } + return Offset(offset); } };