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/bst.h>
|
||||||
#include <fx/endian.h>
|
#include <fx/endian.h>
|
||||||
|
#include <fx/global.h>
|
||||||
#include <fx/int.h>
|
#include <fx/int.h>
|
||||||
#include <fx/object.h>
|
#include <fx/object.h>
|
||||||
#include <fx/reflection/function.h>
|
#include <fx/reflection/function.h>
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
|
|
||||||
static struct fx_bst type_idmap = FX_BST_INIT;
|
static struct fx_bst type_idmap = FX_BST_INIT;
|
||||||
static struct fx_namemap type_namemap = FX_NAMEMAP_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};
|
static union fx_type_id zero_id = {0};
|
||||||
|
|
||||||
struct type_init_ctx {
|
struct type_init_ctx {
|
||||||
@@ -23,6 +25,37 @@ struct type_init_ctx {
|
|||||||
size_t ctx_instance_offset;
|
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(
|
static inline int type_info_compare(
|
||||||
const struct fx_type_info *a,
|
const struct fx_type_info *a,
|
||||||
const struct fx_type_info *b)
|
const struct fx_type_info *b)
|
||||||
@@ -56,10 +89,8 @@ static struct fx_type_info *get_type(
|
|||||||
{
|
{
|
||||||
fx_bst_node *cur = tree->bst_root;
|
fx_bst_node *cur = tree->bst_root;
|
||||||
while (cur) {
|
while (cur) {
|
||||||
struct fx_type_info *cur_node = fx_unbox(
|
struct fx_type_info *cur_node
|
||||||
struct fx_type_info,
|
= fx_unbox(struct fx_type_info, cur, ty_idmap_node);
|
||||||
cur,
|
|
||||||
ty_idmap_node);
|
|
||||||
int cmp = fx_type_id_compare(key, &cur_node->ty_id);
|
int cmp = fx_type_id_compare(key, &cur_node->ty_id);
|
||||||
|
|
||||||
if (cmp > 0) {
|
if (cmp > 0) {
|
||||||
@@ -80,10 +111,8 @@ struct fx_type_component *fx_type_get_component(
|
|||||||
{
|
{
|
||||||
fx_bst_node *cur = tree->bst_root;
|
fx_bst_node *cur = tree->bst_root;
|
||||||
while (cur) {
|
while (cur) {
|
||||||
struct fx_type_component *cur_node = fx_unbox(
|
struct fx_type_component *cur_node
|
||||||
struct fx_type_component,
|
= fx_unbox(struct fx_type_component, cur, c_node);
|
||||||
cur,
|
|
||||||
c_node);
|
|
||||||
int cmp = fx_type_id_compare(key, &cur_node->c_type->ty_id);
|
int cmp = fx_type_id_compare(key, &cur_node->c_type->ty_id);
|
||||||
|
|
||||||
if (cmp > 0) {
|
if (cmp > 0) {
|
||||||
@@ -151,16 +180,14 @@ static fx_result locate_interface(
|
|||||||
struct fx_type_info *dest,
|
struct fx_type_info *dest,
|
||||||
struct type_init_ctx *init_ctx)
|
struct type_init_ctx *init_ctx)
|
||||||
{
|
{
|
||||||
struct fx_type_component *interface_comp = fx_type_get_component(
|
struct fx_type_component *interface_comp
|
||||||
&dest->ty_components,
|
= fx_type_get_component(&dest->ty_components, interface_id);
|
||||||
interface_id);
|
|
||||||
if (interface_comp) {
|
if (interface_comp) {
|
||||||
return FX_RESULT_SUCCESS;
|
return FX_RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fx_type_info *interface_reg = get_type(
|
struct fx_type_info *interface_reg
|
||||||
&type_idmap,
|
= get_type(&type_idmap, interface_id);
|
||||||
interface_id);
|
|
||||||
if (!interface_reg) {
|
if (!interface_reg) {
|
||||||
return FX_RESULT_ERR(NO_ENTRY);
|
return FX_RESULT_ERR(NO_ENTRY);
|
||||||
}
|
}
|
||||||
@@ -227,9 +254,8 @@ static fx_result find_type_components(struct fx_type_info *type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
struct fx_type_info *dep_class = get_type(
|
struct fx_type_info *dep_class
|
||||||
&type_idmap,
|
= get_type(&type_idmap, current_id);
|
||||||
current_id);
|
|
||||||
if (!dep_class) {
|
if (!dep_class) {
|
||||||
return FX_RESULT_ERR(NO_ENTRY);
|
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)
|
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)) {
|
if (!type_has_base_class(info)) {
|
||||||
fx_type_id_copy(FX_TYPE_OBJECT, &info->ty_parent_id);
|
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;
|
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)
|
fx_result fx_type_add_function(fx_type_info *info, struct _fx_object *func)
|
||||||
{
|
{
|
||||||
const char *name = fx_function_get_name(func);
|
const char *name = fx_function_get_name(func);
|
||||||
struct fx_namemap_entry *entry = fx_namemap_get(
|
struct fx_namemap_entry *entry
|
||||||
&info->ty_functions,
|
= fx_namemap_get(&info->ty_functions, name);
|
||||||
name);
|
|
||||||
if (entry) {
|
if (entry) {
|
||||||
return FX_RESULT_ERR(NAME_EXISTS);
|
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)
|
fx_result fx_type_add_property(fx_type_info *info, struct _fx_object *prop)
|
||||||
{
|
{
|
||||||
const char *name = fx_property_get_name(prop);
|
const char *name = fx_property_get_name(prop);
|
||||||
struct fx_namemap_entry *entry = fx_namemap_get(
|
struct fx_namemap_entry *entry
|
||||||
&info->ty_functions,
|
= fx_namemap_get(&info->ty_functions, name);
|
||||||
name);
|
|
||||||
if (entry) {
|
if (entry) {
|
||||||
return FX_RESULT_ERR(NAME_EXISTS);
|
return FX_RESULT_ERR(NAME_EXISTS);
|
||||||
}
|
}
|
||||||
@@ -410,10 +461,8 @@ fx_function *fx_type_info_get_function_by_name(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fx_type_function *func = fx_unbox(
|
struct fx_type_function *func
|
||||||
struct fx_type_function,
|
= fx_unbox(struct fx_type_function, entry, f_entry);
|
||||||
entry,
|
|
||||||
f_entry);
|
|
||||||
return func->f_func;
|
return func->f_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,9 +475,7 @@ fx_function *fx_type_info_get_property_by_name(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fx_type_property *prop = fx_unbox(
|
struct fx_type_property *prop
|
||||||
struct fx_type_property,
|
= fx_unbox(struct fx_type_property, entry, p_entry);
|
||||||
entry,
|
|
||||||
p_entry);
|
|
||||||
return prop->p_prop;
|
return prop->p_prop;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user