L4Re Operating System Framework – Interface and Usage Documentation
Loading...
Searching...
No Matches
examples/libs/l4re/c++/shared_ds/ds_srv.cc

Sharing memory between applications, server/creator side.

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(),
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< L4::Irq > register_irq_obj(L4::Epiface *o) override
Register a handler for an interrupt.
L4::Cap< void > register_obj(L4::Epiface *o, char const *service) override
Register a new server object to a pre-allocated receive endpoint.
A server loop object which has a Object_registry included.
Object_registry const * registry() const
Return registry of this server loop.
void L4_NORETURN loop(l4_utcb_t *utcb=l4_utcb())
Start the server loop.
C++ interface for capabilities.
Definition capability.h:222
Input/Output stream for IPC [un]marshalling.
Definition ipc_stream:801
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:51
@ 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:638
Namespace interface.
@ RW
Readable and writable region.
Definition rm:140
@ Search_addr
Search for a suitable address range.
Definition rm:118
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:163
long label() const L4_NOTHROW
Get the protocol value.
Definition types.h:167
Type information server template.
Capability allocator.