fix scheduler memory error on exit
This commit is contained in:
@@ -182,7 +182,7 @@ function abs_path_to_package(package_dir)
|
||||
return cfg.package
|
||||
}
|
||||
|
||||
return null
|
||||
return package_dir
|
||||
}
|
||||
|
||||
// given a file, find the absolute path, package name, and import name
|
||||
@@ -949,8 +949,9 @@ function try_dylib_symbol(sym, pkg, file_stem) {
|
||||
|
||||
var c_file = file_stem + '.c'
|
||||
var cpp_file = file_stem + '.cpp'
|
||||
var entry = find(dylibs, function(r) {
|
||||
return r.file == c_file || r.file == cpp_file
|
||||
var entry = null
|
||||
arrfor(dylibs, function(r) {
|
||||
if (r.file == c_file || r.file == cpp_file) entry = r
|
||||
})
|
||||
if (!entry || !entry.dylib) return null
|
||||
|
||||
@@ -959,8 +960,8 @@ function try_dylib_symbol(sym, pkg, file_stem) {
|
||||
handle = os.dylib_open(entry.dylib)
|
||||
if (handle) open_dls[entry.dylib] = handle
|
||||
}
|
||||
if (!handle) return null
|
||||
if (!os.dylib_has_symbol(handle, sym)) return null
|
||||
if (!handle) { log.shop(`try_dylib: no handle for ${entry.dylib}`); return null }
|
||||
if (!os.dylib_has_symbol(handle, sym)) { log.shop(`try_dylib: no symbol ${sym} in ${entry.dylib}`); return null }
|
||||
|
||||
log.shop('resolved ' + sym + ' from build cache')
|
||||
return function() { return os.dylib_symbol(handle, sym) }
|
||||
|
||||
@@ -330,6 +330,35 @@ void actor_free(cell_rt *actor)
|
||||
}
|
||||
lockless_shdel(actors, actor->id);
|
||||
|
||||
// Purge any pending timers referencing this actor from the timer heap
|
||||
// to prevent the timer thread from accessing freed memory.
|
||||
{
|
||||
pthread_mutex_lock(&engine.lock);
|
||||
int n = arrlen(timer_heap);
|
||||
int w = 0;
|
||||
for (int r = 0; r < n; r++) {
|
||||
if (timer_heap[r].actor != actor)
|
||||
timer_heap[w++] = timer_heap[r];
|
||||
}
|
||||
arrsetlen(timer_heap, w);
|
||||
for (int i = w / 2 - 1; i >= 0; i--) {
|
||||
int j = i;
|
||||
while (1) {
|
||||
int left = 2 * j + 1, right = 2 * j + 2, smallest = j;
|
||||
if (left < w && timer_heap[left].execute_at_ns < timer_heap[smallest].execute_at_ns)
|
||||
smallest = left;
|
||||
if (right < w && timer_heap[right].execute_at_ns < timer_heap[smallest].execute_at_ns)
|
||||
smallest = right;
|
||||
if (smallest == j) break;
|
||||
timer_node tmp = timer_heap[j];
|
||||
timer_heap[j] = timer_heap[smallest];
|
||||
timer_heap[smallest] = tmp;
|
||||
j = smallest;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&engine.lock);
|
||||
}
|
||||
|
||||
// Do not go forward with actor destruction until the actor is completely free
|
||||
pthread_mutex_lock(actor->msg_mutex);
|
||||
pthread_mutex_lock(actor->mutex);
|
||||
|
||||
Reference in New Issue
Block a user