Closed ysbaddaden closed 2 years ago
AFAIK: the problem is relying on the Crystal stdlib (Mutex
) when we should rely on libc instead (pthread_mutex
). The former relies on the GC when the latter won't.
Using It doesn't even work, and crashes with an infinite recursion.Thread::Mutex
may be fine as a quick workaround, but it won't do in the long run, because it raises on errors which will allocate an exception class.
I tried to call GC_lock
and GC_unlock
but I get a reentrant/concurrent call into GC_collect
:
GC.collect: GC_lock (fiber=main)
GC.collect: GC_lock (fiber=Signal Loop)
GC.collect: GC_unlock (fiber=Signal Loop)
<hangs forever>
It then hangs forever because the second GC.collect
overwrote @@pending
so the main fiber won't be resumed ever again.
It looks like an Atomic::Flag can workaround the issue.
Here is an interesting stacktrace I just got:
We can see that we try to allocate (
#23: Deque.new
) but the HEAP has been filled, so the GC starts a collection, and callsGC_collect
to collect all the stacks to walk, but... the Deque is too small and we try to increase it's capacity (#12
), which tries to allocate but fails because the HEAP is filled, and so we try to collect (oops).