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/error_helper>
#include <l4/re/namespace>
#include <l4/re/util/cap_alloc>
#include <l4/re/util/object_registry>
#include <l4/re/dataspace>
#include <l4/cxx/ipc_server>
#include <l4/util/util.h>
#include <l4/sys/typeinfo_svr>
#include <cstring>
#include <cstdio>
#include <unistd.h>
#include <pthread.h>
#include <pthread-l4.h>
#include <thread>
#include "interface.h"
class My_server_obj : public L4::Server_object_t<L4::Kobject>
{
private:
L4::Cap<L4Re::Dataspace> _shm;
L4::Cap<L4::Irq> _irq;
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;
l4_msgtag_t t;
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)
{
*_ds = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
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");
L4Re::Util::cap_alloc.free(*_ds);
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,
L4::Ipc::make_cap_rw(*_ds));
if (err < 0)
{
printf("Error attaching data space: %s\n", l4sys_errtostr(err));
L4Re::Util::cap_alloc.free(*_ds);
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;
}
static void *server_thread(void *)
{
L4::Cap<L4::Thread> l4_thread = Pthread::L4::cap(pthread_self());
L4Re::Util::Registry_server<> server(l4_thread, L4Re::Env::env()->factory());
L4::Cap<L4Re::Dataspace> ds;
char *addr;
if (!(addr = get_ds(&ds)))
return nullptr;
// 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();
}
int main()
{
pthread_attr_t pattr;
if (pthread_attr_init(&pattr))
L4Re::throw_error(-L4_ENOMEM, "Initialize pthread attributes");
pthread_t thr;
L4Re::chksys(pthread_create(&thr, &pattr, server_thread, nullptr),
"Create server thread");
L4Re::chksys(pthread_attr_destroy(&pattr), "Destroy pthread attributes");
l4_sleep_forever();
return 0;
}
L4Re::Dataspace
Interface for memory-like objects.
Definition dataspace:53
L4Re::Env::env
static Env const * env() noexcept
Returns the initial environment for the current task.
Definition env:96
L4Re::Env::mem_alloc
L4::Cap< Mem_alloc > mem_alloc() const noexcept
Object-capability to the memory allocator.
Definition env:109
L4Re::Env::rm
L4::Cap< Rm > rm() const noexcept
Object-capability to the region map.
Definition env:120
L4Re::Util::Registry_server
A server loop object which has a Object_registry included.
Definition object_registry:294
L4::Cap
C++ interface for capabilities.
Definition capability.h:224
L4::Ipc::Iostream
Input/Output stream for IPC [un]marshalling.
Definition ipc_stream:790
L4::Server_object::dispatch
virtual int dispatch(unsigned long rights, Ipc::Iostream &ios)=0
The abstract handler for client requests to the object.
ipc_server
IPC server loop.
dataspace
Dataspace interface.
env
Environment interface.
error_helper
Error helper.
l4_umword_t
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
L4_ENOMEM
@ L4_ENOMEM
No memory.
Definition err.h:39
L4_EBADPROTO
@ L4_EBADPROTO
Unsupported protocol.
Definition err.h:51
L4Re::Util::cap_alloc
_Cap_alloc & cap_alloc
Capability allocator.
l4_sleep_forever
void l4_sleep_forever(void) L4_NOTHROW L4_NORETURN
Go sleep and never wake up.
Definition util.h:85
L4Re::chksys
long chksys(long err, char const *extra="", long ret=0)
Generate C++ exception on error.
Definition error_helper:72
L4Re::throw_error
void throw_error(long err, char const *extra="")
Generate C++ exception.
Definition error_helper:37
L4::Ipc::make_cap_rw
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:795
namespace
Namespace interface.
L4Re::Rm::F::RW
@ RW
Readable and writable region.
Definition rm:139
L4Re::Rm::F::Search_addr
@ Search_addr
Search for a suitable address range.
Definition rm:114
L4::Irq_handler_object
Server object base class for handling IRQ messages.
Definition ipc_server:161
L4::Server_object_t
Base class (template) for server implementing server objects.
Definition ipc_server:81
l4_msgtag_t
Message tag data structure.
Definition types.h:154
l4_msgtag_t::label
long label() const L4_NOTHROW
Get the protocol value.
Definition types.h:158
typeinfo_svr
Type information server template.
cap_alloc
Capability allocator.