L4Re/departure

Changeset

193:538b15bffd3e
2021-09-08 Paul Boddie raw files shortlog changelog graph Introduced per-file notification support since the existing support had been brought over from the pipe-related paging support and inadvertently provided a common notification mechanism acting across all files.
libfsserver/include/fsserver/file_notification.h (file) libfsserver/include/fsserver/file_pager.h (file) libfsserver/include/fsserver/file_paging.h (file) libfsserver/include/fsserver/notification.h (file) libfsserver/lib/Makefile (file) libfsserver/lib/files/file_notification.cc (file) libfsserver/lib/files/file_pager.cc (file) libfsserver/lib/files/file_paging.cc (file) libfsserver/lib/generic/notification.cc (file)
     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