From 3f6e0738d1a760e561ef6e4c54b3a8118318621b Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Thu, 11 May 2017 20:39:49 +0200 Subject: [PATCH] Qt5: adapt to current staging branch (cap quota, ram quota, slave) --- .../include/qt5/qpluginwidget/qpluginwidget.h | 64 +++++++++++-------- .../src/app/qt5/qt_avplay/avplay_slave.h | 26 +++++--- .../qt5/qt_avplay/filter_framebuffer_slave.h | 30 ++++++--- .../src/app/qt5/qt_avplay/main_window.cpp | 13 +++- .../src/app/qt5/qt_avplay/main_window.h | 1 - .../src/app/qt5/qt_launchpad/launch_entry.cpp | 9 +-- .../src/app/qt5/qt_launchpad/launch_entry.h | 2 + .../src/app/qt5/qt_launchpad/main.cpp | 2 +- .../src/app/qt5/qt_launchpad/qt_launchpad.cpp | 5 +- .../src/app/qt5/qt_launchpad/qt_launchpad.h | 2 +- .../lib/qt5/qpluginwidget/qpluginwidget.cpp | 53 +++++++++++---- .../src/test/qt5/qpluginwidget/main.cpp | 27 +++++--- .../src/test/qt5/qpluginwidget/target.mk | 2 - 13 files changed, 155 insertions(+), 81 deletions(-) diff --git a/repos/libports/include/qt5/qpluginwidget/qpluginwidget.h b/repos/libports/include/qt5/qpluginwidget/qpluginwidget.h index 96a94d6fad..84115d2e77 100644 --- a/repos/libports/include/qt5/qpluginwidget/qpluginwidget.h +++ b/repos/libports/include/qt5/qpluginwidget/qpluginwidget.h @@ -14,21 +14,24 @@ #ifndef QPLUGINWIDGET_H #define QPLUGINWIDGET_H +/* Genode includes */ +#include +#include + +/* Qt includes */ #include #include -#include - #include - enum Plugin_loading_state { LOADING, LOADED, NETWORK_ERROR, INFLATE_ERROR, - QUOTA_EXCEEDED_ERROR, + CAP_QUOTA_EXCEEDED_ERROR, + RAM_QUOTA_EXCEEDED_ERROR, ROM_CONNECTION_FAILED_EXCEPTION, TIMEOUT_EXCEPTION }; @@ -41,18 +44,20 @@ class PluginStarter : public QThread Q_OBJECT private: - QUrl _plugin_url; - QByteArray _args; - int _max_width; - int _max_height; - Nitpicker::View_capability _parent_view; - Loader::Connection *_pc; - enum Plugin_loading_state _plugin_loading_state; - QString _plugin_loading_error_string; + Libc::Env *_env; + QUrl _plugin_url; + QByteArray _args; + int _max_width; + int _max_height; + Nitpicker::View_capability _parent_view; - QNetworkAccessManager *_qnam; - QNetworkReply *_reply; + Loader::Connection *_pc; + enum Plugin_loading_state _plugin_loading_state; + QString _plugin_loading_error_string; + + QNetworkAccessManager *_qnam; + QNetworkReply *_reply; void _start_plugin(QString &file_name, QByteArray const &file_buf); @@ -60,7 +65,8 @@ class PluginStarter : public QThread void networkReplyFinished(); public: - PluginStarter(QUrl plugin_url, QString &args, + PluginStarter(Libc::Env *env, + QUrl plugin_url, QString &args, int max_width, int max_height, Nitpicker::View_capability parent_view); @@ -89,22 +95,25 @@ class QPluginWidget : public QEmbeddedViewWidget private: - enum Plugin_loading_state _plugin_loading_state; - QString _plugin_loading_error_string; + static Libc::Env *_env; + static QPluginWidget *_last; - PluginStarter *_plugin_starter; - bool _plugin_starter_started; + enum Plugin_loading_state _plugin_loading_state; + QString _plugin_loading_error_string; - QUrl _plugin_url; - QString _plugin_args; + PluginStarter *_plugin_starter; + bool _plugin_starter_started; - int _max_width; - int _max_height; + QUrl _plugin_url; + QString _plugin_args; - static QPluginWidget *_last; + int _max_width; + int _max_height; public: - enum { RAM_QUOTA = 5*1024*1024 }; + + enum { PRESERVED_CAPS = 150 }; + enum { PRESERVED_RAM_QUOTA = 5*1024*1024 }; void cleanup(); @@ -117,8 +126,11 @@ class QPluginWidget : public QEmbeddedViewWidget void pluginStartFinished(); public: - QPluginWidget(QWidget *parent, QUrl plugin_url, QString &args, int max_width = -1, int max_height = -1); + QPluginWidget(QWidget *parent, QUrl plugin_url, QString &args, + int max_width = -1, int max_height = -1); ~QPluginWidget(); + + static void set_env(Libc::Env *env) { _env = env; } }; #endif // QPLUGINWIDGET_H diff --git a/repos/libports/src/app/qt5/qt_avplay/avplay_slave.h b/repos/libports/src/app/qt5/qt_avplay/avplay_slave.h index 3951d6e85b..b3bf2b5f3d 100644 --- a/repos/libports/src/app/qt5/qt_avplay/avplay_slave.h +++ b/repos/libports/src/app/qt5/qt_avplay/avplay_slave.h @@ -103,20 +103,25 @@ class Avplay_slave : public QObject return _config_byte_array.constData(); } - static Genode::size_t _quota() { return 32*1024*1024; } - static Name _name() { return "avplay"; } + static Genode::Cap_quota _caps() { return { 150 }; } + static Genode::Ram_quota _ram_quota() { return { 32*1024*1024 }; } + static Name _name() { return "avplay"; } public: Policy(Genode::Rpc_entrypoint &entrypoint, Genode::Region_map &rm, - Genode::Ram_session_capability ram, + Genode::Pd_session &ref_pd, + Genode::Pd_session_capability ref_pd_cap, + Genode::Ram_session &ref_ram, + Genode::Ram_session_capability ref_ram_cap, Input_service &input_service, Framebuffer_service_factory &framebuffer_service_factory, char const *mediafile) : Genode::Slave::Policy(_name(), _name(), *this, entrypoint, - rm, ram, _quota()), + rm, ref_pd, ref_pd_cap, _caps(), + ref_ram, ref_ram_cap, _ram_quota()), _input_service(input_service), _framebuffer_service_factory(framebuffer_service_factory), _mediafile(mediafile), @@ -155,15 +160,18 @@ class Avplay_slave : public QObject /** * Constructor */ - Avplay_slave(Genode::Pd_session &pd, - Genode::Region_map &rm, - Genode::Ram_session_capability ram, + Avplay_slave(Genode::Region_map &rm, + Genode::Pd_session &ref_pd, + Genode::Pd_session_capability ref_pd_cap, + Genode::Ram_session &ref_ram, + Genode::Ram_session_capability ref_ram_cap, Input_service &input_service, Framebuffer_service_factory &framebuffer_service_factory, char const *mediafile) : - _ep(&pd, _ep_stack_size, "avplay_ep"), - _policy(_ep, rm, ram, input_service, framebuffer_service_factory, mediafile), + _ep(&ref_pd, _ep_stack_size, "avplay_ep"), + _policy(_ep, rm, ref_pd, ref_pd_cap, ref_ram, ref_ram_cap, + input_service, framebuffer_service_factory, mediafile), _child(rm, _ep, _policy) { } diff --git a/repos/libports/src/app/qt5/qt_avplay/filter_framebuffer_slave.h b/repos/libports/src/app/qt5/qt_avplay/filter_framebuffer_slave.h index 9d70040219..ee4313919b 100644 --- a/repos/libports/src/app/qt5/qt_avplay/filter_framebuffer_slave.h +++ b/repos/libports/src/app/qt5/qt_avplay/filter_framebuffer_slave.h @@ -46,12 +46,20 @@ class Filter_framebuffer_slave Policy(Genode::Rpc_entrypoint &entrypoint, Genode::Region_map &rm, - Genode::Ram_session_capability ram, + Genode::Pd_session &ref_pd, + Genode::Pd_session_capability ref_pd_cap, + Genode::Ram_session &ref_ram, + Genode::Ram_session_capability ref_ram_cap, Name const &name, - size_t quota, + size_t caps, + size_t ram_quota, Framebuffer_service_factory &framebuffer_service_factory) : - Genode::Slave::Policy(name, name, *this, entrypoint, rm, ram, quota), + Genode::Slave::Policy(name, name, *this, entrypoint, rm, + ref_pd, ref_pd_cap, + Genode::Cap_quota{caps}, + ref_ram, ref_ram_cap, + Genode::Ram_quota{ram_quota}), _framebuffer_service_factory(framebuffer_service_factory) { } @@ -75,15 +83,19 @@ class Filter_framebuffer_slave /** * Constructor */ - Filter_framebuffer_slave(Genode::Pd_session &pd, - Genode::Region_map &rm, - Genode::Ram_session_capability ram, + Filter_framebuffer_slave(Genode::Region_map &rm, + Genode::Pd_session &ref_pd, + Genode::Pd_session_capability ref_pd_cap, + Genode::Ram_session &ref_ram, + Genode::Ram_session_capability ref_ram_cap, Genode::Slave::Policy::Name const &name, - size_t quota, + size_t caps, + size_t ram_quota, Framebuffer_service_factory &framebuffer_service_factory) : - _ep(&pd, _ep_stack_size, "filter_framebuffer_ep"), - _policy(_ep, rm, ram, name, quota, framebuffer_service_factory), + _ep(&ref_pd, _ep_stack_size, "filter_framebuffer_ep"), + _policy(_ep, rm, ref_pd, ref_pd_cap, ref_ram, ref_ram_cap, name, + caps, ram_quota, framebuffer_service_factory), _child(rm, _ep, _policy) { } diff --git a/repos/libports/src/app/qt5/qt_avplay/main_window.cpp b/repos/libports/src/app/qt5/qt_avplay/main_window.cpp index fd8b6858b3..4f3c81d72b 100644 --- a/repos/libports/src/app/qt5/qt_avplay/main_window.cpp +++ b/repos/libports/src/app/qt5/qt_avplay/main_window.cpp @@ -23,6 +23,7 @@ struct Framebuffer_filter { enum { MAX_FILTER_NAME_SIZE = 32 }; char name[MAX_FILTER_NAME_SIZE]; + size_t caps; Genode::Number_of_bytes ram_quota; Filter_framebuffer_slave *slave; }; @@ -59,6 +60,7 @@ Main_window::Main_window(Genode::Env &env) for (; ; node = node.next("framebuffer_filter")) { Framebuffer_filter *framebuffer_filter = new Framebuffer_filter; node.attribute("name").value(framebuffer_filter->name, sizeof(framebuffer_filter->name)); + node.attribute("caps").value(&framebuffer_filter->caps); node.attribute("ram_quota").value(&framebuffer_filter->ram_quota); qDebug() << "filter:" << framebuffer_filter->name << "," << framebuffer_filter->ram_quota; framebuffer_filters.prepend(framebuffer_filter); @@ -71,9 +73,13 @@ Main_window::Main_window(Genode::Env &env) /* start the filtering framebuffer services */ Q_FOREACH(Framebuffer_filter *framebuffer_filter, framebuffer_filters) { - framebuffer_filter->slave = new Filter_framebuffer_slave(_env.pd(), _env.rm(), + framebuffer_filter->slave = new Filter_framebuffer_slave(_env.rm(), + _env.pd(), + _env.pd_session_cap(), + _env.ram(), _env.ram_session_cap(), framebuffer_filter->name, + framebuffer_filter->caps, framebuffer_filter->ram_quota, *framebuffer_service_factory); framebuffer_service_factory = @@ -82,8 +88,9 @@ Main_window::Main_window(Genode::Env &env) /* start avplay */ - Avplay_slave *avplay_slave = new Avplay_slave(_env.pd(), _env.rm(), - _env.ram_session_cap(), + Avplay_slave *avplay_slave = new Avplay_slave(_env.rm(), + _env.pd(), _env.pd_session_cap(), + _env.ram(), _env.ram_session_cap(), _input_service, *framebuffer_service_factory, _mediafile_name.buf); diff --git a/repos/libports/src/app/qt5/qt_avplay/main_window.h b/repos/libports/src/app/qt5/qt_avplay/main_window.h index 00e1fe7550..6ed0e7eac5 100644 --- a/repos/libports/src/app/qt5/qt_avplay/main_window.h +++ b/repos/libports/src/app/qt5/qt_avplay/main_window.h @@ -25,7 +25,6 @@ /* Genode includes */ #include -#include #include #include #include diff --git a/repos/libports/src/app/qt5/qt_launchpad/launch_entry.cpp b/repos/libports/src/app/qt5/qt_launchpad/launch_entry.cpp index fc4ac24670..4ef1b4db7d 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/launch_entry.cpp +++ b/repos/libports/src/app/qt5/qt_launchpad/launch_entry.cpp @@ -7,6 +7,7 @@ #include "launch_entry.h" Launch_entry::Launch_entry(Launchpad_child::Name const &prg_name, + Launchpad::Cap_quota caps, unsigned long default_quota, unsigned long max_quota, Launchpad *launchpad, @@ -15,7 +16,8 @@ Launch_entry::Launch_entry(Launchpad_child::Name const &prg_name, : QWidget(parent), _prg_name(prg_name), _launchpad(launchpad), - _config_ds(config_ds) + _config_ds(config_ds), + _caps(caps) { ui.setupUi(this); @@ -29,7 +31,6 @@ Launch_entry::Launch_entry(Launchpad_child::Name const &prg_name, void Launch_entry::on_launchButton_clicked() { - _launchpad->start_child(_prg_name, - 1024 * ui.quotaDial->value(), - _config_ds); + Launchpad::Ram_quota ram_quota = { 1024UL * ui.quotaDial->value() }; + _launchpad->start_child(_prg_name, _caps, ram_quota, _config_ds); } diff --git a/repos/libports/src/app/qt5/qt_launchpad/launch_entry.h b/repos/libports/src/app/qt5/qt_launchpad/launch_entry.h index 1e3fb80188..0be8e28eae 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/launch_entry.h +++ b/repos/libports/src/app/qt5/qt_launchpad/launch_entry.h @@ -31,6 +31,7 @@ class Launch_entry : public QWidget Launchpad_child::Name const &_prg_name; Launchpad *_launchpad; Genode::Dataspace_capability _config_ds; + Launchpad::Cap_quota _caps; private slots: @@ -39,6 +40,7 @@ class Launch_entry : public QWidget public: Launch_entry(Launchpad_child::Name const &prg_name, + Launchpad::Cap_quota caps, unsigned long default_quota, unsigned long max_quota, Launchpad *launchpad, diff --git a/repos/libports/src/app/qt5/qt_launchpad/main.cpp b/repos/libports/src/app/qt5/qt_launchpad/main.cpp index e1807956cc..febf2d7b83 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/main.cpp +++ b/repos/libports/src/app/qt5/qt_launchpad/main.cpp @@ -66,7 +66,7 @@ void Libc::Component::construct(Libc::Env &env) QApplication a(genode_argc, genode_argv); - Qt_launchpad launchpad(local_env, env.ram().avail()); + Qt_launchpad launchpad(local_env, env.ram().avail_ram().value); Genode::Attached_rom_dataspace config(env, "config"); diff --git a/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.cpp b/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.cpp index 0a00318740..fe95f550c6 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.cpp +++ b/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.cpp @@ -59,7 +59,7 @@ void Qt_launchpad::_avail_quota_update() { static Genode::size_t _avail = 0; - Genode::size_t new_avail = Genode::env()->ram_session()->avail(); + Genode::size_t new_avail = Genode::env()->ram_session()->avail_ram().value; if (new_avail != _avail) quota(new_avail); @@ -76,10 +76,11 @@ void Qt_launchpad::quota(unsigned long quota) void Qt_launchpad::add_launcher(Launchpad_child::Name const &binary_name, - unsigned long default_quota, + Cap_quota caps, unsigned long default_quota, Genode::Dataspace_capability config_ds) { Launch_entry *launch_entry = new Launch_entry(binary_name, + caps, default_quota / 1024, initial_quota() / 1024, this, diff --git a/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.h b/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.h index 1631209abb..3834fd7e14 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.h +++ b/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.h @@ -35,7 +35,7 @@ class Qt_launchpad : public QMainWindow, public Launchpad, private Ui::Qt_launch virtual void quota(unsigned long quota) override; virtual void add_launcher(Launchpad_child::Name const &binary_name, - unsigned long default_quota, + Cap_quota caps, unsigned long default_quota, Genode::Dataspace_capability config_ds) override; virtual void add_child(Launchpad_child::Name const &name, diff --git a/repos/libports/src/lib/qt5/qpluginwidget/qpluginwidget.cpp b/repos/libports/src/lib/qt5/qpluginwidget/qpluginwidget.cpp index a3f0eaf7ba..78016ff6b3 100644 --- a/repos/libports/src/lib/qt5/qpluginwidget/qpluginwidget.cpp +++ b/repos/libports/src/lib/qt5/qpluginwidget/qpluginwidget.cpp @@ -19,6 +19,7 @@ #include +Libc::Env *QPluginWidget::_env = 0; QPluginWidget *QPluginWidget::_last = 0; using namespace Genode; @@ -39,14 +40,14 @@ const char *config = " \ \ \ \ - \ + \ \ \ \ \ \ \ - \ + \ \ \ \ @@ -83,10 +84,12 @@ class Signal_wait_thread : public QThread }; -PluginStarter::PluginStarter(QUrl plugin_url, QString &args, +PluginStarter::PluginStarter(Libc::Env *env, + QUrl plugin_url, QString &args, int max_width, int max_height, Nitpicker::View_capability parent_view) : + _env(env), _plugin_url(plugin_url), _args(args.toLatin1()), _max_width(max_width), @@ -101,22 +104,36 @@ PluginStarter::PluginStarter(QUrl plugin_url, QString &args, void PluginStarter::_start_plugin(QString &file_name, QByteArray const &file_buf) { + Genode::size_t caps = Arg_string::find_arg(_args.constData(), "caps").ulong_value(0); + + if ((long)_env->pd().avail_caps().value - (long)caps < QPluginWidget::PRESERVED_CAPS) { + Genode::error("Cannot donate ", caps, " capabilities to the plugin (quota exceeded)."); + _plugin_loading_state = CAP_QUOTA_EXCEEDED_ERROR; + return; + } + if (file_name.endsWith(".gz")) { file_name.remove(".gz"); - uint32_t file_size = *(uint32_t*)(file_buf.constData() + file_buf.size() - sizeof(uint32_t)); + uint32_t file_size = *(uint32_t*)(file_buf.constData() + + file_buf.size() - sizeof(uint32_t)); Genode::log(__func__, ": file_size_uncompressed=", file_size); - Genode::size_t ram_quota = Arg_string::find_arg(_args.constData(), "ram_quota").ulong_value(0) + file_size; + Genode::size_t ram_quota = Arg_string::find_arg(_args.constData(), + "ram_quota").ulong_value(0) + + file_size; - if ((long)env()->ram_session()->avail() - (long)ram_quota < QPluginWidget::RAM_QUOTA) { - Genode::error("quota exceeded"); - _plugin_loading_state = QUOTA_EXCEEDED_ERROR; + if (((long)_env->ram().avail_ram().value - (long)ram_quota) < + QPluginWidget::PRESERVED_RAM_QUOTA) { + Genode::error("Cannot donate ", ram_quota, " bytes of RAM to the plugin (quota exceeded)."); + _plugin_loading_state = RAM_QUOTA_EXCEEDED_ERROR; return; } - _pc = new Loader::Connection(ram_quota); + _pc = new Loader::Connection(*_env, + Genode::Ram_quota{ram_quota}, + Genode::Cap_quota{caps}); Dataspace_capability ds = _pc->alloc_rom_module(file_name.toUtf8().constData(), file_size); if (ds.valid()) { @@ -160,12 +177,15 @@ void PluginStarter::_start_plugin(QString &file_name, QByteArray const &file_buf } else { Genode::size_t ram_quota = Arg_string::find_arg(_args.constData(), "ram_quota").ulong_value(0); - if ((long)env()->ram_session()->avail() - (long)ram_quota < QPluginWidget::RAM_QUOTA) { - _plugin_loading_state = QUOTA_EXCEEDED_ERROR; + if (((long)env()->ram_session()->avail_ram().value - (long)ram_quota) < + QPluginWidget::PRESERVED_RAM_QUOTA) { + _plugin_loading_state = RAM_QUOTA_EXCEEDED_ERROR; return; } - _pc = new Loader::Connection(ram_quota); + _pc = new Loader::Connection(*_env, + Genode::Ram_quota{ram_quota}, + Genode::Cap_quota{caps}); Dataspace_capability plugin_ds = _pc->alloc_rom_module("plugin.tar", file_buf.size()); if (plugin_ds.valid()) { @@ -386,7 +406,11 @@ void QPluginWidget::paintEvent(QPaintEvent *event) painter.drawText(rect(), Qt::AlignCenter, tr("Could not load plugin: error decompressing gzipped file.")); break; - case QUOTA_EXCEEDED_ERROR: + case CAP_QUOTA_EXCEEDED_ERROR: + painter.drawText(rect(), Qt::AlignCenter, + tr("Could not load plugin: not enough capabilities.")); + break; + case RAM_QUOTA_EXCEEDED_ERROR: painter.drawText(rect(), Qt::AlignCenter, tr("Could not load plugin: not enough memory.")); break; @@ -412,7 +436,8 @@ void QPluginWidget::showEvent(QShowEvent *event) QNitpickerPlatformWindow *platform_window = dynamic_cast(window()->windowHandle()->handle()); - _plugin_starter = new PluginStarter(_plugin_url, _plugin_args, + _plugin_starter = new PluginStarter(_env, + _plugin_url, _plugin_args, _max_width, _max_height, platform_window->view_cap()); _plugin_starter->moveToThread(_plugin_starter); diff --git a/repos/libports/src/test/qt5/qpluginwidget/main.cpp b/repos/libports/src/test/qt5/qpluginwidget/main.cpp index 45e7304500..6a13de0f1b 100644 --- a/repos/libports/src/test/qt5/qpluginwidget/main.cpp +++ b/repos/libports/src/test/qt5/qpluginwidget/main.cpp @@ -12,19 +12,28 @@ /* Qoost includes */ #include -int main(int argc, char *argv[]) +void Libc::Component::construct(Libc::Env &env) { - static QApplication app(argc, argv); + Libc::with_libc([&] { - static Compound_widget w; + QPluginWidget::set_env(&env); - static QString plugin_args("ram_quota=4M"); - static QPluginWidget plugin_widget(&w, QUrl("rom:///test-plugin.tar"), plugin_args, 100, 100); + int argc = 1; + char *argv[] = { "test-qpluginwidget", 0 }; - w.layout()->addWidget(&plugin_widget); - w.resize(150, 150); + QApplication app(argc, argv); - w.show(); + Compound_widget w; - return app.exec(); + QString plugin_args("ram_quota=4M, caps=500"); + QPluginWidget plugin_widget(&w, QUrl("rom:///test-plugin.tar"), + plugin_args, 100, 100); + + w.layout()->addWidget(&plugin_widget); + w.resize(150, 150); + + w.show(); + + return app.exec(); + }); } diff --git a/repos/libports/src/test/qt5/qpluginwidget/target.mk b/repos/libports/src/test/qt5/qpluginwidget/target.mk index f452379dd0..f4f8bd6561 100644 --- a/repos/libports/src/test/qt5/qpluginwidget/target.mk +++ b/repos/libports/src/test/qt5/qpluginwidget/target.mk @@ -15,5 +15,3 @@ test-plugin.tar: config.plugin clean: $(VERBOSE)rm test-plugin.tar - -LIBS += posix