Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/libremidi/backends/alsa_seq/helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ inline void for_all_ports(
const libasound& snd, snd_seq_t* seq,
const std::function<void(snd_seq_client_info_t&, snd_seq_port_info_t&)>& func)
{
if (!seq)
return;
snd_seq_client_info_t* cinfo{};
snd_seq_client_info_alloca(&cinfo);
snd_seq_port_info_t* pinfo{};
Expand All @@ -102,6 +104,8 @@ inline void for_all_ports(
const libasound& snd, snd_seq_t* seq, int client,
const std::function<void(snd_seq_port_info_t&)>& func)
{
if (!seq)
return;
snd_seq_port_info_t* pinfo{};
snd_seq_port_info_alloca(&pinfo);

Expand All @@ -119,6 +123,8 @@ inline unsigned int iterate_port_info(
const libasound& snd, snd_seq_t* seq, snd_seq_port_info_t* pinfo, unsigned int type,
int portNumber)
{
if (!seq)
return 0;
snd_seq_client_info_t* cinfo{};
int count = 0;
snd_seq_client_info_alloca(&cinfo);
Expand Down Expand Up @@ -182,7 +188,11 @@ struct alsa_data
// Set up the ALSA sequencer client.
int ret = snd.seq.open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK);
if (ret < 0)
{
// Every user of seq checks it against nullptr to know the client failed
seq = nullptr;
return ret;
}

// Set client name.
if (!configuration.client_name.empty())
Expand Down
10 changes: 10 additions & 0 deletions include/libremidi/backends/alsa_seq/midi_in.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ class midi_in_impl

~midi_in_impl() override
{
if (!this->seq)
return;

// Cleanup.
if (this->vport >= 0)
snd.seq.delete_port(this->seq, this->vport);
Expand Down Expand Up @@ -190,6 +193,8 @@ class midi_in_impl

stdx::error close_port() override
{
if (!this->seq)
return stdx::error{};
unsubscribe();
stop_queue();
return stdx::error{};
Expand Down Expand Up @@ -348,6 +353,11 @@ class midi_in_alsa_threaded : public midi_in_impl<ConfigurationBase, Configurati
midi_in_alsa_threaded(ConfigurationBase&& conf, ConfigurationImpl&& apiconf)
: midi_in_impl<ConfigurationBase, ConfigurationImpl>{std::move(conf), std::move(apiconf)}
{
// The base already reported the failed client. Do not claim to be open, or
// midi_in::open_*_port goes on to snd_seq_create_port(NULL, ...).
if (!this->seq)
return;

if (this->m_termination_event < 0)
{
this->libremidi_handle_error(this->configuration, "error creating eventfd.");
Expand Down
3 changes: 3 additions & 0 deletions include/libremidi/backends/alsa_seq/midi_out.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class midi_out_impl final

~midi_out_impl() override
{
if (!this->seq)
return;

// Close a connection if it exists.
midi_out_impl::close_port();

Expand Down
13 changes: 12 additions & 1 deletion include/libremidi/backends/alsa_seq/observer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,11 @@ class observer_threaded : public observer_impl<ConfigurationImpl>
observer_threaded(libremidi::observer_configuration&& conf, ConfigurationImpl&& apiconf)
: observer_impl<ConfigurationImpl>{std::move(conf), std::move(apiconf)}
{
// init_client failed (no /dev/snd/seq, e.g. snd-seq not loaded): nothing
// to poll, and snd_seq_poll_descriptors(NULL, ...) segfaults.
if (!this->seq)
return;

// Create relevant descriptors
auto& snd = alsa_data::snd;

Expand Down Expand Up @@ -474,14 +479,20 @@ class observer_manual : public observer_impl<ConfigurationImpl>
observer_manual(libremidi::observer_configuration&& conf, ConfigurationImpl&& apiconf)
: observer_impl<ConfigurationImpl>{std::move(conf), std::move(apiconf)}
{
if (!this->seq)
return;
this->configuration.manual_poll(
poll_parameters{.addr = this->vaddr, .callback = [this](const auto& v) {
this->handle_event_direct(v);
return 0;
}});
}

~observer_manual() { this->configuration.stop_poll(this->vaddr); }
~observer_manual()
{
if (this->seq)
this->configuration.stop_poll(this->vaddr);
}
};
}

Expand Down
Loading