Skip to content

Commit ae48497

Browse files
committed
adc: hardware: improve/simplify error handling
Now that errors from threads are properly propagated we can simplify the error handling and do not have to transfer `Result`s across queues if something goes wrong during thread setup. Signed-off-by: Leonard Göhrs <l.goehrs@pengutronix.de>
1 parent 512763c commit ae48497

File tree

1 file changed

+15
-42
lines changed

1 file changed

+15
-42
lines changed

src/adc/iio/hardware.rs

Lines changed: 15 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use std::path::Path;
2222
use std::sync::atomic::{AtomicU16, AtomicU64, Ordering};
2323
use std::time::{Duration, Instant};
2424

25-
use anyhow::{anyhow, Context, Error, Result};
25+
use anyhow::{anyhow, Context, Result};
2626
use async_std::channel::bounded;
2727
use async_std::sync::Arc;
2828

@@ -275,40 +275,27 @@ impl IioThread {
275275
// setup was sucessful.
276276
// This is why we create Self inside the thread and send it back
277277
// to the calling thread via a queue.
278-
let (thread_res_tx, thread_res_rx) = bounded(1);
278+
let (thread_tx, thread_rx) = bounded(1);
279279

280280
// Spawn a high priority thread that updates the atomic values in `thread`.
281281
wtb.spawn_thread(thread_name, move || {
282-
let adc_setup_res = Self::adc_setup(
282+
let (channels, mut buf) = Self::adc_setup(
283283
adc_name,
284284
trigger_name,
285285
sample_rate,
286286
channel_descs,
287287
buffer_len,
288-
);
289-
let (thread, channels, mut buf) = match adc_setup_res {
290-
Ok((channels, buf)) => {
291-
let thread = Arc::new(Self {
292-
ref_instant: Instant::now(),
293-
timestamp: AtomicU64::new(TIMESTAMP_ERROR),
294-
values: channels.iter().map(|_| AtomicU16::new(0)).collect(),
295-
channel_descs,
296-
});
297-
298-
(thread, channels, buf)
299-
}
300-
Err(e) => {
301-
// Can not fail in practice as the queue is known to be empty
302-
// at this point.
303-
thread_res_tx
304-
.try_send(Err(e))
305-
.expect("Failed to signal ADC setup error due to full queue");
306-
return Ok(());
307-
}
308-
};
288+
)?;
289+
290+
let thread = Arc::new(Self {
291+
ref_instant: Instant::now(),
292+
timestamp: AtomicU64::new(TIMESTAMP_ERROR),
293+
values: channels.iter().map(|_| AtomicU16::new(0)).collect(),
294+
channel_descs,
295+
});
309296

310297
let thread_weak = Arc::downgrade(&thread);
311-
let mut signal_ready = Some((thread, thread_res_tx));
298+
let mut signal_ready = Some((thread, thread_tx));
312299

313300
// Stop running as soon as the last reference to this Arc<IioThread>
314301
// is dropped (e.g. the weak reference can no longer be upgraded).
@@ -318,18 +305,7 @@ impl IioThread {
318305

319306
error!("Failed to refill {} ADC buffer: {}", adc_name, e);
320307

321-
// If the ADC has not yet produced any values we still have the
322-
// queue at hand that signals readiness to the main thread.
323-
// This gives us a chance to return an Err from new().
324-
// If the queue was already used just print an error instead.
325-
if let Some((_, tx)) = signal_ready.take() {
326-
// Can not fail in practice as the queue is only .take()n
327-
// once and thus known to be empty.
328-
tx.try_send(Err(Error::new(e)))
329-
.expect("Failed to signal ADC setup error due to full queue");
330-
}
331-
332-
break;
308+
Err(e)?;
333309
}
334310

335311
let values = channels.iter().map(|ch| {
@@ -356,17 +332,14 @@ impl IioThread {
356332
if let Some((content, tx)) = signal_ready.take() {
357333
// Can not fail in practice as the queue is only .take()n
358334
// once and thus known to be empty.
359-
tx.try_send(Ok(content))
360-
.expect("Failed to signal ADC setup completion due to full queue");
335+
tx.try_send(content)?;
361336
}
362337
}
363338

364339
Ok(())
365340
})?;
366341

367-
let thread = thread_res_rx.recv().await??;
368-
369-
Ok(thread)
342+
Ok(thread_rx.recv().await?)
370343
}
371344

372345
pub async fn new_stm32(

0 commit comments

Comments
 (0)