More cleanups
This commit is contained in:
parent
a615e395f2
commit
f706404e6e
11 changed files with 318 additions and 183 deletions
|
@ -5,6 +5,7 @@ BISON_TARGET(mmss_config_parse config.y ${CMAKE_CURRENT_BINARY_DIR}/config.yy.cp
|
|||
|
||||
add_executable(mmss
|
||||
config.cpp
|
||||
gmrf.cpp
|
||||
iface.cpp
|
||||
log.cpp
|
||||
mmss.cpp
|
||||
|
|
|
@ -40,13 +40,12 @@ namespace Config {
|
|||
void add_network(context_t *mmss, config_t *conf, const char *name) {
|
||||
logf(mmss, LOG_NOTICE, "adding network `%s'", name);
|
||||
|
||||
network_t *net = new network_t;
|
||||
std::shared_ptr<network_t> net = std::make_shared<network_t>();
|
||||
|
||||
net->name = strdup(name);
|
||||
net->name = name;
|
||||
net->mtu = 1500;
|
||||
|
||||
net->next = conf->networks;
|
||||
conf->networks = net;
|
||||
conf->network.push_back(net);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
143
mmss/gmrf.cpp
Normal file
143
mmss/gmrf.cpp
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
Copyright (c) 2013, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "mmss.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
gmrf_addr_t gmrf_iface_get_addr(gmrf_t *gmrf, gmrf_iface_t *iface) {
|
||||
return iface->address;
|
||||
}
|
||||
|
||||
const char* gmrf_iface_get_name(gmrf_t *gmrf, gmrf_iface_t *iface) {
|
||||
return iface->name.c_str();
|
||||
}
|
||||
|
||||
size_t gmrf_iface_get_mtu(gmrf_t *gmrf, gmrf_iface_t *iface) {
|
||||
auto net = iface->net.lock();
|
||||
if (!net)
|
||||
return 0;
|
||||
|
||||
return net->mtu;
|
||||
}
|
||||
|
||||
bool gmrf_iface_send(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len, const gmrf_addr_t *dest) {
|
||||
auto src_iface = iface->iface.lock();
|
||||
assert(src_iface);
|
||||
|
||||
auto net = src_iface->net.lock();
|
||||
if (!net)
|
||||
return false;
|
||||
|
||||
for (auto dest_iface : net->interfaces) {
|
||||
if (gmrf_addr_equal(&dest_iface->address, dest)) {
|
||||
MMSS::enqueue(gmrf->mmss, src_iface, dest_iface, data, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gmrf_iface_send_bc(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len) {
|
||||
auto src_iface = iface->iface.lock();
|
||||
assert(src_iface);
|
||||
|
||||
auto net = src_iface->net.lock();
|
||||
if (!net)
|
||||
return false;
|
||||
|
||||
for (auto dest_iface : net->interfaces) {
|
||||
if (dest_iface != src_iface)
|
||||
MMSS::enqueue(gmrf->mmss, src_iface, dest_iface, data, len);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned delay) {
|
||||
auto node = gmrf->node.lock();
|
||||
assert(node);
|
||||
|
||||
std::shared_ptr<MMSS::scheduled_t> scheduled = std::make_shared<MMSS::scheduled_t>();
|
||||
|
||||
scheduled->node = node;
|
||||
scheduled->f = f;
|
||||
scheduled->arg = arg;
|
||||
|
||||
gmrf->mmss->scheduled_queue.put(scheduled, gmrf->mmss->now+delay);
|
||||
}
|
||||
|
||||
gmrf_time_t gmrf_now(gmrf_t *gmrf) {
|
||||
return gmrf->mmss->now;
|
||||
}
|
||||
|
||||
void gmrf_random_bytes(gmrf_t *gmrf, void *buffer, size_t len) {
|
||||
uint8_t *data = reinterpret_cast<uint8_t*>(buffer);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < len; i++)
|
||||
data[i] = rand_r(&gmrf->rand_seed);
|
||||
}
|
||||
|
||||
static inline const char* get_log_prefix(int log_level) {
|
||||
switch(log_level) {
|
||||
case LOG_CRIT:
|
||||
return "Fatal: ";
|
||||
case LOG_ERR:
|
||||
return "Error: ";
|
||||
case LOG_WARNING:
|
||||
return "Warning: ";
|
||||
case LOG_NOTICE:
|
||||
return "Info: ";
|
||||
case LOG_INFO:
|
||||
return "Verbose: ";
|
||||
case LOG_DEBUG:
|
||||
return "DEBUG: ";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) {
|
||||
char buf[1024];
|
||||
size_t pos = 0;
|
||||
|
||||
pos += MMSS::snprintf_safe(buf, sizeof(buf), "%s: %s", gmrf->name.c_str(), get_log_prefix(priority));
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vsnprintf(buf+pos, sizeof(buf)-pos, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
MMSS::logf(gmrf->mmss, priority, "%s", buf);
|
||||
}
|
||||
|
||||
}
|
|
@ -32,29 +32,34 @@
|
|||
namespace MMSS {
|
||||
|
||||
void dispatch(std::shared_ptr<packet_t> packet) {
|
||||
packet->dest->node->proto->handle_packet(packet->dest->node, packet->dest->node->ctx, packet->dest,
|
||||
&packet->source->address, packet->data.get(), packet->len);
|
||||
auto source = packet->source.lock();
|
||||
auto dest = packet->dest.lock();
|
||||
if (!source || !dest)
|
||||
return;
|
||||
|
||||
auto node = dest->node.lock();
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
node->proto->handle_packet(node.get(), node->ctx, dest.get(), &source->address, packet->data.get(), packet->len);
|
||||
}
|
||||
|
||||
void add_iface(gmrf_t *node, network_t *net, const char *name, const gmrf_addr_t *address) {
|
||||
gmrf_iface_t *iface = new gmrf_iface_t;
|
||||
void add_iface(std::shared_ptr<node_t> node, std::shared_ptr<network_t> net, const std::string &name, const gmrf_addr_t *address) {
|
||||
std::shared_ptr<iface_t> iface = iface_t::create();
|
||||
|
||||
iface->name = strdup(name);
|
||||
iface->name = name;
|
||||
iface->address = *address;
|
||||
|
||||
iface->node = node;
|
||||
iface->net = net;
|
||||
|
||||
iface->node_next = node->interfaces;
|
||||
node->interfaces = iface;
|
||||
node->interfaces.push_back(iface);
|
||||
net->interfaces.push_back(iface);
|
||||
|
||||
iface->network_next = net->interfaces;
|
||||
net->interfaces = iface;
|
||||
|
||||
node->proto->add_iface(node, node->ctx, iface);
|
||||
node->proto->add_iface(node.get(), node->ctx, iface.get());
|
||||
}
|
||||
|
||||
static void enqueue(context_t *mmss, gmrf_iface_t *source, gmrf_iface_t *dest, const void *data, size_t len) {
|
||||
void enqueue(context_t *mmss, std::shared_ptr<iface_t> source, std::shared_ptr<iface_t> dest, const void *data, size_t len) {
|
||||
std::shared_ptr<packet_t> packet = std::make_shared<packet_t>();
|
||||
|
||||
packet->sent = mmss->now;
|
||||
|
@ -69,38 +74,3 @@ static void enqueue(context_t *mmss, gmrf_iface_t *source, gmrf_iface_t *dest, c
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
gmrf_addr_t gmrf_iface_get_addr(gmrf_t *gmrf, gmrf_iface_t *iface) {
|
||||
return iface->address;
|
||||
}
|
||||
|
||||
const char* gmrf_iface_get_name(gmrf_t *gmrf, gmrf_iface_t *iface) {
|
||||
return iface->name;
|
||||
}
|
||||
|
||||
size_t gmrf_iface_get_mtu(gmrf_t *gmrf, gmrf_iface_t *iface) {
|
||||
return iface->net->mtu;
|
||||
}
|
||||
|
||||
bool gmrf_iface_send(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len, const gmrf_addr_t *dest) {
|
||||
gmrf_iface_t *dest_iface;
|
||||
for (dest_iface = iface->net->interfaces; dest_iface; dest_iface = dest_iface->network_next) {
|
||||
if (gmrf_addr_equal(&dest_iface->address, dest)) {
|
||||
MMSS::enqueue(gmrf->mmss, iface, dest_iface, data, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gmrf_iface_send_bc(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len) {
|
||||
gmrf_iface_t *dest_iface;
|
||||
for (dest_iface = iface->net->interfaces; dest_iface; dest_iface = dest_iface->network_next) {
|
||||
if (dest_iface != iface)
|
||||
enqueue(gmrf->mmss, iface, dest_iface, data, len);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
47
mmss/log.cpp
47
mmss/log.cpp
|
@ -25,41 +25,10 @@
|
|||
|
||||
|
||||
#include "mmss.hpp"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
|
||||
#include "util.hpp"
|
||||
|
||||
namespace MMSS {
|
||||
|
||||
static inline int snprintf_safe(char *buffer, size_t size, const char *format, ...) {
|
||||
std::va_list ap;
|
||||
va_start(ap, format);
|
||||
int ret = std::vsnprintf(buffer, size, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ret < 0 ? 0 : ret > size ? size : ret;
|
||||
}
|
||||
|
||||
static inline const char* get_log_prefix(int log_level) {
|
||||
switch(log_level) {
|
||||
case LOG_CRIT:
|
||||
return "Fatal: ";
|
||||
case LOG_ERR:
|
||||
return "Error: ";
|
||||
case LOG_WARNING:
|
||||
return "Warning: ";
|
||||
case LOG_NOTICE:
|
||||
return "Info: ";
|
||||
case LOG_INFO:
|
||||
return "Verbose: ";
|
||||
case LOG_DEBUG:
|
||||
return "DEBUG: ";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
void logf(context_t *mmss, int priority, const char *format, ...) {
|
||||
char buf[1024];
|
||||
size_t pos = 0;
|
||||
|
@ -75,17 +44,3 @@ void logf(context_t *mmss, int priority, const char *format, ...) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) {
|
||||
char buf[1024];
|
||||
size_t pos = 0;
|
||||
|
||||
pos += MMSS::snprintf_safe(buf, sizeof(buf), "%s: %s", gmrf->name, MMSS::get_log_prefix(priority));
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vsnprintf(buf+pos, sizeof(buf)-pos, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
MMSS::logf(gmrf->mmss, priority, "%s", buf);
|
||||
}
|
||||
|
|
|
@ -30,25 +30,11 @@
|
|||
#include <cstdio>
|
||||
|
||||
|
||||
gmrf_time_t gmrf_now(gmrf_t *gmrf) {
|
||||
return gmrf->mmss->now;
|
||||
}
|
||||
|
||||
void gmrf_random_bytes(gmrf_t *gmrf, void *buffer, size_t len) {
|
||||
uint8_t *data = reinterpret_cast<uint8_t*>(buffer);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < len; i++)
|
||||
data[i] = rand_r(&gmrf->rand_seed);
|
||||
}
|
||||
|
||||
namespace MMSS {
|
||||
|
||||
static void init_nodes(gmrf_t *nodes) {
|
||||
gmrf_t *node;
|
||||
for (node = nodes; node; node = node->next) {
|
||||
node->ctx = node->proto->init(node);
|
||||
}
|
||||
static void init_nodes(std::list<std::shared_ptr<node_t>> &nodes) {
|
||||
for (auto node : nodes)
|
||||
node->ctx = node->proto->init(node.get());
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,22 +71,29 @@ void main(int argc, char *argv[]) {
|
|||
|
||||
read_config(&mmss, &conf, "babel_test.mmss");
|
||||
|
||||
network_t net0 = { .mtu = 1500 }, net1 = { .mtu = 1500 };
|
||||
gmrf_t node1 = { .name = strdup("node1"), .mmss = &mmss, .rand_seed = 1, .proto = proto };
|
||||
gmrf_t node2 = { .name = strdup("node2"), .mmss = &mmss, .rand_seed = 2, .proto = proto };
|
||||
gmrf_t node3 = { .name = strdup("node3"), .mmss = &mmss, .rand_seed = 3, .proto = proto };
|
||||
std::shared_ptr<network_t> net0 = std::make_shared<network_t>();
|
||||
std::shared_ptr<network_t> net1 = std::make_shared<network_t>();
|
||||
|
||||
node2.next = &node1;
|
||||
node3.next = &node2;
|
||||
gmrf_t *nodes = &node3;
|
||||
*net0 = (network_t){ .mtu = 1500 };
|
||||
*net1 = (network_t){ .mtu = 1500 };
|
||||
|
||||
std::shared_ptr<node_t> node1 = node_t::create(&mmss, "node1", 1, proto);
|
||||
std::shared_ptr<node_t> node2 = node_t::create(&mmss, "node2", 2, proto);
|
||||
std::shared_ptr<node_t> node3 = node_t::create(&mmss, "node3", 3, proto);
|
||||
|
||||
std::list<std::shared_ptr<node_t>> nodes;
|
||||
|
||||
nodes.push_back(node1);
|
||||
nodes.push_back(node2);
|
||||
nodes.push_back(node3);
|
||||
|
||||
init_nodes(nodes);
|
||||
|
||||
gmrf_addr_t addr1 = {{1}}, addr2 = {{2}}, addr3 = {{3}}, addr4 = {{4}};
|
||||
add_iface(&node1, &net0, "mmss0", &addr1);
|
||||
add_iface(&node2, &net0, "mmss0", &addr2);
|
||||
add_iface(&node2, &net1, "mmss1", &addr3);
|
||||
add_iface(&node3, &net1, "mmss1", &addr4);
|
||||
add_iface(node1, net0, "mmss0", &addr1);
|
||||
add_iface(node2, net0, "mmss0", &addr2);
|
||||
add_iface(node2, net1, "mmss1", &addr3);
|
||||
add_iface(node3, net1, "mmss1", &addr4);
|
||||
|
||||
while (true) {
|
||||
int timeout = get_queue_timeout(&mmss);
|
||||
|
|
112
mmss/mmss.hpp
112
mmss/mmss.hpp
|
@ -29,9 +29,67 @@
|
|||
|
||||
#include "queue.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
|
||||
struct gmrf {
|
||||
private:
|
||||
gmrf(MMSS::context_t *mmss0, const std::string &name0, unsigned rand_seed0, const MMSS::protocol_t *proto0) :
|
||||
mmss(mmss0), name(name0), rand_seed(rand_seed0), proto(proto0) {}
|
||||
gmrf(gmrf const&) = delete;
|
||||
gmrf& operator=(gmrf const&) = delete;
|
||||
|
||||
public:
|
||||
static std::shared_ptr<MMSS::node_t> create(MMSS::context_t *mmss, const std::string &name, unsigned rand_seed, const MMSS::protocol_t *proto) {
|
||||
MMSS::node_t *node = new MMSS::node_t(mmss, name, rand_seed, proto);
|
||||
|
||||
std::shared_ptr<MMSS::node_t> ptr(node);
|
||||
node->node = ptr;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
std::weak_ptr<MMSS::node_t> node;
|
||||
|
||||
MMSS::context_t *mmss;
|
||||
|
||||
std::string name;
|
||||
|
||||
gmrf_context_t *ctx;
|
||||
std::list<std::shared_ptr<MMSS::iface_t>> interfaces;
|
||||
|
||||
unsigned rand_seed;
|
||||
|
||||
const MMSS::protocol_t *proto;
|
||||
};
|
||||
|
||||
struct gmrf_iface {
|
||||
private:
|
||||
gmrf_iface() {}
|
||||
gmrf_iface(gmrf_iface const&) = delete;
|
||||
gmrf_iface& operator=(gmrf_iface const&) = delete;
|
||||
|
||||
public:
|
||||
static std::shared_ptr<MMSS::iface_t> create() {
|
||||
MMSS::iface_t *iface = new MMSS::iface_t;
|
||||
|
||||
std::shared_ptr<MMSS::iface_t> ptr(iface);
|
||||
iface->iface = ptr;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
std::weak_ptr<MMSS::iface_t> iface;
|
||||
|
||||
std::string name;
|
||||
gmrf_addr_t address;
|
||||
|
||||
std::weak_ptr<MMSS::node_t> node;
|
||||
std::weak_ptr<MMSS::network_t> net;
|
||||
};
|
||||
|
||||
|
||||
namespace MMSS {
|
||||
|
||||
class context_t {
|
||||
|
@ -45,17 +103,15 @@ public:
|
|||
|
||||
class config_t {
|
||||
public:
|
||||
network_t *networks;
|
||||
gmrf_t *nodes;
|
||||
std::list<std::shared_ptr<network_t>> network;
|
||||
std::list<std::shared_ptr<node_t>> nodes;
|
||||
};
|
||||
|
||||
class network_t {
|
||||
public:
|
||||
network_t *next;
|
||||
std::string name;
|
||||
|
||||
char *name;
|
||||
|
||||
gmrf_iface_t *interfaces;
|
||||
std::list<std::shared_ptr<iface_t>> interfaces;
|
||||
size_t mtu;
|
||||
};
|
||||
|
||||
|
@ -63,8 +119,8 @@ class packet_t {
|
|||
public:
|
||||
uint64_t sent;
|
||||
|
||||
gmrf_iface_t *source;
|
||||
gmrf_iface_t *dest;
|
||||
std::weak_ptr<iface_t> source;
|
||||
std::weak_ptr<iface_t> dest;
|
||||
|
||||
size_t len;
|
||||
std::unique_ptr<uint8_t> data;
|
||||
|
@ -72,7 +128,7 @@ public:
|
|||
|
||||
class scheduled_t {
|
||||
public:
|
||||
gmrf_t *node;
|
||||
std::shared_ptr<node_t> node;
|
||||
gmrf_scheduled_func f;
|
||||
void *arg;
|
||||
};
|
||||
|
@ -80,20 +136,15 @@ public:
|
|||
|
||||
const protocol_t* load_protocol(const char *module);
|
||||
|
||||
namespace Config {
|
||||
|
||||
void add_network(context_t *mmss, config_t *conf, const char *name);
|
||||
|
||||
}
|
||||
|
||||
bool read_config(context_t *mmss, config_t *conf, const char *filename);
|
||||
|
||||
void add_iface(gmrf_t *node, network_t *net, const char *name, const gmrf_addr_t *address);
|
||||
void add_iface(std::shared_ptr<node_t> node, std::shared_ptr<network_t> net, const std::string &name, const gmrf_addr_t *address);
|
||||
|
||||
uint64_t now(const context_t *mmss);
|
||||
|
||||
void dispatch(std::shared_ptr<packet_t> packet);
|
||||
void run_scheduled(std::shared_ptr<scheduled_t> scheduled);
|
||||
void enqueue(context_t *mmss, std::shared_ptr<iface_t> source, std::shared_ptr<iface_t> dest, const void *data, size_t len);
|
||||
|
||||
void logf(context_t *mmss, int priority, const char *format, ...);
|
||||
|
||||
|
@ -111,31 +162,14 @@ static inline size_t alignto(size_t l, size_t a) {
|
|||
return ((l+a-1)/a)*a;
|
||||
}
|
||||
|
||||
|
||||
namespace Config {
|
||||
|
||||
void add_network(context_t *mmss, config_t *conf, const char *name);
|
||||
|
||||
}
|
||||
|
||||
struct gmrf {
|
||||
gmrf_t *next;
|
||||
}
|
||||
|
||||
char *name;
|
||||
|
||||
MMSS::context_t *mmss;
|
||||
gmrf_context_t *ctx;
|
||||
gmrf_iface_t *interfaces;
|
||||
|
||||
unsigned rand_seed;
|
||||
|
||||
const MMSS::protocol_t *proto;
|
||||
};
|
||||
|
||||
struct gmrf_iface {
|
||||
gmrf_iface_t *node_next;
|
||||
gmrf_iface_t *network_next;
|
||||
|
||||
char *name;
|
||||
gmrf_addr_t address;
|
||||
|
||||
gmrf_t *node;
|
||||
MMSS::network_t *net;
|
||||
};
|
||||
|
||||
#endif /* _GMRF_MMSS_MMSS_HPP_ */
|
||||
|
|
|
@ -33,21 +33,21 @@
|
|||
namespace MMSS {
|
||||
|
||||
const protocol_t* load_protocol(const char *module) {
|
||||
void *handle = dlopen(module, RTLD_NOW);
|
||||
void *handle = ::dlopen(module, RTLD_NOW);
|
||||
if (!handle) {
|
||||
fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror());
|
||||
std::fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dlerror();
|
||||
const protocol_t *proto = reinterpret_cast<const protocol_t*>(dlsym(handle, "mmss_protocol_info"));
|
||||
::dlerror();
|
||||
const protocol_t *proto = reinterpret_cast<const protocol_t*>(::dlsym(handle, "mmss_protocol_info"));
|
||||
if (!proto) {
|
||||
fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror());
|
||||
dlclose(handle);
|
||||
std::fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror());
|
||||
::dlclose(handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fprintf(stderr, "loaded protocol `%s' version %s\n", proto->get_name(), proto->get_version());
|
||||
std::fprintf(stderr, "loaded protocol `%s' version %s\n", proto->get_name(), proto->get_version());
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
|
|
@ -30,17 +30,7 @@
|
|||
namespace MMSS {
|
||||
|
||||
void run_scheduled(std::shared_ptr<scheduled_t> scheduled) {
|
||||
scheduled->f(scheduled->node, scheduled->node->ctx, scheduled->arg);
|
||||
scheduled->f(scheduled->node.get(), scheduled->node->ctx, scheduled->arg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned delay) {
|
||||
std::shared_ptr<MMSS::scheduled_t> scheduled = std::make_shared<MMSS::scheduled_t>();
|
||||
|
||||
scheduled->node = gmrf;
|
||||
scheduled->f = f;
|
||||
scheduled->arg = arg;
|
||||
|
||||
gmrf->mmss->scheduled_queue.put(scheduled, gmrf->mmss->now+delay);
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
|
||||
extern "C" {
|
||||
|
||||
#include <gmrf/gmrf.h>
|
||||
#include <mmss/protocol.h>
|
||||
#include <gmrf/gmrf.h>
|
||||
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,9 @@ class scheduled_t;
|
|||
|
||||
typedef ::mmss_protocol_t protocol_t;
|
||||
|
||||
typedef ::gmrf_t node_t;
|
||||
typedef ::gmrf_iface_t iface_t;
|
||||
|
||||
}
|
||||
|
||||
#endif /* _GMRF_MMSS_TYPES_HPP_ */
|
||||
|
|
47
mmss/util.hpp
Normal file
47
mmss/util.hpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Copyright (c) 2013, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _GMRF_MMSS_UTIL_HPP_
|
||||
#define _GMRF_MMSS_UTIL_HPP_
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
namespace MMSS {
|
||||
|
||||
static inline int snprintf_safe(char *buffer, size_t size, const char *format, ...) {
|
||||
std::va_list ap;
|
||||
va_start(ap, format);
|
||||
int ret = std::vsnprintf(buffer, size, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ret < 0 ? 0 : ret > size ? size : ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* _GMRF_MMSS_UTIL_HPP_ */
|
Reference in a new issue