/* * \brief Client-side Audio_out-session * \author Sebastian Sumpf * \date 2012-12-20 */ /* * Copyright (C) 2012-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 _INCLUDE__AUDIO_OUT_SESSION__CLIENT_H_ #define _INCLUDE__AUDIO_OUT_SESSION__CLIENT_H_ #include #include #include namespace Audio_out { struct Signal; struct Session_client; } struct Audio_out::Signal { Genode::Signal_receiver recv; Genode::Signal_context context; Genode::Signal_context_capability cap; Signal() : cap(recv.manage(&context)) { } void wait() { recv.wait_for_signal(); } }; class Audio_out::Session_client : public Genode::Rpc_client { private: Signal _progress; Signal _alloc; Genode::Signal_transmitter _data_avail; public: /** * Constructor * * \param session session capability * \param alloc_signal true, install 'alloc_signal' receiver * \param progress_signal true, install 'progress_signal' receiver */ Session_client(Genode::Capability session, bool alloc_signal, bool progress_signal) : Genode::Rpc_client(session), _data_avail(call()) { /* ask server for stream data space and attach it */ _stream = static_cast(Genode::env()->rm_session()->attach(call())); if (progress_signal) progress_sigh(_progress.cap); if (alloc_signal) alloc_sigh(_alloc.cap); } /************* ** Signals ** *************/ void progress_sigh(Genode::Signal_context_capability sigh) { call(sigh); } void alloc_sigh(Genode::Signal_context_capability sigh) { call(sigh); } Genode::Signal_context_capability data_avail_sigh() { return Genode::Signal_context_capability(); } /*********************** ** Session interface ** ***********************/ void start() { call(); /* reset tail pointer */ stream()->reset(); } void stop() { call(); } /********************************** ** Session interface extensions ** **********************************/ /** * Wait for progress signal */ void wait_for_progress() { if (!_progress.cap.valid()) { PWRN("Progress signal is not installed, will not block " "(enable in 'Audio_out::Connection')"); return; } _progress.wait(); } /** * Wait for allocation signal * * This can be used when the 'Stream' is full and the application wants * to block until the stream has free elements again. */ void wait_for_alloc() { if (!_alloc.cap.valid()) { PWRN("Alloc signal is not installed, will not block " "(enable in 'Audio_out::Connection')"); return; } _alloc.wait(); } /** * Submit a packet */ void submit(Packet *packet) { bool empty = stream()->empty(); packet->_submit(); if (empty) _data_avail.submit(); } }; #endif /* _INCLUDE__AUDIO_OUT_SESSION__CLIENT_H_ */