Isaac Jurado <dipto...@gmail.com> writes: > Hello, > > I'm playing with event loop libraries implemented in C (libev, libevent, > etc... in my case libsystemd), but configuring them from Guile. > > The qsort example in the documentation [1] seems safe because the qsort C > function directly calls back, so the callback Scheme bindings stay > referenced (by the Scheme code calling qsort) during all the C code > execution. > > Now, in C event loops the situation is different. There is one call to > configure the event callback, in which the function and data pointers are > lent to the loop; and then there is the main loop or the single iteration > call. > > The way I see it, suppose I add a timer. I call one C function passing a > (proceudre->pointer) and an (scm->pointer). In a future time, those > pointers will be used by the C event loop. If a garbage collection happens > in the middle, the results of (procedure->pointer) and (scm->pointer) may > have been reclaimed by the time the C event loop calls back.
I have been down this path before, with guile and with lua. Basically, if C (or non-scheme) has a pointer to a scheme object, then you need to hold a logical reference for it and protect the scheme object, and when the C pointer is dropped decrease the refcnt. I am unclear on the details of how you have a ref that gc is made aware of. One way is to have a scheme array of the object and a count, and have the code null out the object when the count goes to zero or something like that. But the point is that you need to have a proxy in the scheme world, visible to gc, when a pointer to a scheme object is held outside of the scheme world. Forcing gc is not going to be reliable. If you have a reliable scheme, gc can happen at any random time and things will be ok.