Session mapping 1:1 vs. 1:n
Stefan Kalkowski
stefan.kalkowski at ...1...
Thu Aug 27 11:12:22 CEST 2009
Hi Sven,
On Wednesday, 26. August 2009 18:04:34 Sven Fülster wrote:
> Hi all,
>
> during my work, I've written a vesa driver which is capable of serving
> multiple clients (using 'virtual' framebuffers, derived from your
> vesa_drv).
>
> I always thought, that my 'Session_component' is created once when the
> first client opens a connection to my service, so that init calls
> 'create_session' in my 'Root_component' just once and never again.
>
> That was obviously wrong. I've found out, that 'create_session' is
> called once for each client - not on creation of the connection but on
> the first ipc call the client invokes.
That's not fully true. It is called every time on creation of a new session
for a client (normally, not by the client itself). It is not called when the
client invokes the first IPC. When the client calls the server the first time
the session has to be created already. The outcome of the session creation
process is, that the client owns a capability referencing the service.
Without the capability the client cannot call the server. So a client cannot
call that service before 'create_session' was invoked.
>
> For my setting, this behaviour is not useful, so I've manually taken
> care of being a singleton by allocating my 'Root_component' only once in
> 'create-session' and handing out that single object subsequently on each
> following session creation.
>
> I've noticed some strange behaviour with that setting.
>
> (1) I saw that something complained about my singleton
> --
> [init -> vesa_drv] void
> Genode::Avl_node<NT>::insert(Genode::Avl_node<NT>*) [wit
> h NT = Genode::Object_pool<Genode::Server_object>::Entry]: Inserting
> element 26f
> c twice into avl tree!
> --
When in Genode a node (process) requests a 'session' from its parent, that
request - dependent on your policy - is further propagated until it reaches a
node, which owns a capability to the 'root interface' of the requested
service (base/include/root/root.h). By calling the 'session(arg)' method of
the 'root-interface' one creates a new 'Session_component' - each time it is
called. After the creation process, that component is inserted in an AVL
tree. That tree is used to locate 'Session_component's of the different
clients. So if you implement 'create_session' in a manner, that it will
return the same object twice, you will get the first exception, when the same
object is inserted twice in that tree.
>
> But that did not seem to matter, so I ignored it...
>
Well, you shouldn't ignore that :-)
> (2) I had to identify my clients somehow to maintain state information.
> So I hand over a 'shared secret' in each ipc call. That's simply the
> dataspace cap the client got from me.
>
That's exactly the task of a Session_component - to maintain state information
of the client. The client's capability in fact references a Session_component
and the state encapsulated in that object, so you don't need an extra
identifier or secret.
To your problem: you have to share another common object between
different 'Session_component's of the corresponding clients, if you have to
share something. For example: you might have some framebuffer object
representing the physical framebuffer, that is globally known or referenced
by each Session_component, the Session_component stores all information
needed to handle the clients virtual framebuffer.
That way you don't have to abuse the framework's abstractions either ;-).
Potentially, the documentation of sessions, session components and root
components isn't suffcient. We will review our documents for that.
Also, the vesa framebuffer driver isn't a good starting point for you, as you
want to serve different clients and the driver is limited to one client. You
may have a look at the nitlog service for example, which multiplexes logging
messages of different clients into one buffer (demo/src/server/nitlog).
Moreover, you may have a look at the architectural description of the session
interface once again:
http://genode.org/documentation/architecture/interfaces
And the introductorily server/client tutorial:
http://genode.org/documentation/developer-resources/client_server_tutorial
> I noticed that something else than my clients called one of my methods
> during startup with an invalid secret.
>
> --
> [init -> vesa_drv] virtual void
> Framebuffer::Session_component::toggle(Genode::D
> ataspace_capability): Framebuffer::Session_component::toggle
> 4b383d61h
> [init -> vesa_drv] virtual void
> Framebuffer::Session_component::toggle(Genode::D
> ataspace_capability): Framebuffer::Session_component::toggle: _fb_cap
> not accept
> ed.
> --
>
> I wonder who might that be. Maybe a relict of mine or does the framework
> some kind of 'reflection'?
It might be a relict or a client, that only speaks the original framebuffer
protocol and not your extended one - but its just guessing.
>
> (3) However, all that did not really bother, and for a start, everything
> seemed to work nice, but when my setting grew bigger, some ipcs didn't
> work properly.
>
> One of my two clients (the 2nd) caught an 'Ipc_error' when performing
> its second request. The first request performed fine. I thought that
> maybe the ipc could not be performed because the Session_component was
> serving another ipc at that moment. So I've ignored the exception and i
> kept retrying the ipc call. Without any success, and from here on I
> can't imagine what happens.
You don't get an IPC error because another client uses the same
Session_component, in that case you would simply block.
It's hard to give you a hint in the right direction without knowing the code,
but I recommend, that you first fix the problems above, before searching for
a solution to this one. Potentially it is caused by the former problems.
I have a question too. I wonder why do you write a component to multiplex the
framebuffer, when you have nitpicker, which does this for you. Do you need
some extraordinary functionality?
kind regards
Stefan
PS: In general, it is a good idea to abstract things like multiplexing a
driver within a new component and not to build it inside the vesa driver. By
that you could use different framebuffer drivers for your virtual
framebuffer, but potentially now its better not to open up to many building
sites at the same time.
>
> Does anyone have an idea what I've missed?
>
> Kind regards
>
> Sven
> --
> Sven Fülster
>
>
> ---------------------------------------------------------------------------
>--- Let Crystal Reports handle the reporting - Free Crystal Reports 2008
> 30-Day trial. Simplify your report design, integration and deployment - and
> focus on what you do best, core application coding. Discover what's new
> with Crystal Reports now. http://p.sf.net/sfu/bobj-july
> _______________________________________________
> Genode-main mailing list
> Genode-main at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs Developer
http://genode-labs.com
More information about the users
mailing list