diff --git a/internal/shop.cm b/internal/shop.cm index 4a9c5eb6..a088af37 100644 --- a/internal/shop.cm +++ b/internal/shop.cm @@ -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) } diff --git a/source/scheduler.c b/source/scheduler.c index c9c08a1f..97b4736f 100644 --- a/source/scheduler.c +++ b/source/scheduler.c @@ -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);