fx: start implementing global data cleanup

This commit is contained in:
2026-06-20 15:24:23 +01:00
parent f093c0fb6e
commit 32d4d0abf2
3 changed files with 127 additions and 31 deletions
+39
View File
@@ -0,0 +1,39 @@
#include <fx/global.h>
#include <fx/thread.h>
#include <stdlib.h>
#include <string.h>
static fx_queue globals = FX_QUEUE_INIT;
static fx_mutex globals_lock = FX_MUTEX_INIT;
struct global {
fx_object *g_object;
fx_queue_entry g_entry;
};
void fx_cleanup_global(void)
{
fx_queue_entry *cur = fx_queue_first(&globals);
while (cur) {
struct global *global = fx_unbox(struct global, cur, g_entry);
cur = fx_queue_next(cur);
fx_object_unref(global->g_object);
free(global);
}
}
void fx_register_global(fx_object *obj)
{
struct global *global = malloc(sizeof *global);
if (!global) {
return;
}
memset(global, 0x0, sizeof *global);
global->g_object = fx_object_ref(obj);
fx_mutex_lock(&globals_lock);
fx_queue_push_back(&globals, &global->g_entry);
fx_mutex_unlock(&globals_lock);
}
+10
View File
@@ -0,0 +1,10 @@
#ifndef FX_GLOBAL_H_
#define FX_GLOBAL_H_
#include <fx/misc.h>
#include <fx/object.h>
FX_API void fx_register_global(fx_object *obj);
FX_API void fx_cleanup_global(void);
#endif
+78 -31
View File
@@ -5,6 +5,7 @@
#include <fx/bst.h>
#include <fx/endian.h>
#include <fx/global.h>
#include <fx/int.h>
#include <fx/object.h>
#include <fx/reflection/function.h>
@@ -16,6 +17,7 @@
static struct fx_bst type_idmap = FX_BST_INIT;
static struct fx_namemap type_namemap = FX_NAMEMAP_INIT;
static fx_once runtime_cleanup_init = FX_ONCE_INIT;
static union fx_type_id zero_id = {0};
struct type_init_ctx {
@@ -23,6 +25,37 @@ struct type_init_ctx {
size_t ctx_instance_offset;
};
static fx_result fx_type_destroy(struct fx_type_info *info);
static void type_namemap_cleanup(struct fx_namemap_entry *entry)
{
struct fx_type_info *ty
= fx_unbox(struct fx_type_info, entry, ty_namemap_entry);
fx_type_destroy(ty);
}
static void function_namemap_cleanup(struct fx_namemap_entry *entry)
{
struct fx_type_function *func
= fx_unbox(struct fx_type_function, entry, f_entry);
fx_function_unref(func->f_func);
free(func);
}
static void property_namemap_cleanup(struct fx_namemap_entry *entry)
{
struct fx_type_property *prop
= fx_unbox(struct fx_type_property, entry, p_entry);
fx_property_unref(prop->p_prop);
free(prop);
}
static void runtime_cleanup(void)
{
fx_cleanup_global();
// fx_namemap_cleanup(&type_namemap, type_namemap_cleanup);
}
static inline int type_info_compare(
const struct fx_type_info *a,
const struct fx_type_info *b)
@@ -56,10 +89,8 @@ static struct fx_type_info *get_type(
{
fx_bst_node *cur = tree->bst_root;
while (cur) {
struct fx_type_info *cur_node = fx_unbox(
struct fx_type_info,
cur,
ty_idmap_node);
struct fx_type_info *cur_node
= fx_unbox(struct fx_type_info, cur, ty_idmap_node);
int cmp = fx_type_id_compare(key, &cur_node->ty_id);
if (cmp > 0) {
@@ -80,10 +111,8 @@ struct fx_type_component *fx_type_get_component(
{
fx_bst_node *cur = tree->bst_root;
while (cur) {
struct fx_type_component *cur_node = fx_unbox(
struct fx_type_component,
cur,
c_node);
struct fx_type_component *cur_node
= fx_unbox(struct fx_type_component, cur, c_node);
int cmp = fx_type_id_compare(key, &cur_node->c_type->ty_id);
if (cmp > 0) {
@@ -151,16 +180,14 @@ static fx_result locate_interface(
struct fx_type_info *dest,
struct type_init_ctx *init_ctx)
{
struct fx_type_component *interface_comp = fx_type_get_component(
&dest->ty_components,
interface_id);
struct fx_type_component *interface_comp
= fx_type_get_component(&dest->ty_components, interface_id);
if (interface_comp) {
return FX_RESULT_SUCCESS;
}
struct fx_type_info *interface_reg = get_type(
&type_idmap,
interface_id);
struct fx_type_info *interface_reg
= get_type(&type_idmap, interface_id);
if (!interface_reg) {
return FX_RESULT_ERR(NO_ENTRY);
}
@@ -227,9 +254,8 @@ static fx_result find_type_components(struct fx_type_info *type)
}
while (1) {
struct fx_type_info *dep_class = get_type(
&type_idmap,
current_id);
struct fx_type_info *dep_class
= get_type(&type_idmap, current_id);
if (!dep_class) {
return FX_RESULT_ERR(NO_ENTRY);
}
@@ -302,6 +328,10 @@ static bool type_has_base_class(struct fx_type_info *info)
fx_result fx_type_register(struct fx_type_info *info)
{
if (fx_init_once(&runtime_cleanup_init)) {
atexit(runtime_cleanup);
}
if (!type_has_base_class(info)) {
fx_type_id_copy(FX_TYPE_OBJECT, &info->ty_parent_id);
}
@@ -340,12 +370,34 @@ fx_result fx_type_register(struct fx_type_info *info)
return FX_RESULT_SUCCESS;
}
static fx_result fx_type_destroy(struct fx_type_info *info)
{
info->ty_category = FX_TYPE_CLASS;
union fx_type_id metatype = {0};
fx_bst_node *cur = fx_bst_first(&info->ty_components);
while (cur) {
struct fx_type_component *component
= fx_unbox(struct fx_type_component, cur, c_node);
cur = fx_bst_next(cur);
free(component);
}
fx_namemap_cleanup(&info->ty_properties, property_namemap_cleanup);
fx_namemap_cleanup(&info->ty_functions, function_namemap_cleanup);
fx_type_unref(info->ty_metatype);
return FX_RESULT_SUCCESS;
}
fx_result fx_type_add_function(fx_type_info *info, struct _fx_object *func)
{
const char *name = fx_function_get_name(func);
struct fx_namemap_entry *entry = fx_namemap_get(
&info->ty_functions,
name);
struct fx_namemap_entry *entry
= fx_namemap_get(&info->ty_functions, name);
if (entry) {
return FX_RESULT_ERR(NAME_EXISTS);
}
@@ -366,9 +418,8 @@ fx_result fx_type_add_function(fx_type_info *info, struct _fx_object *func)
fx_result fx_type_add_property(fx_type_info *info, struct _fx_object *prop)
{
const char *name = fx_property_get_name(prop);
struct fx_namemap_entry *entry = fx_namemap_get(
&info->ty_functions,
name);
struct fx_namemap_entry *entry
= fx_namemap_get(&info->ty_functions, name);
if (entry) {
return FX_RESULT_ERR(NAME_EXISTS);
}
@@ -410,10 +461,8 @@ fx_function *fx_type_info_get_function_by_name(
return NULL;
}
struct fx_type_function *func = fx_unbox(
struct fx_type_function,
entry,
f_entry);
struct fx_type_function *func
= fx_unbox(struct fx_type_function, entry, f_entry);
return func->f_func;
}
@@ -426,9 +475,7 @@ fx_function *fx_type_info_get_property_by_name(
return NULL;
}
struct fx_type_property *prop = fx_unbox(
struct fx_type_property,
entry,
p_entry);
struct fx_type_property *prop
= fx_unbox(struct fx_type_property, entry, p_entry);
return prop->p_prop;
}