Skip to content

unable to temporarily re-enable interrupts within a Julia callback #17281

@stevengj

Description

@stevengj

In JuliaMath/Cubature.jl#18, I am running into a failure that seems to have been introduced in #16174. In particular, I am passing a Julia callback function to a C library, and in this callback function I would like to temporarily re-enable SIGINT inside a try block. In Julia 0.4 I did this by calling sigatomic_begin/end around the ccall and sigatomic_end/begin inside the callback. In 0.5 this is failing, and @yuyichao suggests that the catch block may be resetting the sigatomic counter.

Here is a compact pure-Julia example that illustrates the problem:

runcallback_(callback::Ptr{Void}) = ccall(callback, Bool, ())
function callback()
    try
        Base.sigatomic_end() # re-enable interrupts
        sleep(3) # wait a while to give a chance to hit ctrl-c if you want
        return true
    catch
        return false
    finally
        Base.sigatomic_begin() # re-suppress interrupts
    end
end
function runcallback(cb::Ptr{Void})
    rcb = cfunction(runcallback_, Bool, (Ptr{Void},))
    try
        Base.sigatomic_begin() # suppress interrupts
        ccall(rcb, Bool, (Ptr{Void},), cb)
    finally
        Base.sigatomic_end() # re-enable interrupts
    end
end
runcallback(cfunction(callback, Bool, ()))

In Julia 0.4, this works (returning true if you let it run, or false if you hit ctrl-c to interrupt the sleep). On Julia 0.5 master, it gives the error:

ERROR: sigatomic_end called in non-sigatomic region
 in runcallback(::Ptr{Void}) at ./REPL[3]:7

Metadata

Metadata

Assignees

No one assigned

    Labels

    regressionRegression in behavior compared to a previous version

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions