fx: start implementing global data cleanup
This commit is contained in:
+39
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user