Ferenc Szontágh
2024-06-25 4f0f4a9d9d2f1a1430839121682c514be22cc641
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "Server.h"
#include <iostream>
#include <csignal>
 
// Initialize the static instance pointer
Server* Server::instance = nullptr;
 
Server::Server() : reloadConfigFlag(false) {
    instance = this; // Set the instance pointer
    signal(SIGUSR1, Server::handleSignal);
    if (!config.loadFromFile("config.json")) {
        std::cerr << "Failed to load config.json" << std::endl;
    }
    loadPlugins();
    for (int i = 0; i < 4; ++i) {
        threadPool.emplace_back(std::make_unique<std::thread>(&Server::handleIPC, this));
    }
}
 
Server::~Server() {
    for (auto& handle : pluginHandles) {
        dlclose(handle);
    }
}
 
Server& Server::getInstance() {
    return *instance;
}
 
void Server::run() {
    mainLoop();
}
 
void Server::reloadConfig() {
    if (config.loadFromFile("config.json")) {
        std::cout << "Configuration reloaded." << std::endl;
        for (auto& plugin : plugins) {
            plugin->updateConfig(config.getConfig());
        }
    } else {
        std::cerr << "Failed to reload configuration." << std::endl;
    }
}
 
void Server::loadPlugins() {
    const char* pluginPath = "./plugins/libSamplePlugin.so";
    void* handle = dlopen(pluginPath, RTLD_LAZY);
    if (!handle) {
        std::cerr << "Cannot open library: " << dlerror() << '\n';
        return;
    }
    pluginHandles.push_back(handle);
 
    typedef IPlugin* (*create_t)();
    create_t create_plugin = (create_t)dlsym(handle, "create");
    const char* dlsym_error = dlerror();
    if (dlsym_error) {
        std::cerr << "Cannot load symbol create: " << dlsym_error << '\n';
        return;
    }
 
    std::shared_ptr<IPlugin> plugin(create_plugin());
    plugins.push_back(plugin);
    ipc.registerHandler(plugin);
    plugin->updateConfig(config.getConfig()); // Forward the config to the plugin
}
 
void Server::mainLoop() {
    while (true) {
        if (reloadConfigFlag.load()) {
            reloadConfig();
            reloadConfigFlag.store(false);
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}
 
void Server::handleIPC() {
    while (true) {
        auto message = ipc.receiveMessage();
        if (message.has_value()) {
            for (auto& plugin : plugins) {
                plugin->handleMessage(message.value());
            }
        }
    }
}
 
void Server::handleSignal(int signal) {
    if (signal == SIGUSR1) {
        std::cout << "Received signal to reload configuration." << std::endl;
        Server::getInstance().reloadConfigFlag.store(true);
    }
}