--- a/src/JackHandler.h Sun Oct 04 12:40:00 2020 +0200
+++ b/src/JackHandler.h Sun Oct 04 18:26:59 2020 +0200
@@ -155,13 +155,25 @@
std::wcerr << L"JACK: " << convertor.from_bytes(message) << std::endl;
}
+ void finalize() {
+ // Close JACK connection:
+ jack_deactivate(realTimeContext.jackClient);
+ jack_client_close(realTimeContext.jackClient);
+ jack_ringbuffer_free(realTimeContext.ringBuffer);
+ }
+
+ void failInConstructor(const relpipe::common::type::StringX& errorMessage) {
+ finalize();
+ throw JackException(errorMessage);
+ }
+
public:
JackHandler(Configuration& configuration) : configuration(configuration) {
// Initialize JACK connection:
std::string clientName = convertor.to_bytes(configuration.jackClientName);
realTimeContext.jackClient = jack_client_open(clientName.c_str(), JackNullOption, nullptr);
- if (realTimeContext.jackClient == nullptr) throw JackException(L"Could not create JACK client.");
+ if (realTimeContext.jackClient == nullptr) failInConstructor(L"Could not create JACK client.");
realTimeContext.ringBuffer = jack_ringbuffer_create(realTimeContext.RING_BUFFER_SIZE * sizeof (MidiMessage));
@@ -172,25 +184,24 @@
jack_set_info_function(jackErrorCallback);
realTimeContext.jackPort = jack_port_register(realTimeContext.jackClient, "output", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
- if (realTimeContext.jackPort == nullptr) throw JackException(L"Could not register port.");
+ if (realTimeContext.jackPort == nullptr) failInConstructor(L"Could not register the JACK port.");
if (mlockall(MCL_CURRENT | MCL_FUTURE)) fwprintf(stderr, L"Warning: Can not lock memory.\n");
int jackError = jack_activate(realTimeContext.jackClient);
- if (jackError) throw JackException(L"Could not activate client.");
+ if (jackError) failInConstructor(L"Could not activate the JACK client.");
// Connect to configured destination ports:
const char* jackPortName = jack_port_name(realTimeContext.jackPort);
for (auto destinationPort : configuration.portsToConnect) {
int error = jack_connect(realTimeContext.jackClient, jackPortName, convertor.to_bytes(destinationPort).c_str());
- if (error) throw JackException(L"Connection to the JACK port failed: " + destinationPort);
+ if (error) failInConstructor(L"Connection to the JACK port failed: " + destinationPort);
}
// Wait for a port connection, because it does not make much sense to send MIDI events nowhere:
while (jack_port_connected(realTimeContext.jackPort) < configuration.requiredJackConnections) usleep(10000);
- // TODO: finalize on exceptions
}
void startRelation(const relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override {
@@ -290,10 +301,7 @@
}
virtual ~JackHandler() {
- // Close JACK connection:
- jack_deactivate(realTimeContext.jackClient);
- jack_client_close(realTimeContext.jackClient);
- jack_ringbuffer_free(realTimeContext.ringBuffer);
+ finalize();
}
};