diff --git a/main.rkt b/main.rkt index 1be7cee..7449c53 100644 --- a/main.rkt +++ b/main.rkt @@ -10,4 +10,6 @@ "private/wv-dialog.rkt" ) webview-set-loglevel + webview-version + webview-info ) diff --git a/private/lib/windows/x86_64/rktwebview.dll b/private/lib/windows/x86_64/rktwebview.dll index 3db76d5..86416e8 100644 Binary files a/private/lib/windows/x86_64/rktwebview.dll and b/private/lib/windows/x86_64/rktwebview.dll differ diff --git a/private/lib/windows/x86_64/rktwebview_prg.exe b/private/lib/windows/x86_64/rktwebview_prg.exe index 59331da..6fa294d 100644 Binary files a/private/lib/windows/x86_64/rktwebview_prg.exe and b/private/lib/windows/x86_64/rktwebview_prg.exe differ diff --git a/private/lib/windows/x86_64/rktwebview_test.exe b/private/lib/windows/x86_64/rktwebview_test.exe index 5041230..e260078 100644 Binary files a/private/lib/windows/x86_64/rktwebview_test.exe and b/private/lib/windows/x86_64/rktwebview_test.exe differ diff --git a/private/racket-webview-qt.rkt b/private/racket-webview-qt.rkt index ac3113a..74cd743 100644 --- a/private/racket-webview-qt.rkt +++ b/private/racket-webview-qt.rkt @@ -45,6 +45,7 @@ rkt-webview-messagebox rkt-webview-version rkt-webview-set-loglevel + rkt-webview-info ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -243,6 +244,7 @@ (_enum '(version = -1 event = 2 js-result = 3 + metrics = 4 ) ) ) @@ -267,6 +269,20 @@ ) ) +(define-cstruct _rkt_metrics_t + ([shm_usage _int] + [shm_free_depth _int] + [shm_free_size _int] + [shm_item_depth _int] + [shm_item_size _int] + [shm_item_usage_factor _double] + [open_windows _int] + [function_calls _int] + [events _int] + [log_file _string*/utf-8] + ) + ) + (define-cstruct _rkt_evt_t ([w _int] [evt _pointer] @@ -279,7 +295,7 @@ (define-cstruct _rkt_data_t ([kind _rkt_data_kind] - [data (_union _rkt_version_t _rkt_evt_t _rkt_js_result_t)] + [data (_union _rkt_version_t _rkt_evt_t _rkt_js_result_t _rkt_metrics_t)] ) ) @@ -299,6 +315,10 @@ (define-rktwebview rkt_webview_set_loglevel (_fun _rkt_loglevel_t -> _void)) +;RKTWEBVIEW_EXPORT rkt_data_t *rkt_webview_info(); +(define-rktwebview rkt_webview_info + (_fun -> _rkt_data_t-pointer/null)) + ;RKTWEBVIEW_EXPORT int rkt_webview_events_waiting(); (define-rktwebview rkt_webview_events_waiting (_fun -> _int)) @@ -595,6 +615,22 @@ (define (rkt-webview-set-loglevel l) (rkt_webview_set_loglevel l)) +(define (rkt-webview-info) + (let* ((d (rkt_webview_info)) + (r (union-ref (rkt_data_t-data d) 3)) + ) + (let ((res + (list (list 'shm-usage (rkt_metrics_t-shm_usage r)) + (list 'shm-freelist (rkt_metrics_t-shm_free_depth r) (rkt_metrics_t-shm_free_size r)) + (list 'shm-alloc (rkt_metrics_t-shm_item_depth r) (rkt_metrics_t-shm_item_size r) (rkt_metrics_t-shm_item_usage_factor r)) + (list 'open-windows (rkt_metrics_t-open_windows r)) + (list 'calls (rkt_metrics_t-function_calls r)) + (list 'events (rkt_metrics_t-events r)) + (list 'log-file (rkt_metrics_t-log_file r)) + ))) + (rkt_webview_free_data d) + res))) + (define (rkt-webview-set-ou-token handle token) (rkt_webview_set_ou_token (rkt-wv-win handle) token) #t) diff --git a/private/racket-webview.rkt b/private/racket-webview.rkt index 7d3a17a..5ae9181 100644 --- a/private/racket-webview.rkt +++ b/private/racket-webview.rkt @@ -107,6 +107,7 @@ webview-default-boilerplate-js webview-version + webview-info wv-context-base-url wv-win-window-nr @@ -954,6 +955,9 @@ (cons (list 'webview webview-major webview-minor webview-patch) (rkt-webview-version))) +(define (webview-info) + (rkt-webview-info)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; testing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/rktwebview_qt/main.cpp b/rktwebview_qt/main.cpp index aac9b19..fa81e6a 100644 --- a/rktwebview_qt/main.cpp +++ b/rktwebview_qt/main.cpp @@ -15,17 +15,7 @@ static void free_data(rkt_data_t *d) { - if (d->kind == version) { - free(d); - } else if (d->kind == event) { - free(d->data.event.event); - free(d); - } else if (d->kind == js_result) { - free(d->data.js_result.value); - free(d); - } else { - ERROR1("UNEXPECTED: data kind %d cannot be freed\n", d->kind); - } + do_free_data(d); } class Handler : public QThread @@ -142,6 +132,11 @@ void Handler::run() quit = true; } break; + case CMD_INFO: { + int open_windows = webview_handler->openWindows(); + result_queue->enqueue(open_windows); + } + break; case CMD_HANDLE_IS_VALID: { int wv = data_obj["wv"].toInt(); bool oke = webview_handler->rktValid(wv); diff --git a/rktwebview_qt/rkt_protocol.h b/rktwebview_qt/rkt_protocol.h index 663bbc3..b1c3082 100644 --- a/rktwebview_qt/rkt_protocol.h +++ b/rktwebview_qt/rkt_protocol.h @@ -27,6 +27,7 @@ #define CMD_SET_OU_TOKEN 24 // arguments: wv: int, token: string -> result_t: int #define CMD_MSG_BOX 25 // arguments: wv: int, title:string, message: string, submessage: string, type:int -> result_t: int #define CMD_SET_LOGLEVEL 26 // arguments: ll: int +#define CMD_INFO 27 // arguments: none #define RESULT_QUIT 36379 diff --git a/rktwebview_qt/rktwebview.cpp b/rktwebview_qt/rktwebview.cpp index cb267f1..983593e 100644 --- a/rktwebview_qt/rktwebview.cpp +++ b/rktwebview_qt/rktwebview.cpp @@ -48,6 +48,9 @@ typedef struct { bool rkt_webview_prg_started; bool valid; + int function_calls; + int events; + std::string log_file; } Handle_t; Handle_t *handler = nullptr; @@ -98,6 +101,7 @@ bool runRktWebview(Handle_t *handler) if (td == nullptr) { td = "C:\\"; } std::string tmpdir = td; std::string logfile = tmpdir + "\\" + "rktwebview.log"; //handler->name + ".log"; + handler->log_file = logfile; SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); @@ -105,10 +109,10 @@ bool runRktWebview(Handle_t *handler) sa.bInheritHandle = TRUE; HANDLE h = CreateFile(logfile.c_str(), - 0, //FILE_APPEND_DATA, + FILE_WRITE_DATA, //FILE_APPEND_DATA, FILE_SHARE_WRITE | FILE_SHARE_READ, &sa, - OPEN_ALWAYS, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); @@ -145,6 +149,7 @@ bool runRktWebview(Handle_t *handler) const char *homedir = pw->pw_dir; std::string log_file = std::string(homedir) + "/.racket-webview.log"; + handler->log_file = log_file; posix_spawn_file_actions_t action; posix_spawn_file_actions_init(&action); @@ -174,25 +179,6 @@ void rkt_webview_cleanup() // So we would need to cleanup at exit of racket/drracket. // Cleaning up when exiting the current custodian is not enough. - /* - QApplication *app = handler->app(); - if (app != nullptr) { - // testing with #:custodian (current-custodian) - QTimer t; - QObject::connect(&t, &QTimer::timeout, app, [app]() { - fprintf(stderr, "Quitting\n"); - app->quit(); - }); - t.setSingleShot(true); - t.start(250); - fprintf(stderr, "Executing app\n"); - app->exec(); - fprintf(stderr, "App exited\n"); - delete handler; - handler = nullptr; - } - */ - if (handler->valid) { INFO0("Sending quit message\n"); handler->command_queue->enqueue(CMD_QUIT); @@ -240,6 +226,8 @@ void rkt_webview_init() handler = new Handle_t; handler->valid = true; handler->name = buf; + handler->function_calls = 0; + handler->events = 0; handler->shm_size = SHM_SIZE; handler->shm = new Shm(handler->name.data(), handler->shm_size, true); @@ -253,6 +241,8 @@ void rkt_webview_init() handler->rkt_webview_prg_started = runRktWebview(handler); if (!handler->rkt_webview_prg_started) { handler->valid = false; } #endif + } else { + handler->function_calls++; } } @@ -280,6 +270,7 @@ static inline bool validHandle() #define FAIL_WV if (!validHandle()) { return 0; } #define NOOP_HANDLE if (!validHandle()) { return; } #define FAIL_CALL_JS if (!validHandle()) { return nullptr; } +#define FAIL_INFO FAIL_CALL_JS rkt_wv_context_t rkt_webview_new_context(const char *boilerplate_js, const char *optional_server_cert_pem) { @@ -512,19 +503,7 @@ void rkt_webview_set_ou_token(rktwebview_t wv, const char *token) void rkt_webview_free_data(rkt_data_t *d) { - if (d == nullptr) { return; } - - if (d->kind == version) { - free(d); - } else if (d->kind == event) { - free(d->data.event.event); - free(d); - } else if (d->kind == js_result) { - free(d->data.js_result.value); - free(d); - } else { - ERROR1("UNEXPECTED: data kind %d cannot be freed\n", d->kind); - } + do_free_data(d); } rkt_data_t *rkt_webview_version() @@ -557,6 +536,7 @@ rkt_data_t *rkt_webview_get_event() rkt_data_t *d = reinterpret_cast(malloc(sizeof(rkt_data_t))); d->kind = rkt_data_kind_t::event; + handler->events += 1; size_t ds = data.size(); d->data.event.event = reinterpret_cast(malloc(ds + 1)); memcpy(d->data.event.event, data.c_str(), ds); @@ -581,3 +561,33 @@ void rkt_webview_env(const char *env_cmds[]) } } + +rkt_data_t *rkt_webview_info() +{ + rkt_webview_init(); + FAIL_INFO + + rkt_data_t *d = new rkt_data_t(); + d->kind = metrics; + + handler->shm->info(d->data.metrics.shm_usage, + d->data.metrics.shm_free_depth, + d->data.metrics.shm_free_size, + d->data.metrics.shm_item_depth, + d->data.metrics.shm_item_size, + d->data.metrics.shm_item_usage_factor); + + JSON j; + handler->command_queue->enqueue(CMD_INFO, j.dump()); + + int open_windows_result; + std::string none; + handler->command_result_queue->dequeue(open_windows_result, none, true); + + d->data.metrics.open_windows = open_windows_result; + d->data.metrics.function_calls = handler->function_calls; + d->data.metrics.log_file = strdup(handler->log_file.c_str()); + d->data.metrics.events = handler->events + handler->event_queue->depth(); + + return d; +} diff --git a/rktwebview_qt/rktwebview.h b/rktwebview_qt/rktwebview.h index c969e5f..0fd9da7 100644 --- a/rktwebview_qt/rktwebview.h +++ b/rktwebview_qt/rktwebview.h @@ -14,7 +14,7 @@ RKTWEBVIEW_EXPORT void rkt_webview_env(const char *env_cmds[]); RKTWEBVIEW_EXPORT void rkt_webview_init(); RKTWEBVIEW_EXPORT void rkt_webview_cleanup(); RKTWEBVIEW_EXPORT void rkt_webview_set_loglevel(rkt_webview_loglevel_t l); -//RKTWEBVIEW_EXPORT void rkt_webview_process_events(int for_ms); +RKTWEBVIEW_EXPORT rkt_data_t *rkt_webview_info(); RKTWEBVIEW_EXPORT void rkt_webview_free_data(rkt_data_t *d); RKTWEBVIEW_EXPORT rkt_data_t *rkt_webview_version(); diff --git a/rktwebview_qt/rktwebview_qt.cpp b/rktwebview_qt/rktwebview_qt.cpp index 04ecaeb..64044ac 100644 --- a/rktwebview_qt/rktwebview_qt.cpp +++ b/rktwebview_qt/rktwebview_qt.cpp @@ -147,7 +147,7 @@ void Rktwebview_qt::processCommand(Command *cmd) w->show(); while(!w->windowCreated()) { - doEvents(); + _app->processEvents(); } cmd->result = id; @@ -156,7 +156,6 @@ void Rktwebview_qt::processCommand(Command *cmd) } break; case COMMAND_CLOSE: { - doEvents(); int wv = cmd->args[0].toInt(); if (_views.contains(wv)) { WebviewWindow *w= _views[wv]; @@ -164,7 +163,7 @@ void Rktwebview_qt::processCommand(Command *cmd) w->closeView(); cmd->result = true; while(w->isVisible()) { - doEvents(); + _app->processEvents(); } _view_js_callbacks.remove(wv); delete w; @@ -175,7 +174,6 @@ void Rktwebview_qt::processCommand(Command *cmd) } break; case COMMAND_SET_OU_TOKEN: { - doEvents(); int wv = cmd->args[0].toInt(); QString ou_token = cmd->args[1].toString(); if (_views.contains(wv)) { @@ -189,7 +187,6 @@ void Rktwebview_qt::processCommand(Command *cmd) } break; case COMMAND_SET_URL: { - doEvents(); int wv = cmd->args[0].toInt(); QString url = cmd->args[1].toString(); if (_views.contains(wv)) { @@ -205,7 +202,6 @@ void Rktwebview_qt::processCommand(Command *cmd) } break; case COMMAND_SET_HTML: { - doEvents(); int wv = cmd->args[0].toInt(); QString html = cmd->args[1].toString(); if (_views.contains(wv)) { @@ -220,7 +216,6 @@ void Rktwebview_qt::processCommand(Command *cmd) } break; case COMMAND_SET_TITLE: { - doEvents(); int wv = cmd->args[0].toInt(); QString title = cmd->args[1].toString(); if (_views.contains(wv)) { @@ -234,7 +229,6 @@ void Rktwebview_qt::processCommand(Command *cmd) } break; case COMMAND_RUN_JS: { - doEvents(); int wv = cmd->args[0].toInt(); QString js = cmd->args[1].toString(); if (_views.contains(wv)) { @@ -249,7 +243,6 @@ void Rktwebview_qt::processCommand(Command *cmd) } break; case COMMAND_CALL_JS: { - doEvents(); int wv = cmd->args[0].toInt(); QString js = cmd->args[1].toString(); if (_views.contains(wv)) { @@ -263,7 +256,6 @@ void Rktwebview_qt::processCommand(Command *cmd) } break; case COMMAND_DEV_TOOLS: { - doEvents(); int wv = cmd->args[0].toInt(); if (_views.contains(wv)) { WebviewWindow *w = _views[wv]; @@ -282,7 +274,6 @@ void Rktwebview_qt::processCommand(Command *cmd) case COMMAND_MIN_WIN: case COMMAND_SHOW_NORMAL_WIN: { - doEvents(); int wv = cmd->args[0].toInt(); if (_views.contains(wv)) { WebviewWindow *w = _views[wv]; @@ -308,7 +299,6 @@ void Rktwebview_qt::processCommand(Command *cmd) break; case COMMAND_WINDOW_STATUS: { - doEvents(); int wv = cmd->args[0].toInt(); window_state_t ws = window_state_t::invalid; if (_views.contains(wv)) { @@ -336,7 +326,6 @@ void Rktwebview_qt::processCommand(Command *cmd) } break; case COMMAND_MOVE: { - doEvents(); int wv = cmd->args[0].toInt(); int x = cmd->args[1].toInt(); int y = cmd->args[2].toInt(); @@ -345,7 +334,7 @@ void Rktwebview_qt::processCommand(Command *cmd) int move_count = w->moveCount(); w->move(x, y); while (w->moveCount() == move_count) { - doEvents(); + _app->processEvents(); } cmd->result = true; } else { @@ -355,7 +344,6 @@ void Rktwebview_qt::processCommand(Command *cmd) } break; case COMMAND_RESIZE: { - doEvents(); int wv = cmd->args[0].toInt(); int width = cmd->args[1].toInt(); int height = cmd->args[2].toInt(); @@ -364,7 +352,7 @@ void Rktwebview_qt::processCommand(Command *cmd) int resize_count = w->resizeCount(); w->resize(width, height); while (w->resizeCount() == resize_count) { - doEvents(); + _app->processEvents(); } cmd->result = true; } else { @@ -652,6 +640,11 @@ window_state_t Rktwebview_qt::rktWindowState(rktwebview_t w) return ws; } +int Rktwebview_qt::openWindows() +{ + return _views.size(); +} + void Rktwebview_qt::rktQuit() { Command c(COMMAND_QUIT); @@ -730,9 +723,7 @@ result_t Rktwebview_qt::rktChooseDir(rktwebview_t w, const char *title, const ch c.args.push_back(s_base_dir); postCommand(&c); - while(!c.done) { - doEvents(); - } + while(!c.done) { doEvents(); } bool r = c.result.toBool(); return r ? result_t::oke : result_t::resize_failed; @@ -750,9 +741,7 @@ result_t Rktwebview_qt::rktFileOpen(rktwebview_t w, const char *title, const cha c.args.push_back(s_pe); postCommand(&c); - while(!c.done) { - doEvents(); - } + while(!c.done) { doEvents(); } bool r = c.result.toBool(); return r ? result_t::oke : result_t::resize_failed; @@ -770,9 +759,7 @@ result_t Rktwebview_qt::rktFileSave(rktwebview_t w, const char *title, const cha c.args.push_back(s_pe); postCommand(&c); - while(!c.done) { - doEvents(); - } + while(!c.done) { doEvents(); } bool r = c.result.toBool(); return r ? result_t::oke : result_t::resize_failed; @@ -859,9 +846,7 @@ result_t Rktwebview_qt::rktMessageBox(rktwebview_t w, const char *title, const c postCommand(&c); - while(!c.done) { - doEvents(); - } + while(!c.done) { doEvents(); } bool r = c.result.toBool(); return r ? result_t::oke : result_t::failed; diff --git a/rktwebview_qt/rktwebview_qt.h b/rktwebview_qt/rktwebview_qt.h index e83de37..16e5599 100644 --- a/rktwebview_qt/rktwebview_qt.h +++ b/rktwebview_qt/rktwebview_qt.h @@ -115,6 +115,9 @@ public: void pageLoaded(rktwebview_t w, bool ok); void onPageLoad(rktwebview_t w); +public: + int openWindows(); + public: void triggerEvent(rktwebview_t wv, const QString &msg); void triggerEvent(rktwebview_t wv, const EventContainer &e); diff --git a/rktwebview_qt/rktwebview_test.cpp b/rktwebview_qt/rktwebview_test.cpp index 9075755..681f84d 100644 --- a/rktwebview_qt/rktwebview_test.cpp +++ b/rktwebview_qt/rktwebview_test.cpp @@ -34,10 +34,16 @@ int main(int argc, char *argv[]) int wv = rkt_webview_create(context, 0); + rkt_data_t *d = rkt_webview_info(); + rkt_webview_free_data(d); + rkt_webview_move(wv, 100, 200); rkt_webview_resize(wv, 800, 600); rkt_webview_set_url(wv, "https://wikipedia.org"); + d = rkt_webview_info(); + rkt_webview_free_data(d); + while(rkt_webview_events_waiting() > 0) { rkt_data_t *d = rkt_webview_get_event(); rkt_webview_free_data(d); @@ -47,8 +53,13 @@ int main(int argc, char *argv[]) #else sleep(10); #endif + d = rkt_webview_info(); + rkt_webview_free_data(d); rkt_webview_close(wv); + d = rkt_webview_info(); + rkt_webview_free_data(d); + rkt_webview_cleanup(); } diff --git a/rktwebview_qt/rktwebview_types.h b/rktwebview_qt/rktwebview_types.h index a1edcc8..fcac80f 100644 --- a/rktwebview_qt/rktwebview_types.h +++ b/rktwebview_qt/rktwebview_types.h @@ -71,10 +71,24 @@ typedef struct { int api_patch; } rkt_version_t; +typedef struct { + int shm_usage; + int shm_free_depth; + int shm_free_size; + int shm_item_depth; + int shm_item_size; + double shm_item_usage_factor; + int open_windows; + int function_calls; + int events; + char *log_file; +} rkt_metrics_t; + typedef enum { version = 1, event = 2, - js_result = 3 + js_result = 3, + metrics = 4 } rkt_data_kind_t; typedef struct { @@ -83,6 +97,7 @@ typedef struct { rkt_version_t version; rkt_event_t event; rkt_js_result_t js_result; + rkt_metrics_t metrics; } data; } rkt_data_t; diff --git a/rktwebview_qt/shm.cpp b/rktwebview_qt/shm.cpp index 74c3fe8..d4a6d5d 100644 --- a/rktwebview_qt/shm.cpp +++ b/rktwebview_qt/shm.cpp @@ -11,8 +11,8 @@ typedef struct __shm_item__ { ShmPlace next; ShmPlace prev; - size_t size; - + int size; + int alloc_size; } ShmItem; @@ -69,6 +69,40 @@ public: return _mem + place; } +public: + void info(int &usage, int &free_depth, int &free_size, int &item_depth, int &item_size, double &usage_factor) { + enterCritical(); + + usage = *_used; + + auto count = [this](ShmPlace *l, int &depth, int &size, double &factor) { + depth = 0; + size = 0; + int alloc_size = 0; + ShmPlace p = *l; + while (p != SHM_NULL) { + //p -= sizeof(ShmItem); + ShmItem *i; + ref(p, &i); + size += i->size; + alloc_size += i->alloc_size; + depth += 1; + p = i->next; + } + if (size > 0) { + factor = (static_cast(alloc_size) / static_cast(size)); + } else { + factor = 1.0; + } + }; + + double x; + count(_free_list, free_depth, free_size, x); + count(_first, item_depth, item_size, usage_factor); + + leaveCritical(); + } + public: int alloc(size_t bytes) { enterCritical(); @@ -104,6 +138,7 @@ public: first_i->prev = p_i; } i->prev = SHM_NULL; + i->alloc_size = bytes; *_first = p_i; place = p_i + sizeof(ShmItem); @@ -118,6 +153,7 @@ public: *_used = u; i->prev = SHM_NULL; i->size = bytes; + i->alloc_size = bytes; i->next = *_first; if (*_first != SHM_NULL) { ShmItem *first_i; @@ -574,6 +610,11 @@ void *Shm::ref(int place) return _shm_api->ref(place); } +void Shm::info(int &usage, int &free_depth, int &free_size, int &item_depth, int &item_size, double &usage_factor) +{ + _shm_api->info(usage, free_depth, free_size, item_depth, item_size, usage_factor); +} + void Shm::lock() { _shm_api->enterCritical(); diff --git a/rktwebview_qt/shm.h b/rktwebview_qt/shm.h index 8de1d08..32b9fc9 100644 --- a/rktwebview_qt/shm.h +++ b/rktwebview_qt/shm.h @@ -52,6 +52,9 @@ public: public: void *ref(int place); +public: + void info(int &usage, int &free_depth, int &free_size, int &item_depth, int &item_size, double &usage_factor); + public: Shm(const char *name, size_t bytes, bool owner); ~Shm(); diff --git a/rktwebview_qt/utils.h b/rktwebview_qt/utils.h index b7e42d6..d7ccabc 100644 --- a/rktwebview_qt/utils.h +++ b/rktwebview_qt/utils.h @@ -2,6 +2,7 @@ #define UTILS_H #include +#include "rktwebview_types.h" inline std::string basedir(const std::string &path) { @@ -56,4 +57,24 @@ const char *logIndicator(int l); #define INFO2(msg, a, b) MKL2(LOG_INFO, msg, a, b) #define DEBUG2(msg, a, b) MKL2(LOG_DEBUG, msg, a, b) +inline void do_free_data(rkt_data_t *d) +{ + if (d == nullptr) { return; } + + if (d->kind == version) { + free(d); + } else if (d->kind == metrics) { + free(d->data.metrics.log_file); + free(d); + } else if (d->kind == event) { + free(d->data.event.event); + free(d); + } else if (d->kind == js_result) { + free(d->data.js_result.value); + free(d); + } else { + ERROR1("UNEXPECTED: data kind %d cannot be freed\n", d->kind); + } +} + #endif // UTILS_H