Hm. That would work. Thank you for that suggestion!
On Wednesday, June 8, 2016 at 2:05:26 PM UTC+2, Yichao Yu wrote: > > On Wed, Jun 8, 2016 at 4:39 AM, Ulf Worsoe <[email protected] > <javascript:>> 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? >
