Hi again! On Wed 27 Aug 2008 12:00, Andy Wingo <[EMAIL PROTECTED]> writes:
> On Wed 27 Aug 2008 07:00, Han-Wen Nienhuys <[EMAIL PROTECTED]> writes: > >>>>> http://thread.gmane.org/gmane.lisp.guile.user/6372 >> >> I think reference counting is the correct solution for this, as far as >> I understand the problem from the quoted message. > > I don't think so; the use case is that (1) we don't want to prevent the > C object from being freed, so we don't want to hold a reference on the C > object; but (2) we do want to know when it is freed, so we can release > our cache; but (3) we want to get the scheme object back if the object > has not in fact been swept. I don't think this is exactly right. I was discussing this on IRC with Ludovic and he made me come out with a better characterization of the problem. Consider a C object, `C'. We wrap it in scheme with a SCM object, `S'. S has a reference on C, using reference counting. C has some kind of API to associate S with it: set_ptr() and get_ptr(). Cool. So what happens if we get C back from a callback at some time in the future? Well we call get_ptr(C) and return that if it's non-null. Otherwise we make a new smob and call set_ptr (C, S) and then return S. So what happens if the scheme object becomes collectable? Well S has a free function which will unref the C object and set_ptr (C, NULL). This is also OK. But what if it goes like this: S becomes collectable in theory mark phase: S is indeed marked as collectable C is returned from a callback: get_ptr() return S at some later time the card containing S is swept; S's free function is run, and S is marked as a free cell at some later point maybe S gets reused for some other purpose however S was already alive in scheme, and we are using it as a smob! The point is: You cannot do C->Scheme mapping reliably in the presence of lazy sweeping, because there is a time in which the object is marked as sweepable but not swept, but the C->Scheme code has no way of knowing this. (While talking with Ludovic we realized that his code has this problem.) My solution was to re-mark when you do get_ptr(), but I see now where the problem with that is. > void* scm_with_sweep_mutex (void* (*with_mutex_func)(void*), void*); I think this is not so elegant, but it is correct. Andy -- http://wingolog.org/