Thanks! I'll try this tomorrow. So similar to what you've done here? 
https://github.com/yuyichao/FunctionWrappers.jl/blob/master/src/FunctionWrappers.jl#L40

I can't remember if I actually called that explicitly, but I believe what I 
ended up with was similar to 
here: http://julialang.org/blog/2013/05/callback, where they use 
unsafe_pointer_to_objref to recover the function object.

On Wednesday, September 28, 2016 at 10:06:51 PM UTC+1, Yichao Yu wrote:
>
> On Wed, Sep 28, 2016 at 5:00 PM, Christian Rorvik 
> <[email protected] <javascript:>> wrote: 
> > I don't have the code at hand right now (it's at work), but what I was 
> doing 
> > was something like 
> > 
> > type Wrapper{Arg} 
> >     cfun::Ptr{Void} 
> >     cobj::Ptr{Void} 
> >     obj 
> > 
> >     function Wrapper{T}(f::T) 
> >         return new(cfunction(call_wrapper, Void, (Ref{T}, Arg)), 
> > pointer_from_objref(f), f) 
> >     end 
> > end 
>
> This is wrong, You shouldn't ever call `pointer_from_objref` for 
> unknown object. The right way to handl this is 
>
> type Wrapper{Arg} 
>     cfun::Ptr{Void} 
>     cobj::Ptr{Void} 
>     obj 
>     function Wrapper{T}(f::T) 
>         to_root = Base.cconvert(Ref{T}, f) 
>         ptr = Base.unsafe_convert(Ref{T}, to_root) 
>         return new(cfunction(call_wrapper, Void, (Ref{T}, Arg)), 
> Ptr{Void}(ptr), to_root) 
>     end 
> end 
>
>
> > 
> > Where call_wrapper would invoke the closure. I had to change 
> call_wrapper to 
> > receive the closure as Ptr{T} and call unsafe_pointer_to_objref and then 
> > call it. 
> > 
> > 
> > On Wednesday, September 28, 2016 at 9:50:47 PM UTC+1, Yichao Yu wrote: 
> >> 
> >> On Wed, Sep 28, 2016 at 4:36 PM, Christian Rorvik 
> >> <[email protected]> wrote: 
> >> > GC of code turned out to be a red herring. After isolating the 
> instance 
> >> > of a 
> >> > call that was crashing, and getting right up to it, GDB was kind 
> enough 
> >> > to 
> >> > get its knickers in a twist and segfault itself every time I stepped 
> >> > instruction by instruction to find the precise point of failure 
> >> > (backtrace 
> >> > after segfault looked pretty meaningless). 
> >> > 
> >> > What it tunred out to be a was a Ref vs Ptr problem, where in Julia I 
> >> > have a 
> >> > callback wrapper that receives a pointer to the closure. I was taking 
> >> > this 
> >> > as Ref{T} and invoking it with a pointer from the C code. This worked 
> >> > all 
> >> > fine and dandy, but somehow caused the object to be collected (I'm 
> >> > guessing). I can see how what I did was wrong, but I can't see how it 
> >> > would 
> >> > lead to something being collected when there still exists roots 
> pointing 
> >> > to 
> >> > it. If anything I would possibly expect a leak. Nonetheless, bit of a 
> >> > wild 
> >> > goose chase. 
> >> 
> >> It's unclear what exactly you mean but just to be clear `cfunction(f, 
> >> Ret, Tuple{Ref{Int}})` expect a pointer to a julia boxed `Int` that is 
> >> rooted somewhere during the execution of the julia callback function. 
> >> It is illegal to pass it a bare C `intptr_t*` (that doesn't point to 
> >> julia memory of a boxed Int) and it is illegal to generates it with 
> >> `ccall(..., (Ptr{Int},), &i)`. 
> >> 
> >> > 
> >> > 
> >> > On Wednesday, September 28, 2016 at 5:22:49 PM UTC+1, Christian 
> Rorvik 
> >> > wrote: 
> >> >> 
> >> >> I'm not yet a 100% sure what is happening in my application, but I'm 
> >> >> embedding Julia and using cfunction() to generate C-callable 
> functions 
> >> >> that 
> >> >> at a later time invoke the registered julia code. I use a fairly 
> >> >> standard 
> >> >> pattern I think, of passing a pointer to a julia object that is 
> retain 
> >> >> in C 
> >> >> and later passed down to the callback created by cfunction, and from 
> >> >> there 
> >> >> resolved to the original real Julia reference type, invoking a 
> closure. 
> >> >> The 
> >> >> closure itself is retained in some global state to prevent garbage 
> >> >> collection. What appears to be happening however, is the code at the 
> >> >> landing 
> >> >> site for the cfunction returned pointer is at some point garbage 
> >> >> collection 
> >> >> (or at least corrupted), as my program, after a while of running, 
> will 
> >> >> segfault upon invoking the callback (after many previously 
> successful 
> >> >> callbacks). It segfaults because it hits invalid code, and it's not 
> >> >> that 
> >> >> some state is missing when running the code. 
> >> >> 
> >> >> Is this to be be expected, and what's the right way to ensure the 
> code 
> >> >> isn't GC'd? 
>

Reply via email to