From: Daniel Kochmanski <dkochman...@gmail.com> Hey,
this patch adds support for si:unload-foreign-module, so it could be called from cffi. For now cffi returns an error on unload call, what prevents from loading libs which use it (for example IOlib). In function ecl_library_close - I'm not sure if first condition is ever met, because refcount doesn't increase on calling load-foreign-library. After this patch is merged into ecl, I'll issue small patch to cffi to actually use new functionality. Best Regards, Daniel Kochmański --- src/c/ffi.d | 27 +++++++++++++++++++++++++++ src/c/ffi/libraries.d | 18 +++++++++++++----- src/c/symbols_list.h | 1 + src/c/symbols_list2.h | 1 + src/h/external.h | 3 ++- 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/c/ffi.d b/src/c/ffi.d index 6adb964..24800e0 100644 --- a/src/c/ffi.d +++ b/src/c/ffi.d @@ -729,6 +729,33 @@ si_load_foreign_module(cl_object filename) } cl_object +si_unload_foreign_module(cl_object module) +{ +#if !defined(ENABLE_DLOPEN) + FEerror("SI:UNLOAD-FOREIGN-MODULE does not work when ECL is statically linked", 0); +#else + cl_object output = ECL_NIL; + + if (ecl_unlikely(ecl_t_of(module) != t_codeblock)) { + FEerror("UNLOAD-FOREIGN-MODULE: Argument is not a foreign module: ~S ", + 1, module); + } +# ifdef ECL_THREADS + mp_get_lock(1, ecl_symbol_value(@'mp::+load-compile-lock+')); + ECL_UNWIND_PROTECT_BEGIN(ecl_process_env()) { +# endif + if (ecl_likely(ecl_library_close(module))) output = ECL_T; +# ifdef ECL_THREADS + (void)0; /* MSVC complains about missing ';' before '}' */ + } ECL_UNWIND_PROTECT_EXIT { + mp_giveup_lock(ecl_symbol_value(@'mp::+load-compile-lock+')); + } ECL_UNWIND_PROTECT_END; +# endif + @(return output) +#endif +} + +cl_object si_find_foreign_symbol(cl_object var, cl_object module, cl_object type, cl_object size) { #if !defined(ENABLE_DLOPEN) diff --git a/src/c/ffi/libraries.d b/src/c/ffi/libraries.d index 9adb734..26aaf3e 100644 --- a/src/c/ffi/libraries.d +++ b/src/c/ffi/libraries.d @@ -205,7 +205,7 @@ dlopen_wrapper(cl_object block) set_library_error(block); } -static void +static int dlclose_wrapper(cl_object block) { if (block->cblock.handle != NULL) { @@ -219,7 +219,9 @@ dlclose_wrapper(cl_object block) FreeLibrary(block->cblock.handle); #endif block->cblock.handle = NULL; + return TRUE; } + return FALSE; } static cl_object @@ -419,18 +421,23 @@ ecl_library_error(cl_object block) { return block->cblock.error; } -void +bool ecl_library_close(cl_object block) { const cl_env_ptr the_env = ecl_process_env(); + bool success = TRUE; ECL_WITH_GLOBAL_LOCK_BEGIN(the_env) { ecl_disable_interrupts(); - if (block->cblock.refs != ecl_make_fixnum(1)) { + /* is it ever a case? no matter how many times i call + load-foreign-module it seems that block->cblock.refs = 1 */ + if (block->cblock.refs > ecl_make_fixnum(1)) { block->cblock.refs = ecl_one_minus(block->cblock.refs); block = ECL_NIL; } else if (block->cblock.handle != NULL) { - GC_call_with_alloc_lock(dlclose_wrapper, block); + success = GC_call_with_alloc_lock(dlclose_wrapper, block); cl_core.libraries = ecl_remove_eq(block, cl_core.libraries); - } + } else { /* block not loaded */ + success = FALSE; + } ecl_enable_interrupts(); } ECL_WITH_GLOBAL_LOCK_END; if (block != ECL_NIL && block->cblock.self_destruct) { @@ -438,6 +445,7 @@ ecl_library_close(cl_object block) { unlink((char*)block->cblock.name->base_string.self); } } + return success; } void diff --git a/src/c/symbols_list.h b/src/c/symbols_list.h index 47851b5..5a5f64c 100755 --- a/src/c/symbols_list.h +++ b/src/c/symbols_list.h @@ -1485,6 +1485,7 @@ cl_symbols[] = { {SYS_ "FREE-FOREIGN-DATA", SI_ORDINARY, si_free_foreign_data, 1, OBJNULL}, {SYS_ "MAKE-FOREIGN-DATA-FROM-ARRAY", SI_ORDINARY, si_make_foreign_data_from_array, 1, OBJNULL}, {SYS_ "LOAD-FOREIGN-MODULE", SI_ORDINARY, si_load_foreign_module, 1, OBJNULL}, +{SYS_ "UNLOAD-FOREIGN-MODULE", SI_ORDINARY, si_unload_foreign_module, 1, OBJNULL}, {SYS_ "NULL-POINTER-P", SI_ORDINARY, si_null_pointer_p, 1, OBJNULL}, {SYS_ "SIZE-OF-FOREIGN-ELT-TYPE", SI_ORDINARY, si_size_of_foreign_elt_type, 1, OBJNULL}, {SYS_ "ALIGNMENT-OF-FOREIGN-ELT-TYPE", SI_ORDINARY, si_alignment_of_foreign_elt_type, 1, OBJNULL}, diff --git a/src/c/symbols_list2.h b/src/c/symbols_list2.h index 5d99c94..70fdd1a 100644 --- a/src/c/symbols_list2.h +++ b/src/c/symbols_list2.h @@ -1485,6 +1485,7 @@ cl_symbols[] = { {SYS_ "FREE-FOREIGN-DATA","si_free_foreign_data"}, {SYS_ "MAKE-FOREIGN-DATA-FROM-ARRAY","si_make_foreign_data_from_array"}, {SYS_ "LOAD-FOREIGN-MODULE","si_load_foreign_module"}, +{SYS_ "UNLOAD-FOREIGN-MODULE","si_unload_foreign_module"}, {SYS_ "NULL-POINTER-P","si_null_pointer_p"}, {SYS_ "SIZE-OF-FOREIGN-ELT-TYPE","si_size_of_foreign_elt_type"}, {SYS_ "ALIGNMENT-OF-FOREIGN-ELT-TYPE","si_alignment_of_foreign_elt_type"}, diff --git a/src/h/external.h b/src/h/external.h index e3dee77..8b79f4a 100755 --- a/src/h/external.h +++ b/src/h/external.h @@ -618,7 +618,7 @@ extern ECL_API cl_object ecl_make_codeblock(); extern ECL_API cl_object ecl_library_open(cl_object filename, bool force_reload); extern ECL_API void *ecl_library_symbol(cl_object block, const char *symbol, bool lock); extern ECL_API cl_object ecl_library_error(cl_object block); -extern ECL_API void ecl_library_close(cl_object block); +extern ECL_API bool ecl_library_close(cl_object block); extern ECL_API void ecl_library_close_all(void); /* ffi/mmap.d */ @@ -650,6 +650,7 @@ extern ECL_API cl_object si_null_pointer_p(cl_object f); extern ECL_API cl_object si_size_of_foreign_elt_type(cl_object tag); extern ECL_API cl_object si_alignment_of_foreign_elt_type(cl_object tag); extern ECL_API cl_object si_load_foreign_module(cl_object module); +extern ECL_API cl_object si_unload_foreign_module(cl_object module); extern ECL_API cl_object si_find_foreign_symbol(cl_object var, cl_object module, cl_object type, cl_object size); extern ECL_API cl_object si_call_cfun(cl_narg, cl_object fun, cl_object return_type, cl_object arg_types, cl_object args, ...); extern ECL_API cl_object si_make_dynamic_callback(cl_narg, cl_object fun, cl_object sym, cl_object return_type, cl_object arg_types, ...); -- 2.2.1 ------------------------------------------------------------------------------ Dive into the World of Parallel Programming! The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net _______________________________________________ Ecls-list mailing list Ecls-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ecls-list