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