I can see that the symbol jl_signal_pending is exported. Can I assume that
this is safe to check from the julia thread? So doing something like this
should work:
function callback_func()
if unsafe_load(cglobal(:jl_signal_pending, Cint),1) > Cint(0)
end
function do_native_call()
disable_sigint() do
ccall(:my_c_function, Void, (Ptr{Void},), cfunction())
end
end
and on the native side:
void my_c_func
On Monday, June 6, 2016 at 10:25:29 AM UTC+2, Ulf Worsoe wrote:
>
> It appears to work in Julia 0.4 - at least I hasn't crashed yet - but I
> have not really stress tested it.
>
> Just disabling SIGINT only gets me half of the way. It will stop the
> function from crashing, but these calls may run for a long time, and in
> some cases it may be relevant to manually stop the call when a sufficiently
> good solution has been found. Is there any robust way to receive
> notification about ctrl-c or check if a ctrl-c has happened before
> returning from a native function?
>
> On Friday, June 3, 2016 at 5:24:28 PM UTC+2, Yichao Yu wrote:
>>
>> On Fri, Jun 3, 2016 at 4:51 AM, Ulf Worsoe <[email protected]> wrote:
>> > I am developing Mosek.jl.
>> >
>> > That library works by creating a task object, adding data to it and
>> calling
>> > a solve function. When a user in interactive mode hits ctrl-c, calls to
>> > native functions are terminated, and that leaves the task object in an
>> > inconsistent state, meaning that even calling the destructor may cause
>> it to
>> > segfault. This is why I am trying to take over the ctrl-c signal. I do
>> > something like this
>> > (
>> https://github.com/JuliaOpt/Mosek.jl/blob/sigint/src/msk8_functions.jl#L2291-L2308):
>>
>>
>> > msk_global_break = false
>> > function msk_global_sigint_handler(sig::Int32)
>> > println("msk_global_sigint_handler")
>> > global msk_global_break = true
>> > nothing
>> > end
>> >
>> > function optimize(task_:: MSKtask)
>> > trmcode_ = Array(Int32,(1,))
>> > SIGINT=2
>> > old_sighandler =
>> >
>> ccall((:signal,"libc"),Ptr{Void},(Cint,Ptr{Void}),SIGINT,cfunction(msk_global_sigint_handler,
>>
>>
>> > Void, (Cint,)))
>> > res = @msk_ccall(
>> > "optimizetrm",Int32,(Ptr{Void},Ptr{Int32}),task_.task,trmcode_)
>> > ccall((:signal,"libc"),Void,(Cint,Ptr{Void}),SIGINT,old_sighandler)
>> > global msk_global_break
>> > if msk_global_break
>> > global msk_global_break = false
>> > throw(InterruptException())
>> > end
>> >
>> > if res != MSK_RES_OK
>> > msg = getlasterror(task_)
>> > throw(MosekError(res,msg))
>> > end
>> > (convert(Int32,trmcode_[1]))
>> > end
>> >
>> > During long calls the msk_global_break flag is checked, and if set, the
>> > operation terminates in a controlled manner.
>>
>> This will not work on 0.5 at least, not sure about 0.4.
>> SIGINT is blocked on all threads and there are always more then one
>> threads, one of them unmanaged and can't run any julia code.
>> You should be able to just use `disable_sigint` to do this on both 0.4
>> and 0.5. It is not necessary on 0.5 if the ccall doesn't call back to
>> julia.
>>
>> >
>> > I have seen older answers to similar questions, saying that this could
>> cause
>> > problems, but have been told that threading may be handled different
>> now. Is
>> > this something I can expect to work in Julia 0.4 and/or 0.5? In
>> particular,
>> > if the native optimizetrm function creates multiple threads, will this
>> still
>> > work?
>>
>