On Wed, Jun 8, 2016 at 4:39 AM, Ulf Worsoe <[email protected]> wrote:
> In this case the callback function is guaranteed to always be called from
> the same thread that called the original native function (i.e. the Julia
> thread).

If it is always on the same thread then you can use `reenable_sigint`
and catch the exception.

>
> It also appears to in the current nightly build.
>
> On Monday, June 6, 2016 at 1:58:06 PM UTC+2, Yichao Yu wrote:
>>
>> On Mon, Jun 6, 2016 at 6:29 AM, Ulf Worsoe <[email protected]> wrote:
>> > The symbol jl_signal_pending is exported, and the following appears to
>> > work
>> > (assuming, of course, sig_atomic_t is an int):
>> >
>> > function callback_func()
>> >   if unsafe_load(cglobal(:jl_signal_pending, Cint),1) > Cint(0)
>> >     return convert(Cint,1)
>> >   else
>> >     return convert(Cint,0)
>> >   end
>> > end
>>
>> This should be "safe" (other than that running a julia function on an
>> unmanaged thread is almost never safe)
>>
>> It won't work on 0.5 though.
>>
>> >
>> >
>> > function do_native_call()
>> >   disable_sigint() do
>> >     ccall(:my_c_function, Void, (Ptr{Void},), cfunction(callback_func,
>> > Cint,()))
>> >   end
>> > end
>> >
>> > and on the native side:
>> > void my_c_func(int (*callback)())
>> > {
>> >   while (1)
>> >   {
>> >     sleep(1);
>> >     if (callback())
>> >      return;
>> >   }
>> > }
>> >
>> > If this a safe way to check for ctrl-c?
>> >
>> >
>> > 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?

Reply via email to