RE: the FFI and C reference counting

On 24 July 2005 14:05, Peter Gammie wrote:
After much head scratching I can only think that the following is happening:
1. Create BDD, BDD.refcount++, add finalizer. 2. BDD becomes unreferenced but not yet GC'd. 3. Call BDD operation returning the same BDD as step 1. (call it BDD') 4. GHC's GC kicks in and BDD.refcount--. (*) 5. BDD'.refcount++, add finalizer.
At (*), CUDD deallocates BDD (== BDD') and BDD' becomes a dangling pointer.
Is this plausible?
Looks plausible to me. The API is being a bit naughty by not incrementing the reference count on an object it returns - this would be ok if the API function returning the object can be sure that the ref count is already at least 1, but in this case it appears that you have been handed an object which has a ref count of possibly 0, which seems bad. I wonder what reasoning the API is using to justify this. COM is another reference-counted API. In COM, the convention is that a returned object will have its reference count already bumped, you have to explicitly Release() it. See QueryInterface(), for example. However, passing an object to a method in COM doesn't require bumping the reference count, but the caller is holding the object so it can be sure the reference count remains non-zero for the duration of the call.
On a related note: what impact will multi-core GHC have on code like this? I get queasy thinking of how it will interact with all those non-threadsafe C libraries bound in a style similar to the above...
Using COM in the Visual Studio extension, we ran into trouble just using the multi-threaded RTS, never mind multi-core. The problem is that the finalizer runs in a different thread than the original thread that created the object, so if the act of decrementing the reference count is not a thread-safe operation, you're in trouble. We had to switch to explicit reference counting operations instead of finalizers in COM code (it isn't too bad, actually). Cheers, Simon
participants (1)
-
Simon Marlow