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?
