base: buffer session args in 'Connection'

This patch is a preparation of the forthcoming async parent interface.
Note that this patch increases the size of connection objects.
Furthermore it adds a diagnostic message whenever a connection fails.

Issue #2166
This commit is contained in:
Norman Feske 2016-11-08 16:37:27 +01:00 committed by Christian Helmuth
parent 7fba39831a
commit 82107bef9b
4 changed files with 51 additions and 30 deletions

View File

@ -33,40 +33,51 @@ class Genode::Connection : public Noncopyable
private: private:
/* /*
* Because the argument string is used with the parent interface, * Buffer for storing the session arguments passed to the
* the message-buffer size of the parent-interface provides a * 'session' method that is called before the 'Connection' is
* realistic upper bound for dimensioning the format- string * constructed.
* buffer.
*/ */
enum { FORMAT_STRING_SIZE = Parent::Session_args::MAX_SIZE }; enum { FORMAT_STRING_SIZE = Parent::Session_args::MAX_SIZE };
Capability<SESSION_TYPE> _cap; char _session_args[FORMAT_STRING_SIZE];
char _affinity_arg[sizeof(Affinity)];
Parent &_parent; Parent &_parent;
On_destruction _on_destruction; On_destruction _on_destruction;
Capability<SESSION_TYPE> _session(Parent &parent, void _session(Parent &parent,
Affinity const &affinity, Affinity const &affinity,
const char *format_args, va_list list) const char *format_args, va_list list)
{ {
char buf[FORMAT_STRING_SIZE]; String_console sc(_session_args, FORMAT_STRING_SIZE);
String_console sc(buf, FORMAT_STRING_SIZE);
sc.vprintf(format_args, list); sc.vprintf(format_args, list);
va_end(list); va_end(list);
/* call parent interface with the resulting argument buffer */ memcpy(_affinity_arg, &affinity, sizeof(Affinity));
return parent.session<SESSION_TYPE>(buf, affinity);
} }
Capability<SESSION_TYPE> _request_cap()
{
Affinity affinity;
memcpy(&affinity, _affinity_arg, sizeof(Affinity));
try {
return env()->parent()->session<SESSION_TYPE>(_session_args, affinity); }
catch (...) {
error(SESSION_TYPE::service_name(), "-session creation failed "
"(", Cstring(_session_args), ")");
throw;
}
}
Capability<SESSION_TYPE> _cap = _request_cap();
public: public:
/** /**
* Constructor * Constructor
* *
* \param cap session capability
* \param od session policy applied when destructing the connection * \param od session policy applied when destructing the connection
* *
* The 'op' argument defines whether the session should automatically * The 'op' argument defines whether the session should automatically
@ -76,8 +87,8 @@ class Genode::Connection : public Noncopyable
* session capability of the connection to another party but never * session capability of the connection to another party but never
* invokes any of the session's RPC functions. * invokes any of the session's RPC functions.
*/ */
Connection(Env &env, Capability<SESSION_TYPE> cap, On_destruction od = CLOSE) Connection(Env &env, Capability<SESSION_TYPE>, On_destruction od = CLOSE)
: _cap(cap), _parent(env.parent()), _on_destruction(od) { } : _parent(env.parent()), _on_destruction(od) { }
/** /**
* Constructor * Constructor
@ -86,8 +97,8 @@ class Genode::Connection : public Noncopyable
* \deprecated Use the constructor with 'Env &' as first * \deprecated Use the constructor with 'Env &' as first
* argument instead * argument instead
*/ */
Connection(Capability<SESSION_TYPE> cap, On_destruction od = CLOSE) Connection(Capability<SESSION_TYPE>, On_destruction od = CLOSE)
: _cap(cap), _parent(*env()->parent()), _on_destruction(od) { } : _parent(*env()->parent()), _on_destruction(od) { }
/** /**
* Destructor * Destructor
@ -116,7 +127,8 @@ class Genode::Connection : public Noncopyable
va_list list; va_list list;
va_start(list, format_args); va_start(list, format_args);
return _session(parent, Affinity(), format_args, list); _session(parent, Affinity(), format_args, list);
return Capability<SESSION_TYPE>();
} }
/** /**
@ -129,7 +141,8 @@ class Genode::Connection : public Noncopyable
va_list list; va_list list;
va_start(list, format_args); va_start(list, format_args);
return _session(parent, affinity, format_args, list); _session(parent, affinity, format_args, list);
return Capability<SESSION_TYPE>();
} }
/** /**
@ -143,7 +156,8 @@ class Genode::Connection : public Noncopyable
va_list list; va_list list;
va_start(list, format_args); va_start(list, format_args);
return _session(*env()->parent(), Affinity(), format_args, list); _session(*env()->parent(), Affinity(), format_args, list);
return Capability<SESSION_TYPE>();
} }
/** /**
@ -158,7 +172,8 @@ class Genode::Connection : public Noncopyable
va_list list; va_list list;
va_start(list, format_args); va_start(list, format_args);
return _session(affinity, format_args, list); _session(affinity, format_args, list);
return Capability<SESSION_TYPE>();
} }
}; };

View File

@ -32,11 +32,7 @@ class Genode::Rom_connection : public Connection<Rom_session>,
Rom_session_capability _session(Parent &parent, char const *label) Rom_session_capability _session(Parent &parent, char const *label)
{ {
try { return session("ram_quota=4K, label=\"%s\"", label); } return session("ram_quota=4K, label=\"%s\"", label);
catch (...) {
error("Could not open ROM session for \"", label, "\"");
throw Rom_connection_failed();
}
} }
public: public:
@ -49,10 +45,14 @@ class Genode::Rom_connection : public Connection<Rom_session>,
* \throw Rom_connection_failed * \throw Rom_connection_failed
*/ */
Rom_connection(Env &env, const char *label) Rom_connection(Env &env, const char *label)
: try :
Connection<Rom_session>(env, _session(env.parent(), label)), Connection<Rom_session>(env, _session(env.parent(), label)),
Rom_session_client(cap()) Rom_session_client(cap())
{ } { }
catch (...) {
error("Could not open ROM session for \"", label, "\"");
throw Rom_connection_failed();
}
/** /**
* Constructor * Constructor
@ -62,10 +62,14 @@ class Genode::Rom_connection : public Connection<Rom_session>,
* argument instead * argument instead
*/ */
Rom_connection(const char *label) Rom_connection(const char *label)
: try :
Connection<Rom_session>(_session(*env()->parent(), label)), Connection<Rom_session>(_session(*env()->parent(), label)),
Rom_session_client(cap()) Rom_session_client(cap())
{ } { }
catch (...) {
error("Could not open ROM session for \"", label, "\"");
throw Rom_connection_failed();
}
}; };
#endif /* _INCLUDE__ROM_SESSION__CONNECTION_H_ */ #endif /* _INCLUDE__ROM_SESSION__CONNECTION_H_ */

