L4Re - L4 Runtime Environment
examples/libs/l4re/c++/shared_ds/ds_srv.cc

Sharing memory between applications, server/creator side.

/*
* (c) 2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
* Alexander Warg <warg@os.inf.tu-dresden.de>
* economic rights: Technische Universit├Ąt Dresden (Germany)
*
* This file is part of TUD:OS and distributed under the terms of the
* GNU General Public License 2.
* Please see the COPYING-GPL-2 file for details.
*/
#include <l4/re/env>
#include <l4/re/namespace>
#include <l4/re/util/object_registry>
#include <l4/re/dataspace>
#include <cstring>
#include <cstdio>
#include <unistd.h>
#include "interface.h"
class My_server_obj : public L4::Server_object_t<L4::Kobject>
{
private:
public:
explicit My_server_obj(L4::Cap<L4Re::Dataspace> shm, L4::Cap<L4::Irq> irq)
: _shm(shm), _irq(irq)
{}
int dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios);
};
int My_server_obj::dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios)
{
// we don't care about the original object reference, however
// we could read out the access rights from the lowest 2 bits
(void) obj;
ios >> t; // extract the tag
switch (t.label())
{
case L4::Meta::Protocol:
// handle the meta protocol requests, implementing the
// runtime dynamic type system for L4 objects.
return L4::Util::handle_meta_request<My_interface>(ios);
case 0:
// since we have just one operation we have no opcode dispatch,
// and just return the data-space and the notifier IRQ capabilities
ios << _shm << _irq;
return 0;
default:
// every other protocol is not supported.
return -L4_EBADPROTO;
}
}
class Shm_observer : public L4::Irq_handler_object
{
private:
char *_shm;
public:
explicit Shm_observer(char *shm)
: _shm(shm)
{}
int dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios);
};
int Shm_observer::dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios)
{
// We don't care about the original object reference, however
// we could read out the access rights from the lowest 2 bits
(void)obj;
// Since we end up here in this function, we got a 'message' from the IRQ
// that is bound to us. The 'ios' stream won't contain any valuable info.
(void)ios;
printf("Client sent us: %s\n", _shm);
return 0;
}
enum
{
DS_SIZE = 4 << 12,
};
static char *get_ds(L4::Cap<L4Re::Dataspace> *_ds)
{
if (!(*_ds).is_valid())
{
printf("Dataspace allocation failed.\n");
return 0;
}
int err = L4Re::Env::env()->mem_alloc()->alloc(DS_SIZE, *_ds, 0);
if (err < 0)
{
printf("mem_alloc->alloc() failed.\n");
return 0;
}
/*
* Attach DS to local address space
*/
char *_addr = 0;
err = L4Re::Env::env()->rm()->attach(&_addr, (*_ds)->size(),
if (err < 0)
{
printf("Error attaching data space: %s\n", l4sys_errtostr(err));
return 0;
}
/*
* Success! Write something to DS.
*/
printf("Attached DS\n");
static char const * const msg = "[DS] Hello from server!";
snprintf(_addr, strlen(msg) + 1, msg);
return _addr;
}
int main()
{
char *addr;
if (!(addr = get_ds(&ds)))
return 2;
// First the IRQ handler, because we need it in the My_server_obj object
Shm_observer observer(addr);
// Registering the observer as an IRQ handler, this allocates an
// IRQ object using the factory of our server.
L4::Cap<L4::Irq> irq = server.registry()->register_irq_obj(&observer);
// Now the initial server object shared with the client via our parent.
// it provides the data-space and the IRQ capabilities to a client.
My_server_obj server_obj(ds, irq);
// Registering the server object to the capability 'shm' in our the L4Re::Env.
// This capability must be provided by the parent. (see the shared_ds.lua)
server.registry()->register_obj(&server_obj, "shm");
// Run our server loop.
server.loop();
return 0;
}