Skip to content

Commit

Permalink
gh-748: Add IDevice::close()
Browse files Browse the repository at this point in the history
  • Loading branch information
runei authored and gavv committed Jul 28, 2024
1 parent 68f938b commit 1818806
Show file tree
Hide file tree
Showing 35 changed files with 230 additions and 34 deletions.
5 changes: 5 additions & 0 deletions src/internal_modules/roc_pipeline/receiver_loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ bool ReceiverLoop::has_clock() const {
return source_.has_clock();
}

status::StatusCode ReceiverLoop::close() {
core::Mutex::Lock lock(source_mutex_);
return source_.close();
}

status::StatusCode ReceiverLoop::rewind() {
core::Mutex::Lock lock(source_mutex_);

Expand Down
1 change: 1 addition & 0 deletions src/internal_modules/roc_pipeline/receiver_loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class ReceiverLoop : public PipelineLoop, private sndio::ISource {
virtual bool has_latency() const;
virtual core::nanoseconds_t latency() const;
virtual bool has_clock() const;
virtual status::StatusCode close();
virtual status::StatusCode rewind();
virtual void reclock(core::nanoseconds_t timestamp);
virtual status::StatusCode read(audio::Frame& frame,
Expand Down
4 changes: 4 additions & 0 deletions src/internal_modules/roc_pipeline/receiver_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ bool ReceiverSource::has_clock() const {
return source_config_.common.enable_cpu_clock;
}

status::StatusCode ReceiverSource::close() {
return status::StatusOK;
}

status::StatusCode ReceiverSource::rewind() {
return status::StatusOK;
}
Expand Down
3 changes: 3 additions & 0 deletions src/internal_modules/roc_pipeline/receiver_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ class ReceiverSource : public sndio::ISource, public core::NonCopyable<> {
//! Check if the source has own clock.
virtual bool has_clock() const;

//! Explicitly close the source.
virtual ROC_ATTR_NODISCARD status::StatusCode close();

//! Restart reading from beginning.
virtual ROC_ATTR_NODISCARD status::StatusCode rewind();

Expand Down
5 changes: 5 additions & 0 deletions src/internal_modules/roc_pipeline/sender_loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ bool SenderLoop::has_state() const {
return sink_.has_state();
}

status::StatusCode SenderLoop::close() {
core::Mutex::Lock lock(sink_mutex_);
return sink_.close();
}

sndio::DeviceState SenderLoop::state() const {
core::Mutex::Lock lock(sink_mutex_);

Expand Down
1 change: 1 addition & 0 deletions src/internal_modules/roc_pipeline/sender_loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ class SenderLoop : public PipelineLoop, private sndio::ISink {
virtual core::nanoseconds_t latency() const;
virtual bool has_clock() const;
virtual status::StatusCode write(audio::Frame& frame);
virtual status::StatusCode close();

// Methods of PipelineLoop
virtual core::nanoseconds_t timestamp_imp() const;
Expand Down
4 changes: 4 additions & 0 deletions src/internal_modules/roc_pipeline/sender_sink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ bool SenderSink::has_clock() const {
return sink_config_.enable_cpu_clock;
}

status::StatusCode SenderSink::close() {
return status::StatusOK;
}

status::StatusCode SenderSink::write(audio::Frame& frame) {
roc_panic_if(init_status_ != status::StatusOK);

Expand Down
3 changes: 3 additions & 0 deletions src/internal_modules/roc_pipeline/sender_sink.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ class SenderSink : public sndio::ISink, public core::NonCopyable<> {
//! Check if the sink has own clock.
virtual bool has_clock() const;

//! Explicitly close the sink.
virtual ROC_ATTR_NODISCARD status::StatusCode close();

//! Write frame.
virtual ROC_ATTR_NODISCARD status::StatusCode write(audio::Frame& frame);

Expand Down
4 changes: 4 additions & 0 deletions src/internal_modules/roc_pipeline/transcoder_sink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ bool TranscoderSink::has_clock() const {
return false;
}

status::StatusCode TranscoderSink::close() {
return status::StatusOK;
}

status::StatusCode TranscoderSink::write(audio::Frame& frame) {
roc_panic_if(init_status_ != status::StatusOK);

Expand Down
3 changes: 3 additions & 0 deletions src/internal_modules/roc_pipeline/transcoder_sink.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ class TranscoderSink : public sndio::ISink, public core::NonCopyable<> {
//! Check if the sink has own clock.
virtual bool has_clock() const;

//! Explicitly close the sink.
virtual ROC_ATTR_NODISCARD status::StatusCode close();

//! Write frame.
virtual ROC_ATTR_NODISCARD status::StatusCode write(audio::Frame& frame);

Expand Down
4 changes: 4 additions & 0 deletions src/internal_modules/roc_pipeline/transcoder_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ bool TranscoderSource::has_clock() const {
return input_source_.has_clock();
}

status::StatusCode TranscoderSource::close() {
return input_source_.close();
}

status::StatusCode TranscoderSource::rewind() {
return input_source_.rewind();
}
Expand Down
3 changes: 3 additions & 0 deletions src/internal_modules/roc_pipeline/transcoder_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ class TranscoderSource : public sndio::ISource, public core::NonCopyable<> {
//! Check if the source has own clock.
virtual bool has_clock() const;

//! Explicitly close the source.
virtual ROC_ATTR_NODISCARD status::StatusCode close();

//! Restart reading from beginning.
virtual ROC_ATTR_NODISCARD status::StatusCode rewind();

Expand Down
7 changes: 7 additions & 0 deletions src/internal_modules/roc_sndio/idevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ class IDevice {
//! If false, the user is responsible to maintain the clock and
//! perform writes or read in-time.
virtual bool has_clock() const = 0;

//! Explicitly close the device.
//! @remarks
//! This method should be called to release resources held by the device
//! before the object is destructed. If this method is not called before
//! the destructor, the destructor will trigger a panic.
virtual ROC_ATTR_NODISCARD status::StatusCode close() = 0;
};

} // namespace sndio
Expand Down
24 changes: 23 additions & 1 deletion src/internal_modules/roc_sndio/pump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,11 @@ status::StatusCode Pump::run() {
code = status::StatusOK; // EOF is fine
}

status::StatusCode close_code = close_all_devices_();

roc_log(LogDebug, "pump: exiting main loop");

return code;
return (code != status::StatusOK) ? code : close_code;
}

void Pump::stop() {
Expand Down Expand Up @@ -273,5 +275,25 @@ status::StatusCode Pump::transfer_frame_(ISource& source, ISink& sink) {
return status::StatusOK;
}

status::StatusCode Pump::close_all_devices_() {
IDevice* devices[] = { &main_source_, &sink_, backup_source_ };
status::StatusCode first_error = status::StatusOK;

for (size_t i = 0; i < ROC_ARRAY_SIZE(devices); ++i) {
if (devices[i]) {
status::StatusCode device_code = devices[i]->close();
if (device_code != status::StatusOK) {
roc_log(LogError, "pump: failed to close device with error %s",
status::code_to_str(device_code));
if (first_error == status::StatusOK) {
first_error = device_code;
}
}
}
}

return first_error;
}

} // namespace sndio
} // namespace roc
1 change: 1 addition & 0 deletions src/internal_modules/roc_sndio/pump.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class Pump : public core::NonCopyable<> {
status::StatusCode next_();
status::StatusCode switch_source_(ISource* new_source);
status::StatusCode transfer_frame_(ISource& source, ISink& sink);
status::StatusCode close_all_devices_();

audio::FrameFactory frame_factory_;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,18 @@ PulseaudioDevice::PulseaudioDevice(audio::FrameFactory& frame_factory,
}

PulseaudioDevice::~PulseaudioDevice() {
if (mainloop_) {
roc_panic("pulseaudio %s: device not closed", device_type_to_str(device_type_));
}
}

status::StatusCode PulseaudioDevice::close() {
roc_log(LogDebug, "pulseaudio %s: closing device", device_type_to_str(device_type_));

close_();
stop_mainloop_();

return status::StatusOK;
}

status::StatusCode PulseaudioDevice::init_status() const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ class PulseaudioDevice : public ISink, public ISource, public core::NonCopyable<
//! Check if the device has own clock.
virtual bool has_clock() const;

//! Explicitly close the device.
virtual ROC_ATTR_NODISCARD status::StatusCode close();

//! Restart reading from beginning.
virtual ROC_ATTR_NODISCARD status::StatusCode rewind();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,13 @@ SndfileSink::SndfileSink(audio::FrameFactory& frame_factory,
}

SndfileSink::~SndfileSink() {
close_();
if (file_) {
roc_panic("sndfile sink: output file is not closed");
}
}

status::StatusCode SndfileSink::close() {
return close_();
}

status::StatusCode SndfileSink::init_status() const {
Expand Down Expand Up @@ -273,9 +279,9 @@ status::StatusCode SndfileSink::open_(const char* driver, const char* path) {
return status::StatusOK;
}

void SndfileSink::close_() {
status::StatusCode SndfileSink::close_() {
if (!file_) {
return;
return status::StatusOK;
}

roc_log(LogDebug, "sndfile sink: closing output");
Expand All @@ -285,9 +291,12 @@ void SndfileSink::close_() {
roc_log(LogError,
"sndfile sink: sf_close() failed, cannot properly close output: %s",
sf_error_number(err));
return status::StatusErrFile;
}

file_ = NULL;

return status::StatusOK;
}

} // namespace sndio
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,15 @@ class SndfileSink : public ISink, public core::NonCopyable<> {
//! Check if the sink has own clock.
virtual bool has_clock() const;

//! Explicitly close the sink.
virtual ROC_ATTR_NODISCARD status::StatusCode close();

//! Write frame.
virtual ROC_ATTR_NODISCARD status::StatusCode write(audio::Frame& frame);

private:
status::StatusCode open_(const char* driver, const char* path);
void close_();
status::StatusCode close_();

SNDFILE* file_;
SF_INFO file_info_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "roc_core/log.h"
#include "roc_core/panic.h"
#include "roc_sndio/backend_map.h"
#include "roc_status/code_to_str.h"

namespace roc {
namespace sndio {
Expand Down Expand Up @@ -41,7 +42,13 @@ SndfileSource::SndfileSource(audio::FrameFactory& frame_factory,
}

SndfileSource::~SndfileSource() {
close_();
if (file_) {
roc_panic("sndfile source: input file is not closed");
}
}

status::StatusCode SndfileSource::close() {
return close_();
}

status::StatusCode SndfileSource::init_status() const {
Expand Down Expand Up @@ -107,8 +114,14 @@ status::StatusCode SndfileSource::rewind() {
}

if (file_) {
close_();
const status::StatusCode close_code = close_();
if (close_code != status::StatusOK) {
roc_log(LogError, "sndfile source: failed to close file during rewind: %s",
status::code_to_str(close_code));
return close_code;
}
}

return open_();
}

Expand Down Expand Up @@ -197,9 +210,9 @@ status::StatusCode SndfileSource::open_() {
return status::StatusOK;
}

void SndfileSource::close_() {
status::StatusCode SndfileSource::close_() {
if (!file_) {
return;
return status::StatusOK;
}

roc_log(LogInfo, "sndfile source: closing input");
Expand All @@ -209,9 +222,12 @@ void SndfileSource::close_() {
roc_log(LogError,
"sndfile source: sf_close() failed, cannot properly close input: %s",
sf_error_number(err));
return status::StatusErrFile;
}

file_ = NULL;

return status::StatusOK;
}

} // namespace sndio
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class SndfileSource : public ISource, private core::NonCopyable<> {
//! Check if the source has own clock.
virtual bool has_clock() const;

//! Explicitly close the source.
virtual ROC_ATTR_NODISCARD status::StatusCode close();

//! Restart reading from beginning.
virtual ROC_ATTR_NODISCARD status::StatusCode rewind();

Expand All @@ -78,7 +81,7 @@ class SndfileSource : public ISource, private core::NonCopyable<> {

private:
status::StatusCode open_();
void close_();
status::StatusCode close_();

status::StatusCode seek_(size_t offset);

Expand Down
Loading

0 comments on commit 1818806

Please sign in to comment.