From 88f107e0f94595efe6577074f1703f23222fee1c Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Sun, 4 Oct 2015 12:19:22 +0200 Subject: [PATCH] Fs_log: new truncate behavior Files are truncated at the next client session if all previous sessions associated with the file are closed. Issue #1538 --- repos/os/src/server/fs_log/log_file.h | 9 ++++++++- repos/os/src/server/fs_log/main.cc | 10 ++++++++++ repos/os/src/server/fs_log/session.h | 20 ++++++++++++++------ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/repos/os/src/server/fs_log/log_file.h b/repos/os/src/server/fs_log/log_file.h index a7680d4b2..3351e2712 100644 --- a/repos/os/src/server/fs_log/log_file.h +++ b/repos/os/src/server/fs_log/log_file.h @@ -36,6 +36,7 @@ class Fs_log::Log_file : public List::Element File_system::Session &_fs; File_handle _handle; seek_off_t _offset; + int _clients; public: @@ -46,12 +47,14 @@ class Fs_log::Log_file : public List::Element char const *dir_path, char const *file_name, seek_off_t offset) : - _fs(fs), _handle(handle), _offset(offset) + _fs(fs), _handle(handle), _offset(offset), _clients(0) { strncpy(_dir_path, dir_path, sizeof(_dir_path)); strncpy(_file_name, file_name, sizeof(_file_name)); } + ~Log_file() { _fs.close(_handle); } + bool match(char const *dir, char const *filename) const { return @@ -59,6 +62,10 @@ class Fs_log::Log_file : public List::Element (strcmp(_file_name, filename, MAX_NAME_LEN) == 0); } + void incr() { ++_clients; } + void decr() { --_clients; } + int client_count() const { return _clients; } + /** * Write a log message to the packet buffer. */ diff --git a/repos/os/src/server/fs_log/main.cc b/repos/os/src/server/fs_log/main.cc index c6ebc47b7..ff61237f8 100644 --- a/repos/os/src/server/fs_log/main.cc +++ b/repos/os/src/server/fs_log/main.cc @@ -212,6 +212,16 @@ class Fs_log::Root_component : return new (md_alloc()) Unlabeled_session_component(*file); } + void _destroy_session(Session_component *session) + { + Log_file *file = session->file(); + destroy(md_alloc(), session); + if (file->client_count() < 1) { + _log_files.remove(file); + destroy(env()->heap(), file); + } + } + public: /** diff --git a/repos/os/src/server/fs_log/session.h b/repos/os/src/server/fs_log/session.h index 1132838dd..8c19ef987 100644 --- a/repos/os/src/server/fs_log/session.h +++ b/repos/os/src/server/fs_log/session.h @@ -33,15 +33,24 @@ namespace Fs_log { class Fs_log::Session_component : public Rpc_object { + protected: + + Log_file &_log_file; + public: + + Session_component(Log_file &log_file) + : _log_file(log_file) { _log_file.incr(); } + + ~Session_component() { _log_file.decr(); } + + Log_file *file() const { return &_log_file; } + virtual size_t write(String const &string) = 0; }; class Fs_log::Unlabeled_session_component : public Session_component { - private: - - Log_file &_log_file; public: @@ -49,7 +58,7 @@ class Fs_log::Unlabeled_session_component : public Session_component * Constructor */ Unlabeled_session_component(Log_file &log_file) - : _log_file(log_file) { } + : Session_component(log_file) { } /***************** ** Log session ** @@ -75,7 +84,6 @@ class Fs_log::Labeled_session_component : public Session_component char _label[Log_session::String::MAX_SIZE]; size_t _label_len; - Log_file &_log_file; public: @@ -83,7 +91,7 @@ class Fs_log::Labeled_session_component : public Session_component * Constructor */ Labeled_session_component(char const *label, Log_file &log_file) - : _log_file(log_file) + : Session_component(log_file) { snprintf(_label, sizeof(_label), "[%s] ", label); _label_len = strlen(_label);