# HG changeset patch # User Paul Boddie # Date 1617227691 -7200 # Node ID af0790b18e8ff9fe90842440a466fc38f21dd6fe # Parent 1d24a4fff0bd0982859925932cd557f8bb995719 Incorporated the paging abstraction in opener abstractions, introducing critical sections around the retrieval and disposal of page mappers and accessors, also discarding page mappers and accessors when disposal occurs. diff -r 1d24a4fff0bd -r af0790b18e8f accessor.h --- a/accessor.h Wed Mar 31 01:06:22 2021 +0200 +++ b/accessor.h Wed Mar 31 23:54:51 2021 +0200 @@ -20,6 +20,10 @@ explicit Accessor(fileid_t fileid, offset_t size=0); + virtual ~Accessor() + { + } + virtual offset_t get_size(); virtual void set_size(offset_t size); diff -r 1d24a4fff0bd -r af0790b18e8f dstest_block_server.cc --- a/dstest_block_server.cc Wed Mar 31 01:06:22 2021 +0200 +++ b/dstest_block_server.cc Wed Mar 31 23:54:51 2021 +0200 @@ -30,7 +30,6 @@ #include "memory_utils.h" #include "page_queue_shared.h" #include "pages.h" -#include "paging.h" #include "resource_server.h" #include "block_file_opener.h" @@ -43,10 +42,9 @@ /* Some memory plus infrastructure. */ MemoryIncremental mem(MEMORY_PAGES); - Paging paging; PageQueueShared queue; Pages pages(&mem, &queue); - BlockFileOpener opener(&paging, &pages); + BlockFileOpener opener(&pages); /* Register a server associating it with the given object. */ diff -r 1d24a4fff0bd -r af0790b18e8f dstest_host_server.cc --- a/dstest_host_server.cc Wed Mar 31 01:06:22 2021 +0200 +++ b/dstest_host_server.cc Wed Mar 31 23:54:51 2021 +0200 @@ -30,7 +30,6 @@ #include "memory_utils.h" #include "page_queue_shared.h" #include "pages.h" -#include "paging.h" #include "resource_server.h" #include "host_file_opener.h" @@ -43,10 +42,9 @@ /* Some memory plus infrastructure. */ MemoryIncremental mem(MEMORY_PAGES); - Paging paging; PageQueueShared queue; Pages pages(&mem, &queue); - HostFileOpener opener(&paging, &pages); + HostFileOpener opener(&pages); /* Register a server associating it with the given object. */ diff -r 1d24a4fff0bd -r af0790b18e8f dstest_test_server.cc --- a/dstest_test_server.cc Wed Mar 31 01:06:22 2021 +0200 +++ b/dstest_test_server.cc Wed Mar 31 23:54:51 2021 +0200 @@ -32,7 +32,6 @@ #include "memory_utils.h" #include "page_queue_shared.h" #include "pages.h" -#include "paging.h" #include "resource_server.h" #include "test_file_opener.h" @@ -66,10 +65,9 @@ /* Some memory plus infrastructure. */ MemoryIncremental mem(memory_pages, page(REGION_PAGES)); - Paging paging; PageQueueShared queue; Pages pages(&mem, &queue); - TestFileOpener opener(&paging, &pages, page(FILE_PAGES)); + TestFileOpener opener(&pages, page(FILE_PAGES)); /* Register a server associating it with the given object. */ diff -r 1d24a4fff0bd -r af0790b18e8f files/block_file_opener.h --- a/files/block_file_opener.h Wed Mar 31 01:06:22 2021 +0200 +++ b/files/block_file_opener.h Wed Mar 31 23:54:51 2021 +0200 @@ -14,8 +14,8 @@ virtual Accessor *make_accessor(fileid_t fileid); public: - explicit BlockFileOpener(Paging *paging, Pages *pages) - : HostFileOpener(paging, pages) + explicit BlockFileOpener(Pages *pages) + : HostFileOpener(pages) { } }; diff -r 1d24a4fff0bd -r af0790b18e8f files/file_pager.cc --- a/files/file_pager.cc Wed Mar 31 01:06:22 2021 +0200 +++ b/files/file_pager.cc Wed Mar 31 23:54:51 2021 +0200 @@ -4,8 +4,9 @@ /* Initialise a pager for a file with a unique file identifier and shared page mapper for moderating access to loaded pages. */ -FilePager::FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags) -: Pager(mapper, flags), fileid(fileid) +FilePager::FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags, + Paging *paging) +: Pager(mapper, flags), _paging(paging), fileid(fileid) { } @@ -21,6 +22,16 @@ +/* Close the pager, removing the mapper from the paging registry if + appropriate. */ + +void FilePager::close() +{ + _paging->detach_pager(fileid, _mapper); +} + + + /* File-specific operations. */ long FilePager::flush(offset_t populated_size, offset_t *size) diff -r 1d24a4fff0bd -r af0790b18e8f files/file_pager.h --- a/files/file_pager.h Wed Mar 31 01:06:22 2021 +0200 +++ b/files/file_pager.h Wed Mar 31 23:54:51 2021 +0200 @@ -2,15 +2,22 @@ #include "mapped_file_object_interface.h" #include "pager.h" +#include "paging.h" /* A pager abstraction for a file. */ class FilePager : public Pager, public MappedFileObject { +protected: + Paging *_paging; + public: fileid_t fileid; - explicit FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags); + explicit FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags, + Paging *paging); + + virtual void close(); /* Server details. */ diff -r 1d24a4fff0bd -r af0790b18e8f files/host_file_opener.h --- a/files/host_file_opener.h Wed Mar 31 01:06:22 2021 +0200 +++ b/files/host_file_opener.h Wed Mar 31 23:54:51 2021 +0200 @@ -27,8 +27,8 @@ virtual Accessor *make_accessor(fileid_t fileid); public: - explicit HostFileOpener(Paging *paging, Pages *pages) - : OpenerResource(paging, pages) + explicit HostFileOpener(Pages *pages) + : OpenerResource(pages) { } }; diff -r 1d24a4fff0bd -r af0790b18e8f files/opener_context_resource.cc --- a/files/opener_context_resource.cc Wed Mar 31 01:06:22 2021 +0200 +++ b/files/opener_context_resource.cc Wed Mar 31 23:54:51 2021 +0200 @@ -52,7 +52,7 @@ if (path == NULL) return -L4_EINVAL; - FilePager *pager = _opener->open(path, flags); + Pager *pager = _opener->open(path, flags); /* Complete the initialisation and start a server in a new thread. If the thread does not start, the resource should be finalised. */ diff -r 1d24a4fff0bd -r af0790b18e8f files/opener_resource.cc --- a/files/opener_resource.cc Wed Mar 31 01:06:22 2021 +0200 +++ b/files/opener_resource.cc Wed Mar 31 23:54:51 2021 +0200 @@ -4,8 +4,8 @@ /* Support for providing access to files. */ -OpenerResource::OpenerResource(Paging *paging, Pages *pages) -: _paging(paging), _pages(pages) +OpenerResource::OpenerResource(Pages *pages) +: Paging(pages) { } @@ -23,34 +23,14 @@ /* Return a pager object for the given path and flags. */ -FilePager *OpenerResource::open(const char *path, flags_t flags) +Pager *OpenerResource::open(const char *path, flags_t flags) { fileid_t fileid = get_fileid(path); if (fileid == FILEID_INVALID) return NULL; - PageMapper *mapper = get_mapper(fileid); - return new FilePager(fileid, mapper, flags); -} - -/* Obtain a page mapper for the 'fileid' or register a new one in the - paging object. */ - -PageMapper *OpenerResource::get_mapper(fileid_t fileid) -{ - PageMapper *mapper; - - if (_paging->reserve(fileid)) - mapper = _paging->get(fileid); - else - { - Accessor *accessor = make_accessor(fileid); - mapper = new PageMapper(accessor, _pages); - _paging->set(fileid, mapper); - } - - return mapper; + return get_pager(fileid, flags); } diff -r 1d24a4fff0bd -r af0790b18e8f files/opener_resource.h --- a/files/opener_resource.h Wed Mar 31 01:06:22 2021 +0200 +++ b/files/opener_resource.h Wed Mar 31 23:54:51 2021 +0200 @@ -2,34 +2,18 @@ #include -#include "file_pager.h" #include "opener_context_resource.h" #include "opener_interface.h" -#include "pager.h" #include "paging.h" #include "pages.h" #include "resource.h" /* Support for providing access to files. */ -class OpenerResource : public Resource, public Opener +class OpenerResource : public Resource, public Paging, public Opener { -protected: - Paging *_paging; - Pages *_pages; - - /* Convenience methods. */ - - PageMapper *get_mapper(fileid_t fileid); - - /* Configurable methods. */ - - virtual fileid_t get_fileid(const char *path) = 0; - - virtual Accessor *make_accessor(fileid_t fileid) = 0; - public: - explicit OpenerResource(Paging *paging, Pages *pages); + explicit OpenerResource(Pages *pages); /* Server details. */ @@ -42,7 +26,7 @@ /* Direct access methods. */ - FilePager *open(const char *path, flags_t flags); + Pager *open(const char *path, flags_t flags); /* Opener interface methods. */ diff -r 1d24a4fff0bd -r af0790b18e8f files/test_file_opener.cc --- a/files/test_file_opener.cc Wed Mar 31 01:06:22 2021 +0200 +++ b/files/test_file_opener.cc Wed Mar 31 23:54:51 2021 +0200 @@ -5,9 +5,8 @@ /* Support for providing access to files. */ -TestFileOpener::TestFileOpener(Paging *paging, Pages *pages, - offset_t file_size) -: OpenerResource(paging, pages), _file_size(file_size) +TestFileOpener::TestFileOpener(Pages *pages, offset_t file_size) +: OpenerResource(pages), _file_size(file_size) { } diff -r 1d24a4fff0bd -r af0790b18e8f files/test_file_opener.h --- a/files/test_file_opener.h Wed Mar 31 01:06:22 2021 +0200 +++ b/files/test_file_opener.h Wed Mar 31 23:54:51 2021 +0200 @@ -16,7 +16,7 @@ virtual Accessor *make_accessor(fileid_t fileid); public: - explicit TestFileOpener(Paging *paging, Pages *pages, offset_t file_size=0); + explicit TestFileOpener(Pages *pages, offset_t file_size=0); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r 1d24a4fff0bd -r af0790b18e8f pager.cc --- a/pager.cc Wed Mar 31 01:06:22 2021 +0200 +++ b/pager.cc Wed Mar 31 23:54:51 2021 +0200 @@ -13,6 +13,8 @@ _mapper->attach(); } +/* Close the pager. */ + void Pager::close() { if (_mapper != NULL) diff -r 1d24a4fff0bd -r af0790b18e8f paging.cc --- a/paging.cc Wed Mar 31 01:06:22 2021 +0200 +++ b/paging.cc Wed Mar 31 23:54:51 2021 +0200 @@ -1,11 +1,15 @@ +#include "file_pager.h" #include "paging.h" -bool Paging::reserve(fileid_t fileid) + + +Paging::Paging(Pages *pages) +: _pages(pages) { - _lock.lock(); +} - return _mappers.find(fileid) != _mappers.end(); -} +/* Return any registered page mapper for the given 'fileid' or NULL if no such + mapper is registered. */ PageMapper *Paging::get(fileid_t fileid) { @@ -17,18 +21,68 @@ else mapper = entry->second; - _lock.unlock(); return mapper; } +/* Register a page 'mapper' for the given 'fileid'. */ + void Paging::set(fileid_t fileid, PageMapper *mapper) { FileMapping::iterator entry = _mappers.find(fileid); if (entry == _mappers.end()) _mappers[fileid] = mapper; +} - _lock.unlock(); +/* Obtain a page mapper for the 'fileid' or register a new one in the + paging object. */ + +PageMapper *Paging::get_mapper(fileid_t fileid) +{ + /* Obtain any registered page mapper. */ + + PageMapper *mapper = get(fileid); + + if (mapper != NULL) + return mapper; + + /* Make an accessor and page mapper, registering the mapper. */ + + Accessor *accessor = make_accessor(fileid); + mapper = new PageMapper(accessor, _pages); + + set(fileid, mapper); + + return mapper; +} + + + +/* Return a pager initialised with a page mapper. */ + +Pager *Paging::get_pager(fileid_t fileid, flags_t flags) +{ + std::lock_guard guard(_lock); + + /* Initialise the pager with the mapper and a reference to this object for + closing the mapper and accessor. */ + + PageMapper *mapper = get_mapper(fileid); + return new FilePager(fileid, mapper, flags, this); +} + +/* Detach a pager, potentially removing its resources. */ + +void Paging::detach_pager(fileid_t fileid, PageMapper *mapper) +{ + std::lock_guard guard(_lock); + + if (!mapper->detach()) + { + _mappers.erase(fileid); + delete mapper->accessor(); + delete mapper; + } } // vim: tabstop=4 expandtab shiftwidth=4 diff -r 1d24a4fff0bd -r af0790b18e8f paging.h --- a/paging.h Wed Mar 31 01:06:22 2021 +0200 +++ b/paging.h Wed Mar 31 23:54:51 2021 +0200 @@ -3,6 +3,8 @@ #include #include +#include "accessor.h" +#include "pager.h" #include "page_mapper.h" @@ -19,15 +21,39 @@ class Paging { protected: + Pages *_pages; + FileMapping _mappers; std::mutex _lock; -public: - bool reserve(fileid_t fileid); + /* Pager initialisation methods. */ + + PageMapper *get_mapper(fileid_t fileid); + + Pager *get_pager(fileid_t fileid, flags_t flags); + + /* Configurable methods. */ + + virtual fileid_t get_fileid(const char *path) = 0; + + virtual Accessor *make_accessor(fileid_t fileid) = 0; + + /* Mapper registry access. */ PageMapper *get(fileid_t fileid); void set(fileid_t fileid, PageMapper *mapper); + +public: + explicit Paging(Pages *pages); + + virtual ~Paging() + { + } + + /* Methods for the pager. */ + + void detach_pager(fileid_t fileid, PageMapper *mapper); }; // vim: tabstop=4 expandtab shiftwidth=4