Skip to content

Commit f12ed4d

Browse files
committed
observer: fix that some backends would be in inconsistent observer state when no notify_in_constructor
1 parent f02c685 commit f12ed4d

4 files changed

Lines changed: 45 additions & 39 deletions

File tree

include/libremidi/backends/alsa_raw/observer.hpp

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ class observer_impl_base
5454
#endif
5555

5656
// Set-up initial state
57-
if (configuration.notify_in_constructor)
58-
this->check_devices();
57+
this->check_devices(configuration.notify_in_constructor);
5958

6059
#if LIBREMIDI_HAS_UDEV
6160
// Start thread
@@ -139,7 +138,7 @@ class observer_impl_base
139138
this->m_timer_fd.cancel();
140139
m_fds[2].revents = 0;
141140

142-
check_devices();
141+
check_devices(true);
143142
}
144143
}
145144
}
@@ -185,7 +184,7 @@ class observer_impl_base
185184
.type = type}};
186185
}
187186

188-
void check_devices()
187+
void check_devices(bool notify)
189188
{
190189
Enumerator new_devs{*this};
191190

@@ -203,18 +202,6 @@ class observer_impl_base
203202
}
204203
}
205204

206-
for (auto& in_next : new_devs.inputs)
207-
{
208-
if (auto it = std::find(m_current_inputs.begin(), m_current_inputs.end(), in_next);
209-
it == m_current_inputs.end())
210-
{
211-
if (auto& cb = this->configuration.input_added)
212-
{
213-
cb(to_port_info<true>(in_next));
214-
}
215-
}
216-
}
217-
218205
for (auto& out_prev : m_current_outputs)
219206
{
220207
if (auto it = std::find(new_devs.outputs.begin(), new_devs.outputs.end(), out_prev);
@@ -227,14 +214,29 @@ class observer_impl_base
227214
}
228215
}
229216

230-
for (auto& out_next : new_devs.outputs)
217+
if (notify)
231218
{
232-
if (auto it = std::find(m_current_outputs.begin(), m_current_outputs.end(), out_next);
233-
it == m_current_outputs.end())
219+
if (auto& cb = this->configuration.input_added)
220+
{
221+
for (auto& in_next : new_devs.inputs)
222+
{
223+
if (auto it = std::find(m_current_inputs.begin(), m_current_inputs.end(), in_next);
224+
it == m_current_inputs.end())
225+
{
226+
cb(to_port_info<true>(in_next));
227+
}
228+
}
229+
}
230+
231+
if (auto& cb = this->configuration.output_added)
234232
{
235-
if (auto& cb = this->configuration.output_added)
233+
for (auto& out_next : new_devs.outputs)
236234
{
237-
cb(to_port_info<false>(out_next));
235+
if (auto it = std::find(m_current_outputs.begin(), m_current_outputs.end(), out_next);
236+
it == m_current_outputs.end())
237+
{
238+
cb(to_port_info<false>(out_next));
239+
}
238240
}
239241
}
240242
}

include/libremidi/backends/alsa_seq/observer.hpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ class observer_impl
6565
return;
6666

6767
// Init with the existing ports
68-
if (configuration.notify_in_constructor)
69-
init_all_ports();
68+
init_all_ports();
7069

7170
// Create the port to listen on the server events
7271
{
@@ -222,7 +221,7 @@ class observer_impl
222221
snd, this->seq, [this](snd_seq_client_info_t& client, snd_seq_port_info_t& port) {
223222
int clt = snd.seq.client_info_get_client(&client);
224223
int pt = snd.seq.port_info_get_port(&port);
225-
register_port(clt, pt);
224+
register_port(clt, pt, configuration.notify_in_constructor);
226225
});
227226
}
228227

@@ -262,7 +261,7 @@ class observer_impl
262261
return ret;
263262
}
264263

265-
void register_port(int client, int port)
264+
void register_port(int client, int port, bool notify)
266265
{
267266
auto pp = get_info(client, port);
268267
if (!pp)
@@ -272,14 +271,17 @@ class observer_impl
272271
return;
273272

274273
m_knownClients[{p.client, p.port}] = p;
275-
if (p.is_input && configuration.input_added)
274+
if (notify)
276275
{
277-
configuration.input_added(to_port_info<true>(p));
278-
}
276+
if (p.is_input && configuration.input_added)
277+
{
278+
configuration.input_added(to_port_info<true>(p));
279+
}
279280

280-
if (p.is_output && configuration.output_added)
281-
{
282-
configuration.output_added(to_port_info<false>(p));
281+
if (p.is_output && configuration.output_added)
282+
{
283+
configuration.output_added(to_port_info<false>(p));
284+
}
283285
}
284286
}
285287

@@ -330,7 +332,7 @@ class observer_impl
330332
}
331333
#endif
332334
case SND_SEQ_EVENT_PORT_START: {
333-
this->register_port(ev.data.addr.client, ev.data.addr.port);
335+
this->register_port(ev.data.addr.client, ev.data.addr.port, true);
334336
break;
335337
}
336338
case SND_SEQ_EVENT_PORT_EXIT: {

include/libremidi/backends/emscripten/observer.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ LIBREMIDI_INLINE observer_emscripten::observer_emscripten(
1919
// Trigger an initial notification
2020
webmidi.load_current_infos();
2121

22-
if (configuration.notify_in_constructor)
23-
update(webmidi.inputs(), webmidi.outputs());
22+
update(webmidi.inputs(), webmidi.outputs(), configuration.notify_in_constructor);
2423
}
2524

2625
LIBREMIDI_INLINE observer_emscripten::~observer_emscripten()
@@ -83,7 +82,7 @@ std::vector<libremidi::output_port> observer_emscripten::get_output_ports() cons
8382

8483
LIBREMIDI_INLINE void observer_emscripten::update(
8584
const std::vector<observer_emscripten::device>& current_inputs,
86-
const std::vector<observer_emscripten::device>& current_outputs)
85+
const std::vector<observer_emscripten::device>& current_outputs, bool notify)
8786
{
8887
// WebMIDI never remove inputs, it just marks them as disconnected.
8988
// At least in known browsers...
@@ -93,13 +92,15 @@ LIBREMIDI_INLINE void observer_emscripten::update(
9392
for (std::size_t i = m_known_inputs.size(); i < current_inputs.size(); i++)
9493
{
9594
m_known_inputs.push_back(current_inputs[i]);
96-
configuration.input_added(to_port_info<true>(i, m_known_inputs[i]));
95+
if (notify)
96+
configuration.input_added(to_port_info<true>(i, m_known_inputs[i]));
9797
}
9898

9999
for (std::size_t i = m_known_outputs.size(); i < current_outputs.size(); i++)
100100
{
101101
m_known_outputs.push_back(current_outputs[i]);
102-
configuration.output_added(to_port_info<false>(i, m_known_outputs[i]));
102+
if (notify)
103+
configuration.output_added(to_port_info<false>(i, m_known_outputs[i]));
103104
}
104105
}
105106
}

include/libremidi/backends/emscripten/observer.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ class observer_emscripten final : public observer_api
2222
observer_configuration&& conf, emscripten_observer_configuration&& apiconf);
2323
~observer_emscripten();
2424

25-
void
26-
update(const std::vector<device>& current_inputs, const std::vector<device>& current_outputs);
25+
void update(
26+
const std::vector<device>& current_inputs, const std::vector<device>& current_outputs,
27+
bool notify);
2728

2829
libremidi::API get_current_api() const noexcept override;
2930

0 commit comments

Comments
 (0)