diff --git a/fx/global.c b/fx/global.c new file mode 100644 index 0000000..189644c --- /dev/null +++ b/fx/global.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include + +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); +} diff --git a/fx/include/fx/global.h b/fx/include/fx/global.h new file mode 100644 index 0000000..5683233 --- /dev/null +++ b/fx/include/fx/global.h @@ -0,0 +1,10 @@ +#ifndef FX_GLOBAL_H_ +#define FX_GLOBAL_H_ + +#include +#include + +FX_API void fx_register_global(fx_object *obj); +FX_API void fx_cleanup_global(void); + +#endif diff --git a/fx/type.c b/fx/type.c index bd6dac1..3ca1719 100644 --- a/fx/type.c +++ b/fx/type.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -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; }