/* * \brief I/O channel * \author Norman Feske * \date 2011-02-17 * * An 'Io_channel' is the interface for the operations on an open file * descriptor. */ /* * Copyright (C) 2011-2013 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ #ifndef _NOUX__IO_CHANNEL_H_ #define _NOUX__IO_CHANNEL_H_ /* Genode includes */ #include /* Noux includes */ #include #include #include namespace Noux { /** * Input/output channel backend that is used for calling * different methos which does not belong to the original * interface, e.g. network methods. */ class Io_channel_backend { public: virtual ~Io_channel_backend() { } virtual int type() const { return -1; } }; /** * Input/output channel interface */ class Io_channel : public Reference_counter { private: /** * List of notifiers (i.e., processes) used by threads that block * for an I/O-channel event */ List _notifiers; Lock _notifiers_lock; public: bool close_on_execve; Io_channel() : close_on_execve(false) { } virtual ~Io_channel() { } virtual Io_channel_backend* backend() { return 0; } virtual bool write(Sysio *sysio, size_t &count) { return false; } virtual bool read(Sysio *sysio) { return false; } virtual bool fstat(Sysio *sysio) { return false; } virtual bool ftruncate(Sysio *sysio) { return false; } virtual bool fcntl(Sysio *sysio) { return false; } virtual bool dirent(Sysio *sysio) { return false; } virtual bool ioctl(Sysio *sysio) { return false; } virtual bool lseek(Sysio *sysio) { return false; } /** * Return true if an unblocking condition of the channel is satisfied * * \param rd if true, check for data available for reading * \param wr if true, check for readiness for writing * \param ex if true, check for exceptions */ virtual bool check_unblock(bool rd, bool wr, bool ex) const { return false; } /** * Return true if the channel is set to non-blocking mode */ virtual bool is_nonblocking() { return false; } /** * Register blocker for getting waked up on an I/O channel event * * This function is normally called by the to-be-blocked thread * prior blocking itself, e.g., during a 'select' syscall. */ void register_wake_up_notifier(Wake_up_notifier *notifier) { Lock::Guard guard(_notifiers_lock); _notifiers.insert(notifier); } /** * Unregister wake-up notifier * * This function is normally called after a blocker has left the * blocking condition, e.g., during the return from the 'select' * syscall'. */ void unregister_wake_up_notifier(Wake_up_notifier *notifier) { Lock::Guard guard(_notifiers_lock); _notifiers.remove(notifier); } /** * Tell all registered notifiers about an occurred I/O event * * This function is called by I/O channel implementations that * respond to external signals, e.g., the availability of new * input from a terminal session. */ void invoke_all_notifiers() { Lock::Guard guard(_notifiers_lock); for (Wake_up_notifier *n = _notifiers.first(); n; n = n->next()) n->wake_up(); } }; } #endif /* _NOUX__IO_CHANNEL_H_ */