libc: remove global watch() function

This patch replaces the function with a 'Watch' interface to be
explicitly passed to the caller (currently only time.cc).

Issue #3497
This commit is contained in:
Norman Feske 2019-09-20 16:59:47 +02:00 committed by Christian Helmuth
parent 5f5d709c07
commit 418ac4c560
7 changed files with 57 additions and 29 deletions

View File

@ -34,6 +34,7 @@ namespace Libc {
struct Current_time;
struct Clone_connection;
struct Kernel_routine_scheduler;
struct Watch;
/**
* Support for shared libraries
@ -98,7 +99,7 @@ namespace Libc {
* Init timing facilities
*/
void init_sleep(Suspend &);
void init_time(Current_time &, Rtc_path const &);
void init_time(Current_time &, Rtc_path const &, Watch &);
/**
* Socket fs

View File

@ -37,6 +37,7 @@
#include <internal/kernel_routine.h>
#include <internal/current_time.h>
#include <internal/kernel_timer_accessor.h>
#include <internal/watch.h>
namespace Libc { class Kernel; }
@ -58,7 +59,8 @@ struct Libc::Kernel final : Vfs::Io_response_handler,
Suspend,
Select,
Kernel_routine_scheduler,
Current_time
Current_time,
Watch
{
private:
@ -513,9 +515,9 @@ struct Libc::Kernel final : Vfs::Io_response_handler,
}
/**
* Alloc new watch handler for given path
* Watch interface
*/
Vfs::Vfs_watch_handle *alloc_watch_handle(char const *path)
Vfs::Vfs_watch_handle *alloc_watch_handle(char const *path) override
{
Vfs::Vfs_watch_handle *watch_handle { nullptr };
typedef Vfs::Directory_service::Watch_result Result;

View File

@ -27,18 +27,6 @@ namespace Libc {
*/
void dispatch_pending_io_signals();
/**
* Get watch handle for given path
*
* \param path path that should be be watched
*
* \return point to the watch handle object or a nullptr
* when the watch operation failed
*
* XXX only needed by time.cc
*/
Vfs::Vfs_watch_handle *watch(char const *path);
/*
* XXX this function is solely needed to support noux fork mechanism
*/

View File

@ -0,0 +1,31 @@
/*
* \brief Interface for watching files
* \author Norman Feske
* \date 2019-09-20
*/
/*
* Copyright (C) 2019 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _LIBC__INTERNAL__WATCH_H_
#define _LIBC__INTERNAL__WATCH_H_
/* libc-internal includes */
#include <internal/types.h>
namespace Libc {
struct Watch : Interface
{
/**
* Alloc new watch handler for given path
*/
virtual Vfs::Vfs_watch_handle *alloc_watch_handle(char const *path) = 0;
};
}
#endif /* _LIBC__INTERNAL__WATCH_H_ */

View File

@ -322,7 +322,7 @@ Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap)
init_plugin(*this);
init_sleep(*this);
init_vfs_plugin(*this);
init_time(*this, _rtc_path);
init_time(*this, _rtc_path, *this);
init_poll(*this);
init_select(*this, *this, *this);
init_socket_fs(*this);

View File

@ -25,12 +25,6 @@ void Libc::dispatch_pending_io_signals()
}
Vfs::Vfs_watch_handle *Libc::watch(char const *path)
{
return Kernel::kernel().alloc_watch_handle(path);
}
void Libc::schedule_suspend(void (*suspended) ())
{
Kernel::kernel().schedule_suspend(suspended);

View File

@ -28,17 +28,22 @@
#include <internal/errno.h>
#include <internal/init.h>
#include <internal/current_time.h>
#include <internal/watch.h>
static Libc::Current_time *_current_time_ptr;
static char const *_rtc_path;
static Libc::Watch *_watch_ptr;
void Libc::init_time(Current_time &current_time, Rtc_path const &rtc_path)
void Libc::init_time(Current_time &current_time,
Rtc_path const &rtc_path,
Watch &watch)
{
static Rtc_path rtc_path_inst = rtc_path;
_current_time_ptr = &current_time;
_rtc_path = rtc_path_inst.string();
_watch_ptr = &watch;
}
@ -51,21 +56,23 @@ struct Libc::Rtc : Vfs::Watch_response_handler
Rtc_path const _rtc_path;
Watch &_watch;
bool _read_file { true };
time_t _rtc_value { 0 };
bool const _rtc_path_valid = (_rtc_path != "");
Rtc(Rtc_path const &rtc_path)
Rtc(Rtc_path const &rtc_path, Watch &watch)
:
_rtc_path(rtc_path)
_rtc_path(rtc_path), _watch(watch)
{
if (!_rtc_path_valid) {
warning("rtc not configured, returning ", _rtc_value);
return;
}
_watch_handle = watch(_rtc_path.string());
_watch_handle = _watch.alloc_watch_handle(_rtc_path.string());
if (_watch_handle) {
_watch_handle->handler(this);
}
@ -134,15 +141,17 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts)
if (!ts) return Errno(EFAULT);
struct Missing_call_of_init_time : Exception { };
auto current_time = [&] ()
{
struct Missing_call_of_init_time : Exception { };
if (!_current_time_ptr)
throw Missing_call_of_init_time();
return _current_time_ptr->current_time();
};
/* initialize timespec just in case users do not check for errors */
ts->tv_sec = 0;
ts->tv_nsec = 0;
@ -153,10 +162,13 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts)
case CLOCK_REALTIME:
case CLOCK_SECOND: /* FreeBSD specific */
{
if (!_watch_ptr)
throw Missing_call_of_init_time();
/*
* XXX move instance to Libc::Kernel
*/
static Rtc rtc(_rtc_path);
static Rtc rtc(_rtc_path, *_watch_ptr);
time_t const rtc_value = rtc.read();
if (!rtc_value) return Errno(EINVAL);