Alive thread implemented

This commit is contained in:
2026-04-11 09:50:59 +02:00
parent 8e5381fda2
commit 52aa0cac10
10 changed files with 215 additions and 31 deletions

View File

@@ -28,6 +28,7 @@
#define COMMAND_SLOT 1
#define COMMAND_RESULT_SLOT 2
#define EVENT_SLOT 3
#define ALIVE_SLOT 4
//#define DEBUG
@@ -42,6 +43,7 @@ typedef struct {
ShmQueue *command_queue;
ShmQueue *command_result_queue;
ShmQueue *event_queue;
ShmQueue *alive_queue;
#ifdef _WIN32
HANDLE rkt_webview_prg_pid;
#else
@@ -59,6 +61,8 @@ typedef struct {
std::thread *guard_thread;
bool guard_go_on;
bool alive_go_on;
std::thread *alive_thread;
} Handle_t;
Handle_t *handler = nullptr;
@@ -96,11 +100,14 @@ bool runRktWebview(Handle_t *handler)
char command_slot[10];
char command_result_slot[10];
char event_slot[10];
char alive_slot[10];
sprintf(shm_size_str, "%d", static_cast<int>(handler->shm_size));
sprintf(command_slot, "%d", COMMAND_SLOT);
sprintf(command_result_slot, "%d", COMMAND_RESULT_SLOT);
sprintf(event_slot, "%d", EVENT_SLOT);
sprintf(alive_slot, "%d", ALIVE_SLOT);
// run rktwebview_prg using the environment variable RKT_WEBVIEW_PRG
#ifdef _WIN32
@@ -137,7 +144,7 @@ bool runRktWebview(Handle_t *handler)
DWORD flags = CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS;
std::string cmdargs = std::string("") + handler->name + " " + shm_size_str + " " + command_slot + " " + command_result_slot + " " + event_slot;
std::string cmdargs = std::string("") + handler->name + " " + shm_size_str + " " + command_slot + " " + command_result_slot + " " + event_slot + " " + alive_slot;
std::string exe = std::string(rkt_webview_prg_path);
std::string dir = basedir(exe);
@@ -178,13 +185,16 @@ bool runRktWebview(Handle_t *handler)
/////////////////////////////////////////////////////////////////////
#define EVT_GUARD_STOP -93273
#define WAIT_ON_EVENT_MS (10 * 1000)
#define ALIVE_MESSAGE_INTERVAL_S 5 // Should be smaller than 10 seconds
#define MAX_WAIT_RESULT (10 * 1000) // Maximum wait in milliseconds for a result
void rkt_evt_guard(void)
{
while(handler->guard_go_on) {
int wv;
std::string data;
if (handler->event_queue->dequeue(wv, data, true)) {
if (handler->event_queue->dequeue(wv, data, WAIT_ON_EVENT_MS)) {
if (wv != EVT_GUARD_STOP) {
handler->evt_queue->enqueue(wv, data);
handler->evt_cb(1);
@@ -193,6 +203,27 @@ void rkt_evt_guard(void)
}
}
void queue_alive_message()
{
int seconds = 0;
int ping = 0;
DEBUG0("Starting queue_alive thread\n");
while(handler->alive_go_on) {
std::this_thread::sleep_for(std::chrono::seconds(1)); // one second
seconds += 1;
//DEBUG2("seconds = %d, %d\n", seconds, ALIVE_MESSAGE_INTERVAL_S);
if (seconds >= ALIVE_MESSAGE_INTERVAL_S && handler->alive_go_on) {
seconds = 0;
++ping;
DEBUG1("Pinging with %d\n", ping);
handler->alive_queue->enqueue(ping);
if (ping > 1000000000) { ping = 0; }
}
}
handler->alive_queue->enqueue(CMD_ALIVE_QUIT);
}
void rkt_webview_cleanup()
{
if (handler != nullptr) {
@@ -212,15 +243,22 @@ void rkt_webview_cleanup()
handler->guard_thread = nullptr;
}
handler->alive_go_on = false;
handler->alive_thread->join();
delete handler->alive_thread;
handler->alive_thread = nullptr;
INFO0("Sending quit message\n");
handler->command_queue->enqueue(CMD_QUIT);
INFO0("Message sent\n");
bool stopped = false;
while(!stopped) {
int cmd;
int cmd = -1;
std::string s;
INFO0("Getting result of quit message\n");
handler->command_result_queue->dequeue(cmd, s, true);
if (!handler->command_result_queue->dequeue(cmd, s, MAX_WAIT_RESULT)) {
ERROR0("Other side has probably stopped working, no result on quit message\n");
}
INFO1("got %d\n", cmd);
if (cmd == RESULT_QUIT) {
stopped = true;
@@ -228,16 +266,23 @@ void rkt_webview_cleanup()
}
}
// Cleanup shared memory
delete handler->event_queue;
delete handler->command_result_queue;
delete handler->command_queue;
delete handler->alive_queue;
delete handler->shm;
// Cleanup Memory Queue
delete handler->evt_queue;
// Cleanup Handler
delete handler;
handler = nullptr;
}
}
void rkt_webview_init()
{
if (handler == nullptr) {
@@ -269,6 +314,8 @@ void rkt_webview_init()
handler->command_result_queue = new ShmQueue(handler->shm, COMMAND_RESULT_SLOT, true);
handler->event_queue = new ShmQueue(handler->shm, EVENT_SLOT, true);
handler->alive_queue = new ShmQueue(handler->shm, ALIVE_SLOT, true);
// Start rktwebview_prg application with the right information
#ifndef DEBUG
handler->rkt_webview_prg_started = runRktWebview(handler);
@@ -278,6 +325,10 @@ void rkt_webview_init()
handler->evt_cb = nullptr;
handler->evt_queue = new MemQueue();
handler->guard_go_on = false;
handler->alive_go_on = true;
handler->alive_thread = new std::thread(queue_alive_message);
} else {
handler->function_calls++;
}
@@ -339,7 +390,7 @@ rkt_wv_context_t rkt_webview_new_context(const char *boilerplate_js, const char
int result;
std::string json_result;
handler->command_result_queue->dequeue(result, json_result, true);
while (!handler->command_result_queue->dequeue(result, json_result, MAX_WAIT_RESULT)) {}
return result;
}
@@ -356,7 +407,7 @@ int rkt_webview_create(rkt_wv_context_t context, rktwebview_t parent)
int result;
std::string json_result;
handler->command_result_queue->dequeue(result, json_result, true);
while (!handler->command_result_queue->dequeue(result, json_result, MAX_WAIT_RESULT)) {}
return result;
}
@@ -383,7 +434,7 @@ void rkt_webview_close(rktwebview_t wv)
handler->command_queue->enqueue(cmd, j.dump()); \
int result; \
std::string json_result; \
handler->command_result_queue->dequeue(result, json_result, true); \
while (!handler->command_result_queue->dequeue(result, json_result, MAX_WAIT_RESULT)) {} \
result_t r = static_cast<result_t>(result); \
return r;
@@ -427,7 +478,7 @@ rkt_data_t *rkt_webview_call_js(rktwebview_t wv, const char *js)
int result;
std::string json_result;
handler->command_result_queue->dequeue(result, json_result, true);
while (!handler->command_result_queue->dequeue(result, json_result, MAX_WAIT_RESULT)) {}
rkt_data_t *r = new rkt_data_t();
r->kind = rkt_data_kind_t::js_result;
@@ -501,8 +552,9 @@ result_t rkt_webview_show_normal(rktwebview_t w)
void rkt_webview_set_loglevel(rkt_webview_loglevel_t l)
{
setLogLevel(l); // library side
auto f = [l]() {
CMDRES0(CMD_SET_LOGLEVEL, static_cast<int>(l));
CMDRES0(CMD_SET_LOGLEVEL, static_cast<int>(l)); // webview process side
};
f();
}
@@ -605,7 +657,7 @@ rkt_data_t *rkt_webview_get_event()
} else {
int wv;
std::string data;
if (handler->event_queue->dequeue(wv, data, false)) {
if (handler->event_queue->dequeue(wv, data, 0)) {
//fprintf(stderr, "got event %d %s\n", wv, data.c_str());
rkt_data_t *d = reinterpret_cast<rkt_data_t *>(malloc(sizeof(rkt_data_t)));
d->kind = rkt_data_kind_t::event;
@@ -657,7 +709,7 @@ rkt_data_t *rkt_webview_info()
int open_windows_result;
std::string none;
handler->command_result_queue->dequeue(open_windows_result, none, true);
while (!handler->command_result_queue->dequeue(open_windows_result, none, MAX_WAIT_RESULT)) {}
d->data.metrics.open_windows = open_windows_result;
d->data.metrics.function_calls = handler->function_calls;