Direct inter-module interface

This commit is contained in:
Perttu Ahola 2014-09-17 23:00:31 +03:00
parent 14abc20e5f
commit 780db76d91
11 changed files with 127 additions and 35 deletions

View File

@ -71,6 +71,7 @@ set(SERVER_SRCS
src/impl/fs.cpp
src/impl/event.cpp
src/impl/tcpsocket.cpp
src/impl/module.cpp
)
add_executable(${SERVER_EXE_NAME} ${SERVER_SRCS})
TARGET_LINK_LIBRARIES(${SERVER_EXE_NAME}

View File

@ -42,5 +42,13 @@ namespace network
Resp_get_packet_type(const Packet::Type &type): type(type){}
};
struct Direct
{
virtual ~Direct(){}
virtual Packet::Type packet_type(const ss_ &name) = 0;
virtual void send(PeerInfo::Id recipient, const Packet::Type &type,
const ss_ &data) = 0;
};
}

View File

@ -2,6 +2,7 @@
#include "interface/server.h"
#include "interface/event.h"
#include "interface/tcpsocket.h"
#include "interface/mutex.h"
#include "network/include/api.h"
#include <iostream>
@ -21,14 +22,16 @@ struct Peer
id(id), socket(socket){}
};
struct Module: public interface::Module
struct Module: public interface::Module, public network::Direct
{
interface::Mutex m_interface_mutex;
interface::Server *m_server;
sp_<interface::TCPSocket> m_listening_socket;
sm_<Peer::Id, Peer> m_peers;
size_t m_next_peer_id = 1;
Module(interface::Server *server):
interface::Module("network"),
m_server(server),
m_listening_socket(interface::createTCPSocket())
{
@ -37,6 +40,8 @@ struct Module: public interface::Module
void init()
{
interface::MutexScope ms(m_interface_mutex);
std::cout<<"network init"<<std::endl;
m_server->sub_event(this, Event::t("core:start"));
m_server->sub_event(this, Event::t("network:send"));
@ -51,12 +56,19 @@ struct Module: public interface::Module
void event(const Event::Type &type, const Event::Private *p)
{
interface::MutexScope ms(m_interface_mutex);
EVENT_VOIDN("core:start", on_start)
EVENT_TYPEN("network:send", on_send_packet, Packet)
EVENT_TYPEN("network:listen_event", on_listen_event, interface::SocketEvent)
EVENT_TYPEN("network:get_packet_type", on_get_packet_type, Req_get_packet_type)
}
void* get_interface()
{
return dynamic_cast<Direct*>(this);
}
void on_start()
{
ss_ address = "any4";
@ -102,6 +114,20 @@ struct Module: public interface::Module
m_server->emit_event("network:get_packet_type_resp",
new Resp_get_packet_type(type));
}
// Direct interface
Packet::Type packet_type(const ss_ &name)
{
interface::MutexScope ms(m_interface_mutex);
}
void send(PeerInfo::Id recipient, const Packet::Type &type, const ss_ &data)
{
interface::MutexScope ms(m_interface_mutex);
// TODO
}
};
extern "C" {

13
src/impl/module.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "interface/module.h"
namespace interface {
void* Module::check_interface()
{
void *i = get_interface();
if(!i)
throw Exception(ss_()+"Module \""+NAME+"\" has no interface");
return i;
}
}

View File

@ -8,9 +8,14 @@ namespace interface
{
struct Module
{
const char *NAME = "(unknown module)";
Module(const char *name): NAME(name){}
virtual ~Module(){};
virtual void init() = 0;
// Never call directly; this is not thread-safe
virtual void event(const Event::Type &type, const Event::Private *p) = 0;
virtual void* get_interface(){
return NULL;
}
void* check_interface();
};
}

View File

@ -25,6 +25,9 @@ namespace interface
virtual ss_ get_builtin_modules_path() = 0;
virtual bool has_module(const ss_ &module_name) = 0;
virtual interface::Module* get_module(const ss_ &module_name) = 0;
virtual interface::Module* check_module(const ss_ &module_name) = 0;
virtual void sub_event(struct Module *module, const Event::Type &type) = 0;
virtual void emit_event(Event event) = 0;
template<typename PrivateT>

View File

@ -18,11 +18,11 @@ namespace server {
struct CState: public State, public interface::Server
{
struct ModuleWithMutex {
interface::Mutex mutex;
struct ModuleContainer {
//interface::Mutex mutex;
interface::Module *module;
ModuleWithMutex(interface::Module *module = NULL): module(module){}
ModuleContainer(interface::Module *module = NULL): module(module){}
};
struct SocketState {
@ -33,13 +33,13 @@ struct CState: public State, public interface::Server
up_<rccpp::Compiler> m_compiler;
ss_ m_modules_path;
sm_<ss_, ModuleWithMutex> m_modules;
sm_<ss_, ModuleContainer> m_modules;
interface::Mutex m_modules_mutex;
sv_<Event> m_event_queue;
interface::Mutex m_event_queue_mutex;
sv_<sv_<ModuleWithMutex*>> m_event_subs;
sv_<sv_<ModuleContainer*>> m_event_subs;
interface::Mutex m_event_subs_mutex;
sm_<int, SocketState> m_sockets;
@ -61,9 +61,9 @@ struct CState: public State, public interface::Server
{
interface::MutexScope ms(m_modules_mutex);
for(auto &pair : m_modules){
ModuleWithMutex &mwm = pair.second;
ModuleContainer &mc = pair.second;
// Don't lock; it would only cause deadlocks
delete mwm.module;
delete mc.module;
}
}
@ -80,12 +80,12 @@ struct CState: public State, public interface::Server
interface::Module *m = static_cast<interface::Module*>(
m_compiler->construct(module_name.c_str(), this));
m_modules[module_name] = ModuleWithMutex(m);
m_modules[module_name] = ModuleContainer(m);
{
ModuleWithMutex &mwm = m_modules[module_name];
interface::MutexScope ms2(mwm.mutex);
mwm.module->init();
ModuleContainer &mc = m_modules[module_name];
//interface::MutexScope ms2(mc.mutex);
mc.module->init();
}
}
@ -112,21 +112,21 @@ struct CState: public State, public interface::Server
return g_server_config.share_path+"/builtin";
}
/*interface::Module* get_module_u(const ss_ &module_name)
interface::Module* get_module(const ss_ &module_name)
{
interface::MutexScope ms(m_modules_mutex);
auto it = m_modules.find(module_name);
if(it == m_modules.end())
return NULL;
return it->second;
return it->second.module;
}
interface::Module* check_module_u(const ss_ &module_name)
interface::Module* check_module(const ss_ &module_name)
{
interface::Module *m = get_module(module_name);
if(m) return m;
throw ModuleNotFoundException(ss_()+"Module not found: "+module_name);
}*/
}
bool has_module(const ss_ &module_name)
{
@ -141,31 +141,31 @@ struct CState: public State, public interface::Server
// Lock modules so that the subscribing one isn't removed asynchronously
interface::MutexScope ms(m_modules_mutex);
// Make sure module is a known instance
ModuleWithMutex *mwm0 = NULL;
ModuleContainer *mc0 = NULL;
ss_ module_name = "(unknown)";
for(auto &pair : m_modules){
ModuleWithMutex &mwm = pair.second;
if(mwm.module == module){
mwm0 = &mwm;
ModuleContainer &mc = pair.second;
if(mc.module == module){
mc0 = &mc;
module_name = pair.first;
break;
}
}
if(mwm0 == nullptr){
if(mc0 == nullptr){
std::cerr<<"sub_event(): Not a known module"<<std::endl;
return;
}
interface::MutexScope ms2(m_event_subs_mutex);
if(m_event_subs.size() <= type + 1)
m_event_subs.resize(type + 1);
sv_<ModuleWithMutex*> &sublist = m_event_subs[type];
if(std::find(sublist.begin(), sublist.end(), mwm0) != sublist.end()){
sv_<ModuleContainer*> &sublist = m_event_subs[type];
if(std::find(sublist.begin(), sublist.end(), mc0) != sublist.end()){
std::cerr<<"sub_event(): Already on list: "<<module_name<<std::endl;
return;
}
std::cerr<<"sub_event(): "<<module_name<<" subscribed to "<<type <<
std::endl;
sublist.push_back(mwm0);
sublist.push_back(mc0);
}
void emit_event(Event event)
@ -179,7 +179,7 @@ struct CState: public State, public interface::Server
{
for(size_t loop_i = 0;; loop_i++){
sv_<Event> event_queue_snapshot;
sv_<sv_<ModuleWithMutex*>> event_subs_snapshot;
sv_<sv_<ModuleContainer*>> event_subs_snapshot;
{
interface::MutexScope ms2(m_event_queue_mutex);
interface::MutexScope ms3(m_event_subs_mutex);
@ -198,16 +198,16 @@ struct CState: public State, public interface::Server
log_d("state", "handle_events(): %zu: No subs", event.type);
continue;
}
sv_<ModuleWithMutex*> &sublist = event_subs_snapshot[event.type];
sv_<ModuleContainer*> &sublist = event_subs_snapshot[event.type];
if(sublist.empty()){
log_d("state", "handle_events(): %zu: No subs", event.type);
continue;
}
log_d("state", "handle_events(): %zu: Handling (%zu handlers)",
event.type, sublist.size());
for(ModuleWithMutex *mwm : sublist){
interface::MutexScope mwm_ms(mwm->mutex);
mwm->module->event(event.type, event.p.get());
for(ModuleContainer *mc : sublist){
//interface::MutexScope mc_ms(mc->mutex);
mc->module->event(event.type, event.p.get());
}
}
}

View File

@ -19,8 +19,8 @@ namespace server
virtual ~State(){}
virtual void load_module(const ss_ &module_name, const ss_ &path) = 0;
virtual void load_modules(const ss_ &path) = 0;
//virtual interface::Module* get_module_u(const ss_ &module_name) = 0;
//virtual interface::Module* check_module_u(const ss_ &module_name) = 0;
virtual interface::Module* get_module(const ss_ &module_name) = 0;
virtual interface::Module* check_module(const ss_ &module_name) = 0;
virtual void sub_event(struct interface::Module *module,
const interface::Event::Type &type) = 0;
virtual void emit_event(interface::Event event) = 0;

View File

@ -13,6 +13,7 @@ struct Module: public interface::Module
interface::Server *m_server;
Module(interface::Server *server):
interface::Module("__loader"),
m_server(server)
{
std::cout<<"__loader construct"<<std::endl;

View File

@ -1,9 +1,11 @@
#include "interface/module.h"
#include "interface/server.h"
#include "interface/event.h"
#include "interface/mutex.h"
#include "test1/include/api.h"
#include "network/include/api.h"
#include <iostream>
//#include <dlfcn.h>
using interface::Event;
@ -11,6 +13,7 @@ namespace test1 {
struct Module: public interface::Module
{
interface::Mutex m_interface_mutex;
interface::Server *m_server;
Event::Type m_EventType_test1_thing;
@ -18,6 +21,7 @@ struct Module: public interface::Module
network::Packet::Type m_NetworkPacketType_dummy_packet = 0;
Module(interface::Server *server):
interface::Module("test1"),
m_server(server),
m_EventType_test1_thing(Event::t("test1:thing"))
{
@ -26,13 +30,25 @@ struct Module: public interface::Module
void init()
{
interface::MutexScope ms(m_interface_mutex);
std::cout<<"test1 init"<<std::endl;
m_server->sub_event(this, Event::t("core:start"));
m_server->sub_event(this, m_EventType_test1_thing);
m_server->sub_event(this, Event::t("network:new_client"));
m_server->sub_event(this, Event::t("network:get_packet_type_resp"));
m_server->emit_event("network:get_packet_type",
new network::Req_get_packet_type("test1:dummy_packet"));
/*MAGIC("network:get_packet_type",
new network::Req_get_packet_type("test1:dummy_packet"),
[&](const network::Resp_get_packet_type &result){
});*/
//network::cfoo();
/*void *m = dlopen("/home/celeron55/softat/buildat/cache/rccpp_build/network.so", RTLD_NOW);
std::cout<<"m="<<m<<std::endl;*/
}
~Module()
@ -42,12 +58,24 @@ struct Module: public interface::Module
void event(const Event::Type &type, const Event::Private *p)
{
interface::MutexScope ms(m_interface_mutex);
EVENT_VOIDN("core:start", on_start)
EVENT_TYPE(m_EventType_test1_thing, on_thing, Thing)
EVENT_TYPEN("network:new_client", on_new_client, network::NewClient)
EVENT_TYPEN("network:get_packet_type_resp", on_get_packet_type_resp,
network::Resp_get_packet_type)
}
void on_start()
{
interface::Module *network_module = m_server->check_module("network");
network::Direct *network_direct =
(network::Direct*)network_module->check_interface();
std::cout<<"Calling network_direct::foo()"<<std::endl;
network_direct->foo();
}
void on_thing(const Thing &thing)
{
std::cout<<"test1.thing: some_data="<<thing.some_data<<std::endl;
@ -57,9 +85,9 @@ struct Module: public interface::Module
{
std::cout<<"test1::on_new_client: id="<<new_client.info.id<<std::endl;
m_server->emit_event("network:send",
new network::Packet(new_client.info.id,
m_NetworkPacketType_dummy_packet, "dummy data"));
auto packet = new network::Packet(new_client.info.id,
m_NetworkPacketType_dummy_packet, "dummy data");
m_server->emit_event("network:send", packet);
}
void on_get_packet_type_resp(const network::Resp_get_packet_type &event)

View File

@ -1,6 +1,7 @@
#include "interface/module.h"
#include "interface/server.h"
#include "interface/event.h"
#include "interface/mutex.h"
#include "test1/include/api.h"
#include <iostream>
@ -10,10 +11,12 @@ namespace test2 {
struct Module: public interface::Module
{
interface::Mutex m_interface_mutex;
interface::Server *m_server;
Event::Type m_EventType_core_start;
Module(interface::Server *server):
interface::Module("test2"),
m_server(server),
m_EventType_core_start(Event::t("core:start"))
{
@ -22,6 +25,8 @@ struct Module: public interface::Module
void init()
{
interface::MutexScope ms(m_interface_mutex);
std::cout<<"test2 init"<<std::endl;
m_server->sub_event(this, m_EventType_core_start);
}
@ -33,6 +38,8 @@ struct Module: public interface::Module
void event(const Event::Type &type, const Event::Private *p)
{
interface::MutexScope ms(m_interface_mutex);
if(type == m_EventType_core_start){
on_start();
}