dde_bsd: implemented delayed session announcement

This becomes necessary in case of the USB audio driver where we have
to wait for and query the function first.

That being said, alternatively we could also announce the session but
ignore any request until there is a device we can use.

Issue #3929.
This commit is contained in:
Josef Söntgen 2020-06-26 16:14:44 +02:00 committed by Christian Helmuth
parent 2ec398e550
commit cd7c99afdc
3 changed files with 46 additions and 28 deletions

View File

@ -43,9 +43,8 @@ namespace Audio {
void update_config(Genode::Env &, Genode::Xml_node);
void init_driver(Genode::Env &, Genode::Allocator &, Genode::Xml_node);
bool driver_active();
void init_driver(Genode::Env &, Genode::Allocator &, Genode::Xml_node,
Genode::Signal_context_capability);
void play_sigh(Genode::Signal_context_capability cap);

View File

@ -500,26 +500,37 @@ struct Main
Audio::update_config(env, config.xml());
}
Genode::Constructible<Audio_out::Out> _out { };
Genode::Constructible<Audio_out::Root> _out_root { };
Genode::Constructible<Audio_in::In> _in { };
Genode::Constructible<Audio_in::Root> _in_root { };
Genode::Signal_handler<Main> announce_session_dispatcher {
env.ep(), *this, &Main::handle_announce_session };
void handle_announce_session()
{
_out.construct(env);
Audio::play_sigh(_out->sigh());
_out_root.construct(env, heap, _out->data_avail());
env.parent().announce(env.ep().manage(*_out_root));
_in.construct(env);
Audio::record_sigh(_in->sigh());
_in_root.construct(env, heap,
Genode::Signal_context_capability());
env.parent().announce(env.ep().manage(*_in_root));
}
Main(Genode::Env &env) : env(env)
{
Audio::init_driver(env, heap, config.xml());
if (!Audio::driver_active()) {
return;
}
static Audio_out::Out out(env);
Audio::play_sigh(out.sigh());
static Audio_out::Root out_root(env, heap, out.data_avail());
env.parent().announce(env.ep().manage(out_root));
static Audio_in::In in(env);
Audio::record_sigh(in.sigh());
static Audio_in::Root in_root(env, heap,
Genode::Signal_context_capability());
env.parent().announce(env.ep().manage(in_root));
config.sigh(config_update_dispatcher);
Audio::init_driver(env, heap, config.xml(),
announce_session_dispatcher);
}
};

View File

@ -417,10 +417,15 @@ namespace {
Genode::Env &env;
Genode::Allocator &alloc;
Genode::Xml_node config;
Genode::Signal_context_capability announce_sigh;
Task_args(Genode::Env &env, Genode::Allocator &alloc,
Genode::Xml_node config)
: env(env), alloc(alloc), config(config) { }
Genode::Xml_node config,
Genode::Signal_context_capability announce_sigh)
:
env(env), alloc(alloc), config(config),
announce_sigh(announce_sigh)
{ }
};
}
@ -429,7 +434,8 @@ static void run_bsd(void *p)
{
Task_args *args = static_cast<Task_args*>(p);
if (!Bsd::probe_drivers(args->env, args->alloc)) {
int const success = Bsd::probe_drivers(args->env, args->alloc);
if (!success) {
Genode::error("no supported sound card found");
Genode::sleep_forever();
}
@ -441,6 +447,10 @@ static void run_bsd(void *p)
adev_usuable = configure_audio_device(args->env, adev, args->config);
if (adev_usuable && args->announce_sigh.valid()) {
Genode::Signal_transmitter(args->announce_sigh).submit();
}
while (true) {
Bsd::scheduler().current()->block_and_schedule();
}
@ -488,13 +498,14 @@ void Audio::update_config(Genode::Env &env, Genode::Xml_node config)
void Audio::init_driver(Genode::Env &env, Genode::Allocator &alloc,
Genode::Xml_node config)
Genode::Xml_node config,
Genode::Signal_context_capability announce_sigh)
{
Bsd::mem_init(env, alloc);
Bsd::irq_init(env.ep(), alloc);
Bsd::timer_init(env);
static Task_args args(env, alloc, config);
static Task_args args(env, alloc, config, announce_sigh);
static Bsd::Task task_bsd(run_bsd, &args, "bsd",
Bsd::Task::PRIORITY_0, Bsd::scheduler(),
@ -503,9 +514,6 @@ void Audio::init_driver(Genode::Env &env, Genode::Allocator &alloc,
}
bool Audio::driver_active() { return drv_loaded() && adev_usuable; }
void Audio::play_sigh(Genode::Signal_context_capability sigh) {
_play_sigh = sigh; }