mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-07 11:50:24 +00:00
noux: add time modification
... and set initial time by using RTC session. Up to now Noux used a monotic clock whose initial start value always was '0' (which correlates to the start of the UNIX epoch) to provide a notion of time. In addition it is now possible to use the RTC session to set the initial value for use cases where having a proper real-world time matters. To use the RTC session the 'rtc' attribute of the '<config>' node must be set to 'yes'. Thereby the session becomes a mandatory dependency as Noux will not start without it. Issue #1784
This commit is contained in:
parent
d0bf6d2b52
commit
94b63924ed
@ -96,6 +96,7 @@ struct Noux::Sysio
|
|||||||
unsigned gid;
|
unsigned gid;
|
||||||
unsigned long inode;
|
unsigned long inode;
|
||||||
unsigned long device;
|
unsigned long device;
|
||||||
|
long long mtime;
|
||||||
|
|
||||||
Stat & operator= (Vfs::Directory_service::Stat const &stat)
|
Stat & operator= (Vfs::Directory_service::Stat const &stat)
|
||||||
{
|
{
|
||||||
@ -105,6 +106,7 @@ struct Noux::Sysio
|
|||||||
gid = stat.gid;
|
gid = stat.gid;
|
||||||
inode = stat.inode;
|
inode = stat.inode;
|
||||||
device = stat.device;
|
device = stat.device;
|
||||||
|
mtime = stat.modification_time.value;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -7,3 +7,4 @@ noux_session
|
|||||||
terminal_session
|
terminal_session
|
||||||
timer_session
|
timer_session
|
||||||
posix
|
posix
|
||||||
|
rtc_session
|
||||||
|
@ -397,6 +397,9 @@ static void _sysio_to_stat_struct(Noux::Sysio const *sysio, struct stat *buf)
|
|||||||
buf->st_blocks = (buf->st_size + FS_BLOCK_SIZE - 1) / FS_BLOCK_SIZE;
|
buf->st_blocks = (buf->st_size + FS_BLOCK_SIZE - 1) / FS_BLOCK_SIZE;
|
||||||
buf->st_ino = sysio->stat_out.st.inode;
|
buf->st_ino = sysio->stat_out.st.inode;
|
||||||
buf->st_dev = sysio->stat_out.st.device;
|
buf->st_dev = sysio->stat_out.st.device;
|
||||||
|
|
||||||
|
if (sysio->stat_out.st.mtime >= 0)
|
||||||
|
buf->st_mtime = sysio->stat_out.st.mtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -934,6 +937,13 @@ extern "C" int gettimeofday(struct timeval *tv, struct timezone *tz)
|
|||||||
|
|
||||||
extern "C" int utimes(const char* path, const struct timeval *times)
|
extern "C" int utimes(const char* path, const struct timeval *times)
|
||||||
{
|
{
|
||||||
|
char * const dst = sysio()->utimes_in.path;
|
||||||
|
size_t const max_len = sizeof(sysio()->utimes_in.path);
|
||||||
|
Genode::strncpy(dst, path, max_len);
|
||||||
|
|
||||||
|
sysio()->utimes_in.sec = times ? times->tv_sec : 0;
|
||||||
|
sysio()->utimes_in.usec = times ? times->tv_usec : 0;
|
||||||
|
|
||||||
if (!noux_syscall(Noux::Session::SYSCALL_UTIMES)) {
|
if (!noux_syscall(Noux::Session::SYSCALL_UTIMES)) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <verbose.h>
|
#include <verbose.h>
|
||||||
#include <user_info.h>
|
#include <user_info.h>
|
||||||
#include <armed_timeout.h>
|
#include <armed_timeout.h>
|
||||||
|
#include <time_info.h>
|
||||||
|
|
||||||
namespace Noux {
|
namespace Noux {
|
||||||
|
|
||||||
@ -124,6 +125,8 @@ class Noux::Child : public Rpc_object<Session>,
|
|||||||
|
|
||||||
User_info const &_user_info;
|
User_info const &_user_info;
|
||||||
|
|
||||||
|
Time_info const &_time_info;
|
||||||
|
|
||||||
Parent_exit *_parent_exit;
|
Parent_exit *_parent_exit;
|
||||||
Kill_broadcaster &_kill_broadcaster;
|
Kill_broadcaster &_kill_broadcaster;
|
||||||
Timer::Connection &_timer_connection;
|
Timer::Connection &_timer_connection;
|
||||||
@ -319,6 +322,7 @@ class Noux::Child : public Rpc_object<Session>,
|
|||||||
Child(Child_policy::Name const &name,
|
Child(Child_policy::Name const &name,
|
||||||
Verbose const &verbose,
|
Verbose const &verbose,
|
||||||
User_info const &user_info,
|
User_info const &user_info,
|
||||||
|
Time_info const &time_info,
|
||||||
Parent_exit *parent_exit,
|
Parent_exit *parent_exit,
|
||||||
Kill_broadcaster &kill_broadcaster,
|
Kill_broadcaster &kill_broadcaster,
|
||||||
Timer::Connection &timer_connection,
|
Timer::Connection &timer_connection,
|
||||||
@ -342,6 +346,7 @@ class Noux::Child : public Rpc_object<Session>,
|
|||||||
_name(name),
|
_name(name),
|
||||||
_verbose(verbose),
|
_verbose(verbose),
|
||||||
_user_info(user_info),
|
_user_info(user_info),
|
||||||
|
_time_info(time_info),
|
||||||
_parent_exit(parent_exit),
|
_parent_exit(parent_exit),
|
||||||
_kill_broadcaster(kill_broadcaster),
|
_kill_broadcaster(kill_broadcaster),
|
||||||
_timer_connection(timer_connection),
|
_timer_connection(timer_connection),
|
||||||
@ -521,6 +526,7 @@ class Noux::Child : public Rpc_object<Session>,
|
|||||||
Child *child = new (_heap) Child(filename,
|
Child *child = new (_heap) Child(filename,
|
||||||
_verbose,
|
_verbose,
|
||||||
_user_info,
|
_user_info,
|
||||||
|
_time_info,
|
||||||
_parent_exit,
|
_parent_exit,
|
||||||
_kill_broadcaster,
|
_kill_broadcaster,
|
||||||
_timer_connection,
|
_timer_connection,
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <kill_broadcaster.h>
|
#include <kill_broadcaster.h>
|
||||||
#include <vfs/dir_file_system.h>
|
#include <vfs/dir_file_system.h>
|
||||||
#include <vfs/simple_env.h>
|
#include <vfs/simple_env.h>
|
||||||
|
#include <time_info.h>
|
||||||
|
|
||||||
namespace Noux {
|
namespace Noux {
|
||||||
|
|
||||||
@ -98,7 +99,9 @@ connect_stdio(Genode::Env &env,
|
|||||||
Vfs::File_system &root,
|
Vfs::File_system &root,
|
||||||
Noux::Vfs_io_waiter_registry &vfs_io_waiter_registry,
|
Noux::Vfs_io_waiter_registry &vfs_io_waiter_registry,
|
||||||
Noux::Terminal_io_channel::Type type,
|
Noux::Terminal_io_channel::Type type,
|
||||||
Genode::Allocator &alloc)
|
Genode::Allocator &alloc,
|
||||||
|
Noux::Time_info &time_info,
|
||||||
|
Timer::Connection &timer)
|
||||||
{
|
{
|
||||||
using namespace Vfs;
|
using namespace Vfs;
|
||||||
using namespace Noux;
|
using namespace Noux;
|
||||||
@ -142,7 +145,8 @@ connect_stdio(Genode::Env &env,
|
|||||||
|
|
||||||
return *new (alloc)
|
return *new (alloc)
|
||||||
Vfs_io_channel(path.string(), root.leaf_path(path.string()),
|
Vfs_io_channel(path.string(), root.leaf_path(path.string()),
|
||||||
vfs_handle, vfs_io_waiter_registry, env.ep());
|
vfs_handle, vfs_io_waiter_registry, env.ep(),
|
||||||
|
time_info, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -241,6 +245,8 @@ struct Noux::Main
|
|||||||
|
|
||||||
User_info _user_info { _config.xml() };
|
User_info _user_info { _config.xml() };
|
||||||
|
|
||||||
|
Time_info _time_info { _env, _config.xml() };
|
||||||
|
|
||||||
Signal_handler<Main> _destruct_handler {
|
Signal_handler<Main> _destruct_handler {
|
||||||
_env.ep(), *this, &Main::_handle_destruct };
|
_env.ep(), *this, &Main::_handle_destruct };
|
||||||
|
|
||||||
@ -273,6 +279,7 @@ struct Noux::Main
|
|||||||
Noux::Child _init_child { _name_of_init_process(),
|
Noux::Child _init_child { _name_of_init_process(),
|
||||||
_verbose,
|
_verbose,
|
||||||
_user_info,
|
_user_info,
|
||||||
|
_time_info,
|
||||||
0,
|
0,
|
||||||
_kill_broadcaster,
|
_kill_broadcaster,
|
||||||
_timer_connection,
|
_timer_connection,
|
||||||
@ -302,13 +309,13 @@ struct Noux::Main
|
|||||||
Shared_pointer<Io_channel>
|
Shared_pointer<Io_channel>
|
||||||
_channel_0 { &connect_stdio(_env, _terminal, _config.xml(), _root_dir,
|
_channel_0 { &connect_stdio(_env, _terminal, _config.xml(), _root_dir,
|
||||||
_io_response_handler.io_waiter_registry,
|
_io_response_handler.io_waiter_registry,
|
||||||
Tio::STDIN, _heap), _heap },
|
Tio::STDIN, _heap, _time_info, _timer_connection), _heap },
|
||||||
_channel_1 { &connect_stdio(_env, _terminal, _config.xml(), _root_dir,
|
_channel_1 { &connect_stdio(_env, _terminal, _config.xml(), _root_dir,
|
||||||
_io_response_handler.io_waiter_registry,
|
_io_response_handler.io_waiter_registry,
|
||||||
Tio::STDOUT, _heap), _heap },
|
Tio::STDOUT, _heap, _time_info, _timer_connection), _heap },
|
||||||
_channel_2 { &connect_stdio(_env, _terminal, _config.xml(), _root_dir,
|
_channel_2 { &connect_stdio(_env, _terminal, _config.xml(), _root_dir,
|
||||||
_io_response_handler.io_waiter_registry,
|
_io_response_handler.io_waiter_registry,
|
||||||
Tio::STDERR, _heap), _heap };
|
Tio::STDERR, _heap, _time_info, _timer_connection), _heap };
|
||||||
|
|
||||||
Main(Env &env) : _env(env)
|
Main(Env &env) : _env(env)
|
||||||
{
|
{
|
||||||
|
@ -238,7 +238,9 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
|||||||
leaf_path,
|
leaf_path,
|
||||||
vfs_handle,
|
vfs_handle,
|
||||||
_vfs_io_waiter_registry,
|
_vfs_io_waiter_registry,
|
||||||
_env.ep()),
|
_env.ep(),
|
||||||
|
_time_info,
|
||||||
|
_timer_connection),
|
||||||
_heap);
|
_heap);
|
||||||
|
|
||||||
_sysio.open_out.fd = add_io_channel(channel);
|
_sysio.open_out.fd = add_io_channel(channel);
|
||||||
@ -511,6 +513,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
|||||||
child = new (_heap) Child(_child_policy.name(),
|
child = new (_heap) Child(_child_policy.name(),
|
||||||
_verbose,
|
_verbose,
|
||||||
_user_info,
|
_user_info,
|
||||||
|
_time_info,
|
||||||
this,
|
this,
|
||||||
_kill_broadcaster,
|
_kill_broadcaster,
|
||||||
_timer_connection,
|
_timer_connection,
|
||||||
@ -844,7 +847,8 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
|||||||
Milliseconds const ms =
|
Milliseconds const ms =
|
||||||
_timer_connection.curr_time().trunc_to_plain_ms();
|
_timer_connection.curr_time().trunc_to_plain_ms();
|
||||||
|
|
||||||
_sysio.gettimeofday_out.sec = (ms.value / 1000);
|
_sysio.gettimeofday_out.sec = _time_info.initial_time();
|
||||||
|
_sysio.gettimeofday_out.sec += (ms.value / 1000);
|
||||||
_sysio.gettimeofday_out.usec = (ms.value % 1000) * 1000;
|
_sysio.gettimeofday_out.usec = (ms.value % 1000) * 1000;
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
@ -864,7 +868,8 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
|||||||
/* CLOCK_SECOND is used by time(3) in the libc. */
|
/* CLOCK_SECOND is used by time(3) in the libc. */
|
||||||
case Sysio::CLOCK_ID_SECOND:
|
case Sysio::CLOCK_ID_SECOND:
|
||||||
{
|
{
|
||||||
_sysio.clock_gettime_out.sec = (ms.value / 1000);
|
_sysio.clock_gettime_out.sec = _time_info.initial_time();
|
||||||
|
_sysio.clock_gettime_out.sec += (ms.value / 1000);
|
||||||
_sysio.clock_gettime_out.nsec = 0;
|
_sysio.clock_gettime_out.nsec = 0;
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
@ -889,13 +894,42 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
|||||||
case SYSCALL_UTIMES:
|
case SYSCALL_UTIMES:
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* This systemcall is currently not implemented because we lack
|
* Always return true, even if 'update_modification_timestamp'
|
||||||
* the needed mechanisms in most file-systems.
|
* failed to keep programs, e.g. make, happy.
|
||||||
*
|
|
||||||
* But we return true anyway to keep certain programs, e.g. make
|
|
||||||
* happy.
|
|
||||||
*/
|
*/
|
||||||
result = true;
|
result = true;
|
||||||
|
|
||||||
|
char const *path = (char const *)_sysio.utimes_in.path;
|
||||||
|
unsigned long sec = _sysio.utimes_in.sec;
|
||||||
|
unsigned long usec = _sysio.utimes_in.usec;
|
||||||
|
(void)usec;
|
||||||
|
|
||||||
|
Vfs::Vfs_handle *vfs_handle = 0;
|
||||||
|
_root_dir.open(path, 0, &vfs_handle, _heap);
|
||||||
|
if (!vfs_handle) { break; }
|
||||||
|
|
||||||
|
if (!sec) {
|
||||||
|
Milliseconds const ms =
|
||||||
|
_timer_connection.curr_time().trunc_to_plain_ms();
|
||||||
|
sec = _time_info.initial_time();
|
||||||
|
sec += (ms.value / 1000);
|
||||||
|
usec = (ms.value % 1000) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
Registered_no_delete<Vfs_io_waiter>
|
||||||
|
vfs_io_waiter(_vfs_io_waiter_registry);
|
||||||
|
|
||||||
|
Vfs::Timestamp ts { .value = (long long)sec };
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (vfs_handle->fs().update_modification_timestamp(vfs_handle, ts)) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
vfs_io_waiter.wait_for_io();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_root_dir.close(vfs_handle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
104
repos/ports/src/noux/time_info.h
Normal file
104
repos/ports/src/noux/time_info.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* \brief Time information
|
||||||
|
* \author Josef Soentgen
|
||||||
|
* \date 2019-04-09
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 _NOUX__TIME_INFO_H_
|
||||||
|
#define _NOUX__TIME_INFO_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <util/string.h>
|
||||||
|
#include <util/xml_node.h>
|
||||||
|
#include <rtc_session/connection.h>
|
||||||
|
|
||||||
|
/* Noux includes */
|
||||||
|
#include <noux_session/sysio.h>
|
||||||
|
|
||||||
|
namespace Noux {
|
||||||
|
class Time_info;
|
||||||
|
using namespace Genode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Noux::Time_info : Noncopyable
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Constructible<Rtc::Connection> _rtc { };
|
||||||
|
|
||||||
|
Genode::int64_t _initial_time { 0 };
|
||||||
|
|
||||||
|
static bool _leap(unsigned year)
|
||||||
|
{
|
||||||
|
return ((year % 4) == 0
|
||||||
|
&& ((year % 100) != 0 || (year % 400) == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert RTC timestamp to UNIX epoch (UTC)
|
||||||
|
*/
|
||||||
|
static Genode::int64_t _convert(Rtc::Timestamp const &ts)
|
||||||
|
{
|
||||||
|
if (ts.year < 1970) { return 0; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Seconds per year lookup table
|
||||||
|
*/
|
||||||
|
static constexpr unsigned _secs_per_year[2] = {
|
||||||
|
365 * 86400, 366 * 86400,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Seconds per month lookup table
|
||||||
|
*/
|
||||||
|
static constexpr unsigned _sec_per_month[13] = {
|
||||||
|
0 * 86400,
|
||||||
|
31 * 86400, 28 * 86400, 31 * 86400, 30 * 86400,
|
||||||
|
31 * 86400, 30 * 86400, 31 * 86400, 31 * 86400,
|
||||||
|
30 * 86400, 31 * 86400, 30 * 86400, 31 * 86400
|
||||||
|
};
|
||||||
|
|
||||||
|
Genode::int64_t time = 0;
|
||||||
|
|
||||||
|
for (unsigned i = 1970; i < ts.year; i++) {
|
||||||
|
/* abuse bool conversion for seconds look up */
|
||||||
|
time += _secs_per_year[(int)_leap(i)];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 1; i < ts.month; i++) {
|
||||||
|
time += _sec_per_month[i];
|
||||||
|
}
|
||||||
|
time += _leap(ts.year) * 86400LL;
|
||||||
|
|
||||||
|
time += 86400LL * (ts.day-1);
|
||||||
|
time += 3600LL * ts.hour;
|
||||||
|
time += 60LL * ts.minute;
|
||||||
|
time += ts.second;
|
||||||
|
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Time_info(Env &env, Xml_node config)
|
||||||
|
{
|
||||||
|
/* only try to establish the connection on demand */
|
||||||
|
bool const rtc = config.attribute_value("rtc", false);
|
||||||
|
if (!rtc) { return; }
|
||||||
|
|
||||||
|
_rtc.construct(env);
|
||||||
|
_initial_time = _convert(_rtc->current_time());
|
||||||
|
}
|
||||||
|
|
||||||
|
Genode::int64_t initial_time() const { return _initial_time; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _NOUX__TIME_INFO_H_ */
|
@ -14,9 +14,13 @@
|
|||||||
#ifndef _NOUX__VFS_IO_CHANNEL_H_
|
#ifndef _NOUX__VFS_IO_CHANNEL_H_
|
||||||
#define _NOUX__VFS_IO_CHANNEL_H_
|
#define _NOUX__VFS_IO_CHANNEL_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <timer_session/connection.h>
|
||||||
|
|
||||||
/* Noux includes */
|
/* Noux includes */
|
||||||
#include <io_channel.h>
|
#include <io_channel.h>
|
||||||
#include <vfs/dir_file_system.h>
|
#include <vfs/dir_file_system.h>
|
||||||
|
#include <time_info.h>
|
||||||
|
|
||||||
namespace Noux {
|
namespace Noux {
|
||||||
class Vfs_io_waiter;
|
class Vfs_io_waiter;
|
||||||
@ -69,11 +73,30 @@ struct Noux::Vfs_io_channel : Io_channel
|
|||||||
|
|
||||||
bool const _dir = _fh.ds().directory(_leaf_path.base());
|
bool const _dir = _fh.ds().directory(_leaf_path.base());
|
||||||
|
|
||||||
|
Time_info const &_time_info;
|
||||||
|
Timer::Connection &_timer;
|
||||||
|
|
||||||
void _sync()
|
void _sync()
|
||||||
{
|
{
|
||||||
|
Milliseconds const ms =
|
||||||
|
_timer.curr_time().trunc_to_plain_ms();
|
||||||
|
uint64_t sec = _time_info.initial_time();
|
||||||
|
sec += (ms.value / 1000);
|
||||||
|
|
||||||
|
Vfs::Timestamp ts { .value = (long long)sec };
|
||||||
|
|
||||||
Registered_no_delete<Vfs_io_waiter>
|
Registered_no_delete<Vfs_io_waiter>
|
||||||
vfs_io_waiter(_vfs_io_waiter_registry);
|
vfs_io_waiter(_vfs_io_waiter_registry);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (_fh.fs().update_modification_timestamp(&_fh, ts)) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
Genode::error("_sync: update_modification_timestamp failed");
|
||||||
|
vfs_io_waiter.wait_for_io();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (!_fh.fs().queue_sync(&_fh))
|
while (!_fh.fs().queue_sync(&_fh))
|
||||||
vfs_io_waiter.wait_for_io();
|
vfs_io_waiter.wait_for_io();
|
||||||
|
|
||||||
@ -89,11 +112,13 @@ struct Noux::Vfs_io_channel : Io_channel
|
|||||||
Vfs_io_channel(char const *path, char const *leaf_path,
|
Vfs_io_channel(char const *path, char const *leaf_path,
|
||||||
Vfs::Vfs_handle *vfs_handle,
|
Vfs::Vfs_handle *vfs_handle,
|
||||||
Vfs_io_waiter_registry &vfs_io_waiter_registry,
|
Vfs_io_waiter_registry &vfs_io_waiter_registry,
|
||||||
Entrypoint &ep)
|
Entrypoint &ep,
|
||||||
|
Time_info const &time_info,
|
||||||
|
Timer::Connection &timer)
|
||||||
:
|
:
|
||||||
_read_avail_handler(ep, *this, &Vfs_io_channel::_handle_read_avail),
|
_read_avail_handler(ep, *this, &Vfs_io_channel::_handle_read_avail),
|
||||||
_fh(*vfs_handle), _vfs_io_waiter_registry(vfs_io_waiter_registry),
|
_fh(*vfs_handle), _vfs_io_waiter_registry(vfs_io_waiter_registry),
|
||||||
_path(path), _leaf_path(leaf_path)
|
_path(path), _leaf_path(leaf_path), _time_info(time_info), _timer(timer)
|
||||||
{
|
{
|
||||||
_fh.fs().register_read_ready_sigh(&_fh, _read_avail_handler);
|
_fh.fs().register_read_ready_sigh(&_fh, _read_avail_handler);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user