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? 
>

Reply via email to