1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/libfsserver/include/fsserver/file_notification.h Wed Sep 08 01:18:00 2021 +0200
1.3 @@ -0,0 +1,48 @@
1.4 +/*
1.5 + * File-specific notification support.
1.6 + *
1.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk>
1.8 + *
1.9 + * This program is free software; you can redistribute it and/or
1.10 + * modify it under the terms of the GNU General Public License as
1.11 + * published by the Free Software Foundation; either version 2 of
1.12 + * the License, or (at your option) any later version.
1.13 + *
1.14 + * This program is distributed in the hope that it will be useful,
1.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.17 + * GNU General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License
1.20 + * along with this program; if not, write to the Free Software
1.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
1.22 + * Boston, MA 02110-1301, USA
1.23 + */
1.24 +
1.25 +#pragma once
1.26 +
1.27 +#include <mutex>
1.28 +
1.29 +#include <fsserver/notification.h>
1.30 +
1.31 +
1.32 +
1.33 +/* Notification support for files. */
1.34 +
1.35 +class FileNotification : public NotificationSupport
1.36 +{
1.37 +protected:
1.38 + std::mutex _lock;
1.39 + unsigned int _attached = 0;
1.40 +
1.41 +public:
1.42 + explicit FileNotification();
1.43 +
1.44 + /* Accounting methods. */
1.45 +
1.46 + void attach();
1.47 +
1.48 + unsigned int detach();
1.49 +};
1.50 +
1.51 +// vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/libfsserver/include/fsserver/file_pager.h Sat Sep 04 23:23:32 2021 +0200
2.2 +++ b/libfsserver/include/fsserver/file_pager.h Wed Sep 08 01:18:00 2021 +0200
2.3 @@ -75,9 +75,9 @@
2.4
2.5 /* Notification methods. */
2.6
2.7 - virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags);
2.8 + virtual long subscribe(l4_cap_idx_t endpoint, notify_flags_t flags);
2.9
2.10 - virtual long unsubscribe(l4_cap_idx_t notifier);
2.11 + virtual long unsubscribe(l4_cap_idx_t endpoint);
2.12 };
2.13
2.14 // vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/libfsserver/include/fsserver/file_paging.h Sat Sep 04 23:23:32 2021 +0200
3.2 +++ b/libfsserver/include/fsserver/file_paging.h Wed Sep 08 01:18:00 2021 +0200
3.3 @@ -24,8 +24,8 @@
3.4 #include <map>
3.5 #include <mutex>
3.6
3.7 +#include <fsserver/file_notification.h>
3.8 #include <fsserver/file_opening.h>
3.9 -#include <fsserver/notification.h>
3.10 #include <fsserver/page_mapper.h>
3.11 #include <fsserver/pager.h>
3.12 #include <fsserver/pages.h>
3.13 @@ -37,15 +37,21 @@
3.14 typedef std::map<fileid_t, PageMapper *> FileMapping;
3.15 typedef std::pair<fileid_t, PageMapper *> FileMappingEntry;
3.16
3.17 +/* Mapping type from file identifiers to notification managers. */
3.18 +
3.19 +typedef std::map<fileid_t, FileNotification *> FileNotifiers;
3.20 +typedef std::map<fileid_t, FileNotification *> FileNotifierEntry;
3.21 +
3.22
3.23
3.24 /* A registry of mappers for accessors. */
3.25
3.26 -class FilePaging : public NotificationSupport
3.27 +class FilePaging
3.28 {
3.29 protected:
3.30 Pages *_pages;
3.31 FileMapping _mappers;
3.32 + FileNotifiers _notifiers;
3.33 std::mutex _lock;
3.34
3.35 /* Mapper registry access. */
3.36 @@ -60,18 +66,26 @@
3.37
3.38 map_flags_t get_flags(flags_t flags);
3.39
3.40 + long get_mapper(FileOpening *opening, const char *path, flags_t flags, fileid_t fileid, PageMapper **mapper);
3.41 +
3.42 + /* Notification manager access. */
3.43 +
3.44 + FileNotification *get_notifier(fileid_t fileid);
3.45 +
3.46 + void remove(fileid_t fileid, FileNotification *notifier);
3.47 +
3.48 public:
3.49 explicit FilePaging(Pages *pages);
3.50
3.51 /* Pager initialisation methods. */
3.52
3.53 - long get_mapper(FileOpening *opening, const char *path, flags_t flags, fileid_t fileid, PageMapper **mapper);
3.54 -
3.55 long get_pager(FileOpening *opening, const char *path, flags_t flags, fileid_t fileid, Pager **pager);
3.56
3.57 /* Methods for the pager. */
3.58
3.59 void detach_pager(fileid_t fileid, PageMapper *mapper);
3.60 +
3.61 + FileNotification *notifier(fileid_t fileid);
3.62 };
3.63
3.64 // vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/libfsserver/include/fsserver/notification.h Sat Sep 04 23:23:32 2021 +0200
4.2 +++ b/libfsserver/include/fsserver/notification.h Wed Sep 08 01:18:00 2021 +0200
4.3 @@ -75,6 +75,8 @@
4.4 public:
4.5 explicit NotificationSupport(unsigned int endpoints=0);
4.6
4.7 + virtual ~NotificationSupport();
4.8 +
4.9 virtual void notify(unsigned int endpoint, notify_flags_t flags);
4.10
4.11 virtual void notify_others(unsigned int endpoint, notify_flags_t flags);
5.1 --- a/libfsserver/lib/Makefile Sat Sep 04 23:23:32 2021 +0200
5.2 +++ b/libfsserver/lib/Makefile Wed Sep 08 01:18:00 2021 +0200
5.3 @@ -48,6 +48,7 @@
5.4 files/ext2_file_opener.cc \
5.5 files/ext2_file_operations.cc \
5.6 files/ext2_filesystem.cc \
5.7 + files/file_notification.cc \
5.8 files/file_pager.cc \
5.9 files/file_paging.cc \
5.10 files/filesystem_resource.cc \
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/libfsserver/lib/files/file_notification.cc Wed Sep 08 01:18:00 2021 +0200
6.3 @@ -0,0 +1,54 @@
6.4 +/*
6.5 + * Notification support for files.
6.6 + *
6.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk>
6.8 + *
6.9 + * This program is free software; you can redistribute it and/or
6.10 + * modify it under the terms of the GNU General Public License as
6.11 + * published by the Free Software Foundation; either version 2 of
6.12 + * the License, or (at your option) any later version.
6.13 + *
6.14 + * This program is distributed in the hope that it will be useful,
6.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.17 + * GNU General Public License for more details.
6.18 + *
6.19 + * You should have received a copy of the GNU General Public License
6.20 + * along with this program; if not, write to the Free Software
6.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
6.22 + * Boston, MA 02110-1301, USA
6.23 + */
6.24 +
6.25 +#include "file_notification.h"
6.26 +
6.27 +
6.28 +
6.29 +FileNotification::FileNotification()
6.30 +: NotificationSupport()
6.31 +{
6.32 +}
6.33 +
6.34 +/* Accounting methods. */
6.35 +
6.36 +/* Attach a user of this object. */
6.37 +
6.38 +void FileNotification::attach()
6.39 +{
6.40 + std::lock_guard<std::mutex> guard(_lock);
6.41 +
6.42 + _attached += 1;
6.43 +}
6.44 +
6.45 +/* Detach a user of this object. */
6.46 +
6.47 +unsigned int FileNotification::detach()
6.48 +{
6.49 + std::lock_guard<std::mutex> guard(_lock);
6.50 +
6.51 + if (_attached)
6.52 + _attached -= 1;
6.53 +
6.54 + return _attached;
6.55 +}
6.56 +
6.57 +// vim: tabstop=4 expandtab shiftwidth=4
7.1 --- a/libfsserver/lib/files/file_pager.cc Sat Sep 04 23:23:32 2021 +0200
7.2 +++ b/libfsserver/lib/files/file_pager.cc Wed Sep 08 01:18:00 2021 +0200
7.3 @@ -54,7 +54,10 @@
7.4
7.5 /* Notify other users of the file. */
7.6
7.7 - _paging->notify_others(_endpoint, NOTIFY_PEER_CLOSED);
7.8 + FileNotification *notifier = _paging->notifier(fileid);
7.9 +
7.10 + if (notifier != NULL)
7.11 + notifier->notify_others(_endpoint, NOTIFY_PEER_CLOSED);
7.12 }
7.13
7.14
7.15 @@ -67,7 +70,11 @@
7.16
7.17 if (_resized)
7.18 {
7.19 - _paging->notify_others(_endpoint, NOTIFY_CONTENT_AVAILABLE);
7.20 + FileNotification *notifier = _paging->notifier(fileid);
7.21 +
7.22 + if (notifier != NULL)
7.23 + notifier->notify_others(_endpoint, NOTIFY_CONTENT_AVAILABLE);
7.24 +
7.25 _resized = false;
7.26 }
7.27
7.28 @@ -109,18 +116,27 @@
7.29
7.30 /* Subscribe to notifications. */
7.31
7.32 -long FilePager::subscribe(l4_cap_idx_t notifier, notify_flags_t flags)
7.33 +long FilePager::subscribe(l4_cap_idx_t endpoint, notify_flags_t flags)
7.34 {
7.35 /* Readers can subscribe to new data (at end), and pipe closed events.
7.36 Writers can subscribe to new space and pipe closed events. */
7.37
7.38 - _endpoint = _paging->subscribe(notifier, flags);
7.39 + FileNotification *notifier = _paging->notifier(fileid);
7.40 +
7.41 + if (notifier == NULL)
7.42 + return -L4_ENOSYS;
7.43 +
7.44 + _endpoint = notifier->subscribe(endpoint, flags);
7.45 return L4_EOK;
7.46 }
7.47
7.48 -long FilePager::unsubscribe(l4_cap_idx_t notifier)
7.49 +long FilePager::unsubscribe(l4_cap_idx_t endpoint)
7.50 {
7.51 - _paging->unsubscribe(_endpoint, notifier);
7.52 + FileNotification *notifier = _paging->notifier(fileid);
7.53 +
7.54 + if (notifier != NULL)
7.55 + notifier->unsubscribe(_endpoint, endpoint);
7.56 +
7.57 return L4_EOK;
7.58 }
7.59
8.1 --- a/libfsserver/lib/files/file_paging.cc Sat Sep 04 23:23:32 2021 +0200
8.2 +++ b/libfsserver/lib/files/file_paging.cc Wed Sep 08 01:18:00 2021 +0200
8.3 @@ -27,7 +27,7 @@
8.4
8.5
8.6 FilePaging::FilePaging(Pages *pages)
8.7 -: NotificationSupport(), _pages(pages)
8.8 +: _pages(pages)
8.9 {
8.10 }
8.11
8.12 @@ -49,6 +49,14 @@
8.13 return mapper;
8.14 }
8.15
8.16 +/* Remove a notification manager for the given 'fileid'. */
8.17 +
8.18 +void FilePaging::remove(fileid_t fileid, FileNotification *notifier)
8.19 +{
8.20 + _notifiers.erase(fileid);
8.21 + delete notifier;
8.22 +}
8.23 +
8.24 /* Remove a page mapper and its resources for the given 'fileid'. */
8.25
8.26 void FilePaging::remove(fileid_t fileid, PageMapper *mapper)
8.27 @@ -58,14 +66,17 @@
8.28 delete mapper;
8.29 }
8.30
8.31 -/* Register a page 'mapper' for the given 'fileid'. */
8.32 +/* Register a page 'mapper' and a notification manager for the given 'fileid'. */
8.33
8.34 void FilePaging::set(fileid_t fileid, PageMapper *mapper)
8.35 {
8.36 FileMapping::iterator entry = _mappers.find(fileid);
8.37
8.38 - if (entry == _mappers.end())
8.39 - _mappers[fileid] = mapper;
8.40 + if (entry != _mappers.end())
8.41 + return;
8.42 +
8.43 + _mappers[fileid] = mapper;
8.44 + _notifiers[fileid] = new FileNotification;
8.45 }
8.46
8.47
8.48 @@ -106,6 +117,18 @@
8.49 return L4_EOK;
8.50 }
8.51
8.52 +/* Obtain a file-specific notification manager. */
8.53 +
8.54 +FileNotification *FilePaging::get_notifier(fileid_t file)
8.55 +{
8.56 + FileNotifiers::iterator entry = _notifiers.find(file);
8.57 +
8.58 + if (entry != _notifiers.end())
8.59 + return _notifiers[file];
8.60 + else
8.61 + return NULL;
8.62 +}
8.63 +
8.64
8.65
8.66 /* Return a pager initialised with a page mapper. */
8.67 @@ -138,6 +161,20 @@
8.68
8.69 if (!mapper->detach())
8.70 remove(fileid, mapper);
8.71 +
8.72 + FileNotification *notifier = get_notifier(fileid);
8.73 +
8.74 + if ((notifier != NULL) && (!notifier->detach()))
8.75 + remove(fileid, notifier);
8.76 +}
8.77 +
8.78 +/* Obtain a file-specific notification manager. */
8.79 +
8.80 +FileNotification *FilePaging::notifier(fileid_t file)
8.81 +{
8.82 + std::lock_guard<std::mutex> guard(_lock);
8.83 +
8.84 + return get_notifier(file);
8.85 }
8.86
8.87 // vim: tabstop=4 expandtab shiftwidth=4
9.1 --- a/libfsserver/lib/generic/notification.cc Sat Sep 04 23:23:32 2021 +0200
9.2 +++ b/libfsserver/lib/generic/notification.cc Wed Sep 08 01:18:00 2021 +0200
9.3 @@ -34,6 +34,10 @@
9.4 _endpoints.resize(_min_endpoints);
9.5 }
9.6
9.7 +NotificationSupport::~NotificationSupport()
9.8 +{
9.9 +}
9.10 +
9.11 /* Subscribe to notifications using a notification object, returning the
9.12 endpoint number. */
9.13