commit 96be27ae41b9f43899effb7b20b10fb995013c49
parent 37862e5a766cf657da28aa18b5a9fe23c312ce9a
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date: Tue, 17 Aug 2021 16:11:27 +0200
Fix cute troubles
Diffstat:
11 files changed, 122 insertions(+), 56 deletions(-)
diff --git a/examples/gui/CMakeLists.txt b/examples/gui/CMakeLists.txt
@@ -2,6 +2,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
find_package(Qt6 COMPONENTS Quick REQUIRED)
+find_package(Qt6 COMPONENTS Widgets REQUIRED)
add_executable(clap-gui
main.cc
@@ -14,9 +15,7 @@ add_executable(clap-gui
plugin-proxy.hh
plugin-proxy.cc
)
-target_compile_options(clap-gui PRIVATE -fsanitize=address)
-target_link_options(clap-gui PRIVATE -fsanitize=address)
-target_link_libraries(clap-gui clap-io Qt6::Quick)
+target_link_libraries(clap-gui clap-io Qt6::Widgets Qt6::Quick)
set_target_properties(clap-gui PROPERTIES CXX_STANDARD 17)
install(TARGETS clap-gui DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
\ No newline at end of file
diff --git a/examples/gui/application.cc b/examples/gui/application.cc
@@ -1,15 +1,15 @@
#include <QCommandLineParser>
#include <QQmlContext>
#include <QQmlEngine>
-#include <QQuickView>
#include <QQuickItem>
+#include <QQuickView>
#include <QWindow>
#include "../io/messages.hh"
#include "application.hh"
-Application::Application(int argc, char **argv)
- : QGuiApplication(argc, argv), quickView_(new QQuickView()) {
+Application::Application(int& argc, char **argv)
+ : QApplication(argc, argv), quickView_(new QQuickView()) {
bool waitForDebbugger = false;
while (waitForDebbugger)
@@ -34,20 +34,28 @@ Application::Application(int argc, char **argv)
auto socket = parser.value(socketOpt).toULongLong();
- socketReadNotifier_ = new QSocketNotifier(socket, QSocketNotifier::Read, this);
- connect(
- socketReadNotifier_,
- &QSocketNotifier::activated,
- [this](QSocketDescriptor socket, QSocketNotifier::Type type) { remoteChannel_->onRead(); });
+ socketReadNotifier_.reset(new QSocketNotifier(socket, QSocketNotifier::Read, this));
+ connect(socketReadNotifier_.get(),
+ &QSocketNotifier::activated,
+ [this](QSocketDescriptor socket, QSocketNotifier::Type type) {
+ remoteChannel_->onRead();
+ if (!remoteChannel_->isOpen())
+ quit();
+ });
- socketWriteNotifier_ = new QSocketNotifier(socket, QSocketNotifier::Write, this);
- connect(
- socketWriteNotifier_,
- &QSocketNotifier::activated,
- [this](QSocketDescriptor socket, QSocketNotifier::Type type) { remoteChannel_->onWrite(); });
+ socketWriteNotifier_.reset(new QSocketNotifier(socket, QSocketNotifier::Write, this));
+ connect(socketWriteNotifier_.get(),
+ &QSocketNotifier::activated,
+ [this](QSocketDescriptor socket, QSocketNotifier::Type type) {
+ remoteChannel_->onWrite();
+ if (!remoteChannel_->isOpen())
+ {
+ quit();
+ }
+ });
- socketErrorNotifier_ = new QSocketNotifier(socket, QSocketNotifier::Exception, this);
- connect(socketErrorNotifier_,
+ socketErrorNotifier_.reset(new QSocketNotifier(socket, QSocketNotifier::Exception, this));
+ connect(socketErrorNotifier_.get(),
&QSocketNotifier::activated,
[this](QSocketDescriptor socket, QSocketNotifier::Type type) {
remoteChannel_->onError();
@@ -70,8 +78,19 @@ void Application::modifyFd(clap_fd_flags flags) {
socketErrorNotifier_->setEnabled(flags & CLAP_FD_ERROR);
}
+void Application::removeFd() {
+ socketReadNotifier_.reset();
+ socketWriteNotifier_.reset();
+ socketErrorNotifier_.reset();
+}
+
void Application::onMessage(const clap::RemoteChannel::Message &msg) {
switch (msg.type) {
+ case clap::messages::kDestroyRequest:
+ clap::messages::DestroyResponse rp;
+ remoteChannel_->sendResponseAsync(rp, msg.cookie);
+ break;
+
case clap::messages::kDefineParameterRequest: {
clap::messages::DefineParameterRequest rq;
msg.get(rq);
diff --git a/examples/gui/application.hh b/examples/gui/application.hh
@@ -1,6 +1,6 @@
#pragma once
-#include <QGuiApplication>
+#include <QApplication>
#include <QSocketNotifier>
#include <QWindow>
@@ -9,24 +9,25 @@
class QQuickView;
-class Application : public QGuiApplication, public clap::RemoteChannel::EventControl {
+class Application : public QApplication, public clap::RemoteChannel::EventControl {
Q_OBJECT;
public:
- Application(int argc, char **argv);
+ Application(int& argc, char **argv);
clap::RemoteChannel& remoteChannel() const { return *remoteChannel_; }
void modifyFd(clap_fd_flags flags) override;
+ void removeFd() override;
- static Application& instance() { return *dynamic_cast<Application *>(QCoreApplication::instance()); }
+ static Application& instance() { return *dynamic_cast<Application *>(QApplication::instance()); }
private:
void onMessage(const clap::RemoteChannel::Message& msg);
QQuickView *quickView_ = nullptr;
- QSocketNotifier *socketReadNotifier_ = nullptr;
- QSocketNotifier *socketWriteNotifier_ = nullptr;
- QSocketNotifier *socketErrorNotifier_ = nullptr;
+ std::unique_ptr<QSocketNotifier> socketReadNotifier_;
+ std::unique_ptr<QSocketNotifier> socketWriteNotifier_;
+ std::unique_ptr<QSocketNotifier> socketErrorNotifier_;
std::unique_ptr<QWindow> hostWindow_ = nullptr;
diff --git a/examples/host/application.cc b/examples/host/application.cc
@@ -55,12 +55,12 @@ Application::Application(int argc, char **argv)
Application::~Application() {
saveSettings();
- delete mainWindow_;
- mainWindow_ = nullptr;
-
delete engine_;
engine_ = nullptr;
+ delete mainWindow_;
+ mainWindow_ = nullptr;
+
delete settings_;
settings_ = nullptr;
}
diff --git a/examples/io/remote-channel.cc b/examples/io/remote-channel.cc
@@ -95,6 +95,9 @@ namespace clap {
if (socket_ == -1)
return;
+ modifyFd(0);
+ evControl_.removeFd();
+
::close(socket_);
socket_ = -1;
}
@@ -166,6 +169,9 @@ namespace clap {
}
void RemoteChannel::runOnce() {
+ if (!isOpen())
+ return;
+
#ifdef __unix__
pollfd pfd;
pfd.fd = socket_;
@@ -173,14 +179,19 @@ namespace clap {
pfd.revents = 0;
int ret = ::poll(&pfd, 1, -1);
- if (ret < 1)
- // TODO error handling
+ if (ret < 1) {
+ if (errno == EAGAIN || errno == EINTR)
+ return;
+ close();
return;
+ }
if (pfd.revents & POLLOUT)
onWrite();
- if (pfd.revents & POLLIN)
+ if (isOpen() && pfd.revents & POLLIN)
onRead();
+ if (isOpen() && pfd.revents & POLLERR)
+ close();
#endif
}
} // namespace clap
diff --git a/examples/io/remote-channel.hh b/examples/io/remote-channel.hh
@@ -16,6 +16,7 @@ namespace clap {
class EventControl {
public:
virtual void modifyFd(clap_fd_flags flags) = 0;
+ virtual void removeFd() = 0;
};
struct Message final {
@@ -53,7 +54,7 @@ namespace clap {
void set(const T &msg) noexcept {
type = T::type;
data = &msg;
- size = sizeof (T);
+ size = sizeof(T);
}
};
@@ -103,6 +104,7 @@ namespace clap {
void runOnce();
clap_fd fd() const { return socket_; }
+ bool isOpen() const noexcept { return socket_ != -1; }
private:
using ReadBuffer = Buffer<uint8_t, 128 * 1024>;
@@ -122,7 +124,7 @@ namespace clap {
uint32_t nextCookie_ = 0;
MessageHandler handler_;
- std::unordered_map<uint32_t /* cookie */, const MessageHandler&> syncHandlers_;
+ std::unordered_map<uint32_t /* cookie */, const MessageHandler &> syncHandlers_;
EventControl &evControl_;
clap_fd socket_;
clap_fd_flags ioFlags_ = 0;
diff --git a/examples/plugins/dc-offset/dc-offset.cc b/examples/plugins/dc-offset/dc-offset.cc
@@ -27,15 +27,17 @@ namespace clap {
kParamIdOffset = 0,
};
- DcOffset::DcOffset(const std::string& pluginPath, const clap_host *host) : CorePlugin(PathProvider::create(pluginPath, "dc-offset"), descriptor(), host) {
+ DcOffset::DcOffset(const std::string &pluginPath, const clap_host *host)
+ : CorePlugin(PathProvider::create(pluginPath, "dc-offset"), descriptor(), host) {
parameters_.addParameter(clap_param_info{
- .id = kParamIdOffset,
- .flags = 0,
- .name = "offset",
- .module = "/",
- .min_value = -1,
- .max_value = 1,
- .default_value = 0,
+ kParamIdOffset,
+ 0,
+ nullptr,
+ "offset",
+ "/",
+ -1,
+ 1,
+ 0,
});
}
diff --git a/examples/plugins/dc-offset/skin/main.qml b/examples/plugins/dc-offset/skin/main.qml
@@ -6,8 +6,8 @@ Rectangle {
height: 200
color: "#224477"
- Dial {
+ /*Dial {
property QtObject param: plugin.getParam(0)
inputMode: Dial.Vertical
- }
+ }*/
}
\ No newline at end of file
diff --git a/examples/plugins/gain/gain.cc b/examples/plugins/gain/gain.cc
@@ -26,15 +26,17 @@ namespace clap {
kParamIdGain = 0,
};
- Gain::Gain(const std::string& pluginPath, const clap_host *host) : CorePlugin(PathProvider::create(pluginPath, "gain"), descriptor(), host) {
+ Gain::Gain(const std::string &pluginPath, const clap_host *host)
+ : CorePlugin(PathProvider::create(pluginPath, "gain"), descriptor(), host) {
parameters_.addParameter(clap_param_info{
- .id = kParamIdGain,
- .flags = 0,
- .name = "gain",
- .module = "/",
- .min_value = -1,
- .max_value = 1,
- .default_value = 0,
+ kParamIdGain,
+ 0,
+ nullptr,
+ "gain",
+ "/",
+ -1,
+ 1,
+ 0,
});
}
diff --git a/examples/plugins/remote-gui.cc b/examples/plugins/remote-gui.cc
@@ -6,8 +6,8 @@
#include <cassert>
#include "../io/messages.hh"
-#include "path-provider.hh"
#include "core-plugin.hh"
+#include "path-provider.hh"
#include "remote-gui.hh"
namespace clap {
@@ -22,7 +22,7 @@ namespace clap {
assert(child_ == -1);
assert(!channel_);
- auto& pathProvider = plugin_.pathProvider();
+ auto &pathProvider = plugin_.pathProvider();
#ifdef __unix__
/* create a socket pair */
@@ -49,7 +49,13 @@ namespace clap {
::snprintf(socketStr, sizeof(socketStr), "%d", sockets[1]);
auto path = pathProvider.getGuiExecutable();
auto skin = pathProvider.getSkinDirectory();
- ::execl(path.c_str(), path.c_str(), "--socket", socketStr, "--skin", skin.c_str(), (const char *)nullptr);
+ ::execl(path.c_str(),
+ path.c_str(),
+ "--socket",
+ socketStr,
+ "--skin",
+ skin.c_str(),
+ (const char *)nullptr);
printf("Failed to start child process: %m\n");
std::terminate();
} else {
@@ -71,6 +77,10 @@ namespace clap {
plugin_.hostEventLoop_->modify_fd(plugin_.host_, channel_->fd(), flags);
}
+ void RemoteGui::removeFd() {
+ plugin_.hostEventLoop_->unregister_fd(plugin_.host_, channel_->fd());
+ }
+
clap_fd RemoteGui::fd() const { return channel_ ? channel_->fd() : -1; }
void RemoteGui::onFd(clap_fd_flags flags) {
@@ -128,8 +138,25 @@ namespace clap {
messages::DestroyResponse response;
channel_->sendRequestSync(request, response);
- plugin_.hostEventLoop_->unregister_fd(plugin_.host_, channel_->fd());
+ channel_->close();
channel_.reset();
+
+ waitChild();
+ }
+
+ void RemoteGui::waitChild() {
+#ifdef __unix__
+ if (child_ == -1)
+ return;
+ int stat = 0;
+ int ret;
+
+ do {
+ ret = ::waitpid(child_, &stat, 0);
+ } while (ret == -1 && errno == EINTR);
+
+ child_ = -1;
+#endif
}
bool RemoteGui::attachCocoa(void *nsView) noexcept {
@@ -149,7 +176,7 @@ namespace clap {
messages::AttachResponse response;
request.window = window;
- std::snprintf(request.display, sizeof(request.display), "%s", display_name ? : "");
+ std::snprintf(request.display, sizeof(request.display), "%s", display_name ?: "");
return channel_->sendRequestSync(request, response);
}
diff --git a/examples/plugins/remote-gui.hh b/examples/plugins/remote-gui.hh
@@ -33,11 +33,14 @@ namespace clap {
// RemoteChannel::EventControl
void modifyFd(clap_fd_flags flags) override;
+ void removeFd() override;
+
clap_fd fd() const;
void onFd(clap_fd_flags flags);
private:
void onMessage(const RemoteChannel::Message& msg);
+ void waitChild();
std::unique_ptr<RemoteChannel> channel_;