Hi Jameson, Thank you for your answer,

`primesieve_sieve` is not calling Julia code (juste somme pointer arithmetics and a delete). But it seems that call to `println` in the finalizer is causing the error, strangely.

What would be the prefered way to handle memory deallocation in this case? Copying the result from the C function and immediately deleting the memory allocated by it would be the easiest way, but it will impact the performance. Is there any way to avoid that?

Also, I don't know if it's the right explanation, but I have the feeling that because the GC doesn't know how much memory has been allocated by the C function, he doesn't know when deallocating memory becomes "urgent". Is there any way to inform the GC how much memory is hold by a given pointer?

note, if a c functions returns a bits type (such as Ptr), it is invalid to declare it to return a struct (such as C_primesieve_array). this will soon cause failures on the x86 linux ABI.

is the `primesieve_free` c-function itself attempting to execute julia code?

note, that since you didn't return `primes_ptr`, it will be garbage collected (and finalized) shortly after your primes function returns

On Sun Feb 08 2015 at 2:15:21 PM <[email protected] <mailto:[email protected]>> wrote:

    Hi guys,

    While creating a tiny wrapper over the C/C++ primesieve
    <https://github.com/kimwalisch/primesieve> library, I encountered
    an error while trying to finalize the Ptr returned by a function.
    This pointer must be freed by another function from the library,
    so I tried to wrap it into a finalizer function but it doesn't
    work because of the following error: "task switch not allowed from
    inside gc finalizer". Could someone explain how this could be done
    properly? I would try to avoid the returned array if possible.
    Here is the code so far:

    |

    constLIB_PRIMESIEVE ="libprimesieve.so"

    type C_primesieve_array
        handle::Ptr{Int32}
    end

    functionprimes(n::Int)
        size =Cint[0]
        primes_ptr =ccall(
    (:primesieve_generate_primes,LIB_PRIMESIEVE),
            C_primesieve_array,
    (UInt64,UInt64,Ptr{Cint},Int),
    1,n,size,3)

    functionprimesieve_array_finalizer(primesieve_arr::C_primesieve_array)
            ccall(
    (:primesieve_free,LIB_PRIMESIEVE),
    Void,(Ptr{Int32},),primesieve_arr.handle)
    end

        finalizer(primes_ptr,primesieve_array_finalizer)
    returnpointer_to_array(primes_ptr.handle,size[1],false)
    end
    |


    Thank you very much,
    Rémi


Reply via email to