View File

@ -80,6 +80,7 @@ compare_output_to {
[init -> test-ldso] Catch exceptions in program [init -> test-ldso] Catch exceptions in program
[init -> test-ldso] --------------------------- [init -> test-ldso] ---------------------------
[init -> test-ldso] exception in remote procedure call: [init -> test-ldso] exception in remote procedure call:
[init -> test-ldso] Error: ROM-session creation failed (ram_quota=4K, label="unknown_file")
[init -> test-ldso] Error: Could not open ROM session for "unknown_file" [init -> test-ldso] Error: Could not open ROM session for "unknown_file"
[init -> test-ldso] caught [init -> test-ldso] caught
[init -> test-ldso] exception in program: caught [init -> test-ldso] exception in program: caught

View File

@ -68,6 +68,7 @@ compare_output_to {
[init -> test-report_rom] Reporter: start reporting (while the ROM client still listens) [init -> test-report_rom] Reporter: start reporting (while the ROM client still listens)
[init -> test-report_rom] ROM client: wait for update notification [init -> test-report_rom] ROM client: wait for update notification
[init -> test-report_rom] ROM client: try to open the same report again [init -> test-report_rom] ROM client: try to open the same report again
[init -> test-report_rom] Error: Report-session creation failed (label="brightness", ram_quota=12288, buffer_size=4096)
[init -> test-report_rom] ROM client: catched Parent::Service_denied - OK [init -> test-report_rom] ROM client: catched Parent::Service_denied - OK
[init -> test-report_rom] --- test-report_rom finished --- [init -> test-report_rom] --- test-report_rom finished ---
} }