2024-04-25 16:48:50 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
#include "logo.h"
|
2024-05-16 10:13:43 +08:00
|
|
|
#include "times.h"
|
2024-04-25 16:48:50 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
#include "id_generator.h"
|
|
|
|
|
#include "stellar_priv.h"
|
|
|
|
|
|
|
|
|
|
static const char *log_config_file = "./conf/log.toml";
|
|
|
|
|
static const char *stellar_config_file = "./conf/stellar.toml";
|
|
|
|
|
|
|
|
|
|
static void signal_handler(int signo)
|
|
|
|
|
{
|
|
|
|
|
if (signo == SIGINT)
|
|
|
|
|
{
|
|
|
|
|
STELLAR_LOG_STATE("SIGINT received, notify threads to exit !!!");
|
|
|
|
|
ATOMIC_SET(&runtime->need_exit, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (signo == SIGQUIT)
|
|
|
|
|
{
|
|
|
|
|
STELLAR_LOG_STATE("SIGQUIT received, notify threads to exit !!!");
|
|
|
|
|
ATOMIC_SET(&runtime->need_exit, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (signo == SIGTERM)
|
|
|
|
|
{
|
|
|
|
|
STELLAR_LOG_STATE("SIGTERM received, notify threads to exit !!!");
|
|
|
|
|
ATOMIC_SET(&runtime->need_exit, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (signo == SIGHUP)
|
|
|
|
|
{
|
|
|
|
|
STELLAR_LOG_STATE("SIGHUP received, reload log level !!!");
|
|
|
|
|
log_reload_level(log_config_file);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-15 18:01:24 +08:00
|
|
|
static int all_session_have_freed(void)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < config->io_opts.nr_threads; i++)
|
|
|
|
|
{
|
|
|
|
|
struct session_manager *sess_mgr = runtime->threads[i].sess_mgr;
|
|
|
|
|
struct session_manager_stat *sess_stat = session_manager_stat(sess_mgr);
|
|
|
|
|
|
|
|
|
|
if (ATOMIC_READ(&sess_stat->curr_nr_tcp_sess_used) != 0)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ATOMIC_READ(&sess_stat->curr_nr_udp_sess_used) != 0)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-16 11:52:14 +08:00
|
|
|
static int all_stat_have_output(void)
|
|
|
|
|
{
|
|
|
|
|
static int count = 0;
|
|
|
|
|
if (runtime->stat_last_output_ts == stellar_get_monotonic_time_msec())
|
|
|
|
|
{
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return count == 2;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 16:48:50 +08:00
|
|
|
int main(int argc, char **argv)
|
|
|
|
|
{
|
2024-05-17 16:55:46 +08:00
|
|
|
struct stellar st = {runtime};
|
2024-05-16 10:13:43 +08:00
|
|
|
stellar_update_time_cache();
|
2024-04-25 16:48:50 +08:00
|
|
|
|
|
|
|
|
signal(SIGINT, signal_handler);
|
|
|
|
|
signal(SIGQUIT, signal_handler);
|
|
|
|
|
signal(SIGTERM, signal_handler);
|
|
|
|
|
signal(SIGHUP, signal_handler);
|
|
|
|
|
|
|
|
|
|
if (log_init(log_config_file) != 0)
|
|
|
|
|
{
|
|
|
|
|
STELLAR_LOG_ERROR("unable to init log");
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
|
|
|
|
STELLAR_LOG_STATE("start stellar (version: %s)\n %s", __stellar_version, logo_str);
|
|
|
|
|
|
|
|
|
|
if (stellar_load_config(stellar_config_file, config) != 0)
|
|
|
|
|
{
|
|
|
|
|
STELLAR_LOG_ERROR("unable to load config file");
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
|
|
|
|
stellar_print_config(config);
|
|
|
|
|
STELLAR_LOG_DEBUG("sizeof(struct session) = %lu bytes", sizeof(struct session));
|
|
|
|
|
|
|
|
|
|
if (id_generator_init(config->dev_opts.base, config->dev_opts.offset) != 0)
|
|
|
|
|
{
|
|
|
|
|
STELLAR_LOG_ERROR("unable to init id generator");
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
runtime->stat = stellar_stat_new(config->io_opts.nr_threads);
|
|
|
|
|
if (runtime->stat == NULL)
|
|
|
|
|
{
|
|
|
|
|
STELLAR_LOG_ERROR("unable to create stellar stat");
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
2024-05-17 16:55:46 +08:00
|
|
|
runtime->plug_mgr = plugin_manager_init(&st, "./stellar_plugin/spec.toml");
|
2024-04-25 16:48:50 +08:00
|
|
|
if (runtime->plug_mgr == NULL)
|
|
|
|
|
{
|
|
|
|
|
STELLAR_LOG_ERROR("unable to create plugin manager");
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
runtime->packet_io = packet_io_new(&config->io_opts);
|
|
|
|
|
if (runtime->packet_io == NULL)
|
|
|
|
|
{
|
|
|
|
|
STELLAR_LOG_ERROR("unable to create packet io");
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (stellar_thread_init(runtime, config) != 0)
|
|
|
|
|
{
|
|
|
|
|
STELLAR_LOG_ERROR("unable to init thread context");
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (stellar_thread_run(runtime, config) != 0)
|
|
|
|
|
{
|
|
|
|
|
STELLAR_LOG_ERROR("unable to create worker thread");
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-16 10:13:43 +08:00
|
|
|
runtime->stat_last_output_ts = stellar_get_monotonic_time_msec();
|
2024-04-25 16:48:50 +08:00
|
|
|
while (!ATOMIC_READ(&runtime->need_exit))
|
|
|
|
|
{
|
2024-05-16 10:13:43 +08:00
|
|
|
stellar_update_time_cache();
|
|
|
|
|
if (stellar_get_monotonic_time_msec() - runtime->stat_last_output_ts > 2000)
|
2024-04-25 16:48:50 +08:00
|
|
|
{
|
2024-05-16 10:13:43 +08:00
|
|
|
runtime->stat_last_output_ts = stellar_get_monotonic_time_msec();
|
2024-04-25 16:48:50 +08:00
|
|
|
stellar_stat_output(runtime->stat);
|
|
|
|
|
}
|
|
|
|
|
usleep(1000); // 1ms
|
2024-05-15 11:40:00 +08:00
|
|
|
|
2024-05-15 18:01:24 +08:00
|
|
|
// Only available in dump file mode, automatically exits when all sessions have been released
|
2024-05-16 11:52:14 +08:00
|
|
|
if (packet_io_wait_exit(runtime->packet_io) && all_session_have_freed() && all_stat_have_output())
|
2024-05-15 11:40:00 +08:00
|
|
|
{
|
2024-05-16 11:52:14 +08:00
|
|
|
STELLAR_LOG_STATE("all sessions have been released and all stat have been output, notify threads to exit !!!");
|
2024-05-15 11:40:00 +08:00
|
|
|
ATOMIC_SET(&runtime->need_exit, 1);
|
|
|
|
|
}
|
2024-04-25 16:48:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error_out:
|
|
|
|
|
stellar_thread_join(runtime, config);
|
|
|
|
|
stellar_thread_clean(runtime, config);
|
|
|
|
|
packet_io_free(runtime->packet_io);
|
2024-05-17 16:55:46 +08:00
|
|
|
plugin_manager_exit(runtime->plug_mgr);
|
2024-04-25 16:48:50 +08:00
|
|
|
stellar_stat_free(runtime->stat);
|
|
|
|
|
STELLAR_LOG_STATE("stellar exit !!!\n");
|
|
|
|
|
log_free();
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|