Qt5: adapt to current staging branch (cap quota, ram quota, slave)

This commit is contained in:
Christian Prochaska 2017-05-11 20:39:49 +02:00 committed by Christian Helmuth
parent 10e2e223cd
commit 3f6e0738d1
13 changed files with 155 additions and 81 deletions

View File

@ -14,21 +14,24 @@
#ifndef QPLUGINWIDGET_H
#define QPLUGINWIDGET_H
/* Genode includes */
#include <libc/component.h>
#include <loader_session/connection.h>
/* Qt includes */
#include <QtGui>
#include <QtNetwork>
#include <loader_session/connection.h>
#include <qnitpickerviewwidget/qnitpickerviewwidget.h>
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

View File

@ -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)
{ }

View File

@ -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)
{ }

View File

@ -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);

View File

@ -25,7 +25,6 @@
/* Genode includes */
#include <base/service.h>
#include <cap_session/connection.h>
#include <input/root.h>
#include <os/config.h>
#include <rom_session/connection.h>

View File

@ -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);
}

View File

@ -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,

View File

@ -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");

View File

@ -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,

View File

@ -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,

View File

@ -19,6 +19,7 @@
#include <qpluginwidget/qpluginwidget.h>
Libc::Env *QPluginWidget::_env = 0;
QPluginWidget *QPluginWidget::_last = 0;
using namespace Genode;
@ -39,14 +40,14 @@ const char *config = " \
<default-route> \
<any-service> <parent/> <any-child/> </any-service> \
</default-route> \
<start name=\"tar_rom\"> \
<start name=\"tar_rom\" caps=\"100\"> \
<resource name=\"RAM\" quantum=\"1M\"/> \
<provides> <service name=\"ROM\"/> </provides> \
<config> \
<archive name=\"plugin.tar\"/> \
</config> \
</start> \
<start name=\"init\"> \
<start name=\"init\" caps=\"200\"> \
<resource name=\"RAM\" quantum=\"2G\"/> \
<configfile name=\"config.plugin\"/> \
<route> \
@ -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<QNitpickerPlatformWindow*>(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);

View File

@ -12,19 +12,28 @@
/* Qoost includes */
#include <qoost/compound_widget.h>
int main(int argc, char *argv[])
void Libc::Component::construct(Libc::Env &env)
{
static QApplication app(argc, argv);
Libc::with_libc([&] {
static Compound_widget<QWidget, QHBoxLayout> 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<QWidget, QHBoxLayout> 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();
});
}

View File

@ -15,5 +15,3 @@ test-plugin.tar: config.plugin
clean:
$(VERBOSE)rm test-plugin.tar
LIBS += posix