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 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 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(),
L4Re::Rm::F::Search_addr | L4Re::Rm::F::RW,
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;
}
Interface for memory-like objects.
Definition: dataspace:63
static Env const * env() noexcept
Returns the initial environment for the current task.
Definition: env:103
L4::Cap< Mem_alloc > mem_alloc() const noexcept
Object-capability to the memory allocator.
Definition: env:116
L4::Cap< Rm > rm() const noexcept
Object-capability to the region map.
Definition: env:127
L4::Cap< void > alloc() noexcept
Allocate a new capability slot.
bool free(L4::Cap< void > cap, l4_cap_idx_t task=L4_INVALID_CAP, unsigned unmap_flags=L4_FP_ALL_SPACES) noexcept
Free the capability.
L4::Cap< void > register_obj(L4::Epiface *o, char const *service) override
Register a new server object to a pre-allocated receive endpoint.
L4::Cap< L4::Irq > register_irq_obj(L4::Epiface *o) override
Register a handler for an interrupt.
A server loop object which has a Object_registry included.
void L4_NORETURN loop()
Start the server loop.
Object_registry const * registry() const
Return registry of this server loop.
Input/Output stream for IPC [un]marshalling.
Definition: ipc_stream:803
virtual int dispatch(unsigned long rights, Ipc::Iostream &ios)=0
The abstract handler for client requests to the object.
IPC server loop.
Dataspace interface.
Environment interface.
unsigned long l4_umword_t
Unsigned machine word.
Definition: l4int.h:52
@ L4_EBADPROTO
Unsupported protocol.
Definition: err.h:61
_Cap_alloc & cap_alloc
Capability allocator.
Cap< T > make_cap_rw(L4::Cap< T > cap) noexcept
Make an L4::Ipc::Cap<T> for the given capability with L4_CAP_FPAGE_RW rights.
Definition: ipc_types:634
Namespace interface.
@ Search_addr
Search for a suitable address range.
Definition: rm:105
Server object base class for handling IRQ messages.
Definition: ipc_server:172
Base class (template) for server implementing server objects.
Definition: ipc_server:92
Message tag data structure.
Definition: types.h:160
long label() const L4_NOTHROW
Get the protocol value.
Definition: types.h:164
Type information server template.
Capability allocator.