[Tarantool-patches] [PATCH 2/2] func: fix not unloading of unused modules
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Thu Nov 28 01:24:13 MSK 2019
Hi! Thanks for the review!
On 27/11/2019 09:41, Konstantin Osipov wrote:
> * Vladislav Shpilevoy <v.shpilevoy at tarantool.org> [19/11/27 11:15]:
>> C functions are loaded from .so/.dylib dynamic libraries. A
>> library is loaded when any function from there is called first
>> time. And was supposed to be unloaded, when all its functions are
>> dropped from the schema (box.schema.func.drop()), and none of them
>> is still in a call. But the unloading part was broken.
>
> Wow. This is damn genius!
>
> It never occurred to me that error injections could be used to
> test some obscure code paths.
>
> The impact of this on testing is going to be huge.
>> module_gc(struct module *module)
>> {
>> - if (!module->is_unloading || !rlist_empty(&module->funcs) ||
>> - module->calls != 0)
>> - return;
>> - module_delete(module);
>> + if (rlist_empty(&module->funcs) && module->calls == 0)
>> + module_delete(module);
>> }
>
> This is LGTM. Georgy wrote the original patches so you may want
> to solicit his review as well.
>> +f1:wakeup()
>> + | ---
>> + | ...
>> +test_run:wait_cond(function() return f1:status() == 'dead' end)
>> + | ---
>> + | - true
>> + | ...
>> +check_module_count_diff(0)
>> + | ---
>> + | ...
>> +
>> +f2:wakeup()
>
> This is a bit hackish way to cancel a sleep. I thought we had
> errinj_sleep injection which would reliably cancel a sleep when
> you clear it? If there is no such function I don't think
> it is a blocker for this patch to get in as is.
>
The sleeping function is in a C module, and can use only public
API from module.h. So we can't use error injections in it. But
the sleep can be dropped in a different way. I pushed the diff
below on the branch:
====================================================================
diff --git a/test/box/function1.c b/test/box/function1.c
index fd434c280..87062d6a8 100644
--- a/test/box/function1.c
+++ b/test/box/function1.c
@@ -237,10 +237,11 @@ test_sleep(box_function_ctx_t *ctx, const char *args, const char *args_end)
(void) args;
(void) args_end;
/*
- * Sleep until an explicit wakeup. Purpose of this
- * function - test module unloading prevention while at
- * least one of its functions is being executed.
+ * Sleep until a cancellation. Purpose of this function -
+ * test module unloading prevention while at least one of
+ * its functions is being executed.
*/
- fiber_sleep(100000);
+ while (!fiber_is_cancelled())
+ fiber_sleep(0);
return 0;
}
diff --git a/test/box/gh-4648-func-load-unload.result b/test/box/gh-4648-func-load-unload.result
index 8c4d23938..e695dd365 100644
--- a/test/box/gh-4648-func-load-unload.result
+++ b/test/box/gh-4648-func-load-unload.result
@@ -114,7 +114,7 @@ check_module_count_diff(0)
| ---
| ...
-f1:wakeup()
+f1:cancel()
| ---
| ...
test_run:wait_cond(function() return f1:status() == 'dead' end)
@@ -125,7 +125,7 @@ check_module_count_diff(0)
| ---
| ...
-f2:wakeup()
+f2:cancel()
| ---
| ...
test_run:wait_cond(function() return f2:status() == 'dead' end)
diff --git a/test/box/gh-4648-func-load-unload.test.lua b/test/box/gh-4648-func-load-unload.test.lua
index d7e445f65..10b9de87a 100644
--- a/test/box/gh-4648-func-load-unload.test.lua
+++ b/test/box/gh-4648-func-load-unload.test.lua
@@ -54,10 +54,10 @@ box.schema.func.drop('function1')
box.schema.func.drop('function1.test_sleep')
check_module_count_diff(0)
-f1:wakeup()
+f1:cancel()
test_run:wait_cond(function() return f1:status() == 'dead' end)
check_module_count_diff(0)
-f2:wakeup()
+f2:cancel()
test_run:wait_cond(function() return f2:status() == 'dead' end)
check_module_count_diff(-1)
More information about the Tarantool-patches
mailing list