genode/ports/src/noux/io_channel.h

137 lines
3.5 KiB
C++

/*
* \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 <base/lock.h>
/* Noux includes */
#include <noux_session/sysio.h>
#include <shared_pointer.h>
#include <wake_up_notifier.h>
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<Wake_up_notifier> _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_ */