Session object pool

Norman Feske norman.feske at ...1...
Tue Nov 29 17:51:30 CET 2011


Hello Alexander,

> I'm writing a server application which acts as a communicator between it's  
> clients. Each of my sessions needs to know about other active sessions, so  
> what I'd like to know is if there is a way to access the session object  
> pool directly, or should I maintain my own list of running sessions?

In cases like this, we use the maintain a separate data structure. From
my experience, the lookup of other sessions is mostly concerned about a
certain property of the session object - not the session object as a
whole. So it often make sense to give this property a separate name in
the form of a type. For an example, you may take a look at the new TCP
terminal server that comes with the Genode version 11.11. You can find
it at:

  gems/src/server/tcp_terminal/main.cc

In this server, each session corresponds to a potentially open socket.
For this particular property (a socket that is open), we defined a
separate interface ('Open_socket'), which is inherited by the
'Session_component'. At session-creation time, the
'Open_socket'-property gets constructed. In the constructor, its adds
itself to the global 'open_socket_pool', which can then be used to query
open sockets.

Of course, we could have used a plain list of sessions but the way the
TCP terminal is implemented makes it more obvious which part of the
session (only the 'Open_socket interface') is exposed to others.

I hope not to confuse you with this example. In short, I recommend you
to use a separate data structure.

> Also, a question about "doing it the right way". I transfer data chunks  
> (not more than several Kbytes) to/from clients using RPC calls (initiated  
> by clients), and I use Signal_transmitter objects to notify clients about  
> data & other stuff. Is that normal? ;)

Great that you are asking! There is no universal answer to this question
though. It depends on the rate and expected throughput of communication
and the desired simplicity of your implementation. To give some examples:

* At core, we want to keep things as simple as possible. Hence, the LOG
  service uses a plain synchronous RPC interface for transmitting
  LOG output ('Log_session::write').

* For use cases where we expect a lot of traffic, the overhead of
  chopping the payload in tiny messages is unfortunate. For this
  reason, the higher-level 'Terminal::Session' interface is designed
  to use a combination of a shared-memory buffer and signaling.
  Client and server share a dataspace that is allocated at the
  server-side when the session is created. The server does newer
  change the content of the dataspace except when explicitly
  asked by the client. If a client wants to output data, it writes
  its data to the dataspace and then informs the server to consume
  it via a synchronous RPC call. While the RPC call is in flight,
  the server copies-out the data and consumes it. Reading data
  works similar. The client explicitly asks the server to copy new
  data to the dataspace by issuing an RPC call. So the payload
  gets transferred via shared memory but client and server work
  synchronous.

  I think, your example resembles this case, right?

* For bulk data, it is often desired to decouple client and server
  as much as possible. For example, a NIC driver may receive
  network packets at a high rate, or a music player wants to
  stream a bulk of audio samples to a audio mixer. In such cases,
  issuing an RPC call per data packet is a bad idea because each
  packet would involve multiple context switches. For this reason
  Genode's interfaces for networking (nic_session), block devices
  (block_session), audio output (audio_out_session) make use
  of the packet-stream API. This API is based on shared memory and
  a data-flow protocol that uses signaling only. In contrast to
  the terminal session mentioned above, both client and server
  access the dataspace at the same time, but different portions
  of it. The pointers to the packet-stream API are:

    os/include/os/packet_stream.h - general API
    os/include/packet_stream_rx/  - for a server that receives data
    os/include/packet_stream_tx/  - for a server that transmits data

  The NIC session is both, a receiver and transmitter. So it is a
  good example to take as reference of using this API:

    os/include/nic_session/


Hopefully, this little overview is of help. Please do not hesitate to
dig further. .-)

Cheers
Norman


-- 
Dr.-Ing. Norman Feske
Genode Labs

http://www.genode-labs.com · http://genode.org

Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden
Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth




More information about the users mailing list