interrupt handing and the GUI (bug #37672)

classic Classic list List threaded Threaded
32 messages Options
12
Reply | Threaded
Open this post in threaded view
|

interrupt handing and the GUI (bug #37672)

John W. Eaton
Administrator
I have marked bug 37672 (https://savannah.gnu.org/bugs/?37672) as a
blocker for the release.  I have some ideas about why this is not
working and what we can do to fix it.

In the CLI version of Octave, the terminal driver sends a SIGINT
signal to the Octave process when the user types Ctrl-C at the
command prompt.  Then the SIGINT signal is caught and we end up in the
function user_abort.

In the GUI, typing Ctrl-C in the terminal window doesn't generate a
SIGINT signal directly as it does when Octave is running in a
terminal.  Instead, it eventually calls the function
TerminalView::copyClipboard (in the Unix version of the libqterminal
code) or QWinTerminalImpl::copyClipboard (in the Windows version of
the libqterminal code).  Then, if there is no selection, we call
::raise (SIGINT) to generate an interrupt signal for the process.
 From there, we end up in user_abort.

Ignoring things like "debug_on_interrupt", the function user_abort
may do one of two things to handle the signal.

The first is to set the global variable octave_interrupt_state and
return.  Then Octave periodically checks this variable (typically
using the OCTAVE_QUIT macro) and if it is set, throws an exception and
returns to the command prompt.

This method of interrupt handling works in the CLI and GUI versions of
Octave.  This is how interrupts inside loops like

   while (true) disp ('foo-i-hithere'); end

are handled.

The second method of signal handling is to call the function
jump_to_enclosing_context, which calls longjmp to return to a "safe"
location at which point Octave throws an exception and returns to the
command prompt.

This type of interrupt handling is used when we need to be able to
interrupt calls to library functions that we don't have control over
so we can't insert calls to OCTAVE_QUIT to make them abort.  This
method works for the CLI version of Octave but not with the GUI.  The
difference is that in the CLI version, we only have one thread but in
the GUI, we have multiple threads and the exception is being thrown in
the thread where the GUI is running instead of the thread where the
Octave interpreter is running.

I was able to examine this behavior by using "info threads" in gdb
while doing something like

   x = rand (3000);
   inv (x);

in Octave and typing Ctrl-C in the command window when Octave is busy
working on the inverse.

My first thought was that we need to make sure that the SIGINT signal
and interrupt handler are executed inside the same thread where Octave
is running, so instead of simply calling ::raise inside the
copyClipboard function, I modified Octave to emit a Qt signal there
that would be handled by a Qt slot function running in the Octave
interpreter thread.  Of course this doesn't work because in that
thread the Octave interpreter never returns to give control back to
the Qt thread manager.

Here is my proposed solution:

Instead of using setjmp/longjmp and relying on Unix signal handling to
interrupt the process, we execute these long-running external
functions in separate threads that we can cancel when an interrupt
arrives.  Then in the main thread we just wait for the thread to
finish and periodically check to see whether the
octave_interrupt_state variable is set.  If it is, then we cancel the
thread and throw an exception.  That will all happen inside the thread
that is running the Octave interpreter, so we won't be trying to throw
an exception across threads.

I understand how to do this with pthreads.  I'll either need help with
Windows threads or maybe we could use the pthreads-win32 library
(LGPL; available here: http://www.sourceware.org/pthreads-win32).

Another question is whether we should always use this approach or
continue to use the setjmp/longjmp method for the CLI version of
Octave.

Does anyone see a better way?

jwe
Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

Daniel Sebald
On 11/10/2013 11:07 AM, John W. Eaton wrote:

> I have marked bug 37672 (https://savannah.gnu.org/bugs/?37672) as a
> blocker for the release. I have some ideas about why this is not
> working and what we can do to fix it.
>
> In the CLI version of Octave, the terminal driver sends a SIGINT
> signal to the Octave process when the user types Ctrl-C at the
> command prompt. Then the SIGINT signal is caught and we end up in the
> function user_abort.
>
> In the GUI, typing Ctrl-C in the terminal window doesn't generate a
> SIGINT signal directly as it does when Octave is running in a
> terminal. Instead, it eventually calls the function
> TerminalView::copyClipboard (in the Unix version of the libqterminal
> code) or QWinTerminalImpl::copyClipboard (in the Windows version of
> the libqterminal code). Then, if there is no selection, we call
> ::raise (SIGINT) to generate an interrupt signal for the process.
>  From there, we end up in user_abort.
>
> Ignoring things like "debug_on_interrupt", the function user_abort
> may do one of two things to handle the signal.
>
> The first is to set the global variable octave_interrupt_state and
> return. Then Octave periodically checks this variable (typically
> using the OCTAVE_QUIT macro) and if it is set, throws an exception and
> returns to the command prompt.
>
> This method of interrupt handling works in the CLI and GUI versions of
> Octave. This is how interrupts inside loops like
>
> while (true) disp ('foo-i-hithere'); end
>
> are handled.
>
> The second method of signal handling is to call the function
> jump_to_enclosing_context, which calls longjmp to return to a "safe"
> location at which point Octave throws an exception and returns to the
> command prompt.
>
> This type of interrupt handling is used when we need to be able to
> interrupt calls to library functions that we don't have control over
> so we can't insert calls to OCTAVE_QUIT to make them abort. This
> method works for the CLI version of Octave but not with the GUI. The
> difference is that in the CLI version, we only have one thread but in
> the GUI, we have multiple threads and the exception is being thrown in
> the thread where the GUI is running instead of the thread where the
> Octave interpreter is running.
>
> I was able to examine this behavior by using "info threads" in gdb
> while doing something like
>
> x = rand (3000);
> inv (x);
>
> in Octave and typing Ctrl-C in the command window when Octave is busy
> working on the inverse.
>
> My first thought was that we need to make sure that the SIGINT signal
> and interrupt handler are executed inside the same thread where Octave
> is running, so instead of simply calling ::raise inside the
> copyClipboard function, I modified Octave to emit a Qt signal there
> that would be handled by a Qt slot function running in the Octave
> interpreter thread. Of course this doesn't work because in that
> thread the Octave interpreter never returns to give control back to
> the Qt thread manager.

Yes, this doesn't sound good.  I sort of like the way it already exists,
i.e., that the GUI interprets the SIGINT based upon what window is
active, and if it is the terminal window that is active issue an
interrupt back to the OS with the target being the Octave-core thread
which the GUI knows because it is the one that launched the Octave-core
thread and should have a record of process information.


> Here is my proposed solution:
>
> Instead of using setjmp/longjmp and relying on Unix signal handling to
> interrupt the process, we execute these long-running external
> functions in separate threads that we can cancel when an interrupt
> arrives. Then in the main thread we just wait for the thread to
> finish and periodically check to see whether the
> octave_interrupt_state variable is set. If it is, then we cancel the
> thread and throw an exception. That will all happen inside the thread
> that is running the Octave interpreter, so we won't be trying to throw
> an exception across threads.
>
> I understand how to do this with pthreads. I'll either need help with
> Windows threads or maybe we could use the pthreads-win32 library
> (LGPL; available here: http://www.sourceware.org/pthreads-win32).
>
> Another question is whether we should always use this approach or
> continue to use the setjmp/longjmp method for the CLI version of
> Octave.
>
> Does anyone see a better way?

This seems vaguely familiar and I recall looking at the interrupt code
at some point.  This might have been around the time we cleaned up the
header files for the SIGxx definitions and found duplicate symbols that
we didn't know exactly how to handle.  I haven't time to search through
where or what I might have written, but I recall looking at the way
interrupts were handled and thought that some change would be needed in
the Octave core code for some reason or another.  It was either that the
core would have to not grab control of the SIGINT at initialization or
that it would have to do so under the condition of running embedded
inside some GUI.  Again, it's all vague now.

Anyway, what you are proposing sounds better, i.e., no exception across
threads--but what I just said might not be a proper characterization,
what I mean is no function calls across threads as a result of a SIGINT.
  However, periodically checking some variable as regards to an
interrupt signal doesn't feel elegant.  I would think there might be a
better way of bouncing signals about by setting up or redefining
interrupt handlers differently.

One thing I wonder is whether the notion of an exception across threads
is correct.  Unlike threads sharing memory or function calls, signals
sort of go back to the OS.

Long external functions inside separate threads I'm fine with (hey,
could then maybe make use of multiple cores), but why if they are run in
the main thread are they not interruptable by the current mechanism?

Dan
Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

Daniel Sebald
On 11/10/2013 12:25 PM, Daniel J Sebald wrote:

> On 11/10/2013 11:07 AM, John W. Eaton wrote:
>> I have marked bug 37672 (https://savannah.gnu.org/bugs/?37672) as a
>> blocker for the release. I have some ideas about why this is not
>> working and what we can do to fix it.
>>
>> In the CLI version of Octave, the terminal driver sends a SIGINT
>> signal to the Octave process when the user types Ctrl-C at the
>> command prompt. Then the SIGINT signal is caught and we end up in the
>> function user_abort.
>>
>> In the GUI, typing Ctrl-C in the terminal window doesn't generate a
>> SIGINT signal directly as it does when Octave is running in a
>> terminal. Instead, it eventually calls the function
>> TerminalView::copyClipboard (in the Unix version of the libqterminal
>> code) or QWinTerminalImpl::copyClipboard (in the Windows version of
>> the libqterminal code). Then, if there is no selection, we call
>> ::raise (SIGINT) to generate an interrupt signal for the process.
>> From there, we end up in user_abort.
>>
>> Ignoring things like "debug_on_interrupt", the function user_abort
>> may do one of two things to handle the signal.
>>
>> The first is to set the global variable octave_interrupt_state and
>> return. Then Octave periodically checks this variable (typically
>> using the OCTAVE_QUIT macro) and if it is set, throws an exception and
>> returns to the command prompt.

Instead of octave_interrupt_state, maybe there could be two threads in
Octave core:  one whose main purpose is to handle signal and thread
flow, the other being the main Octave-core thread as it currently exists.

Dan
Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

Rik-4
In reply to this post by John W. Eaton
On 11/10/2013 09:08 AM, [hidden email] wrote:
> Here is my proposed solution:
>
> Instead of using setjmp/longjmp and relying on Unix signal handling to
> interrupt the process, we execute these long-running external
> functions in separate threads that we can cancel when an interrupt
> arrives.
How is it determined what might be a long-running external function?
sleep() can be either very short (sleep (0.01)) or very long (sleep (10)).
It seems like it would be difficult to program the AI needed for each function.

Would the determination of "long-running" be done on a case-by-case basis
in the code or do we assume that any external library function might
potentially be long?  I would worry in that case that someone with fread()
might have the the overhead of setting up, launching a thread, and cleaning
up all to read a single value.


>   Then in the main thread we just wait for the thread to
> finish and periodically check to see whether the
> octave_interrupt_state variable is set.  If it is, then we cancel the
> thread and throw an exception.  That will all happen inside the thread
> that is running the Octave interpreter, so we won't be trying to throw
> an exception across threads.
>
> I understand how to do this with pthreads.  I'll either need help with
> Windows threads or maybe we could use the pthreads-win32 library
> (LGPL; available here: http://www.sourceware.org/pthreads-win32).
>
> Another question is whether we should always use this approach or
> continue to use the setjmp/longjmp method for the CLI version of
> Octave.
I guess it depends on the performance considerations above.  Maintaining
more lines of code is always more work so maybe if we figure out a working
solution we should apply it everywhere.

--Rik
> Does anyone see a better way?
>
> jwe

Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

John W. Eaton
Administrator
On 11/10/2013 03:18 PM, Rik wrote:

> On 11/10/2013 09:08 AM, [hidden email] wrote:
>> Here is my proposed solution:
>>
>> Instead of using setjmp/longjmp and relying on Unix signal handling to
>> interrupt the process, we execute these long-running external
>> functions in separate threads that we can cancel when an interrupt
>> arrives.
> How is it determined what might be a long-running external function?
> sleep() can be either very short (sleep (0.01)) or very long (sleep (10)).
> It seems like it would be difficult to program the AI needed for each function.
>
> Would the determination of "long-running" be done on a case-by-case basis
> in the code or do we assume that any external library function might
> potentially be long?  I would worry in that case that someone with fread()
> might have the the overhead of setting up, launching a thread, and cleaning
> up all to read a single value.

For the most part we've already made this distinction.  The functions
that are called with F77_XFCN (but not F77_FUNC or F77_FCN) and any
block of code surrounded by
{BEGIN,END}_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE are subject to the
setjmp/longjmp signal handling treatment.

So for those bits of code we already have the overhead of copying the
setjmp info, calling setjmp, and the restoring the setjmp info.  We
would just be replacing that with the thread creation and
octave_interrupt_state detection code.

In any case, we could examine any of the locations where F77_XFCN or
{BEGIN,END}_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE is used and skip that
if the operation is expected to be fast.  For example, in the code for
computing a matrix inverse, we might choose to skip thread creation or
the setjmp/longjmp setup if the size of the matrix is less than some
threshold.  For iterative solvers there is probably no general way to
determine whether they will be fast.

jwe
Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

John W. Eaton
Administrator
In reply to this post by Daniel Sebald
On 11/10/2013 01:25 PM, Daniel J Sebald wrote:
> On 11/10/2013 11:07 AM, John W. Eaton wrote:
>
> Yes, this doesn't sound good. I sort of like the way it already exists,
> i.e., that the GUI interprets the SIGINT based upon what window is
> active, and if it is the terminal window that is active issue an
> interrupt back to the OS with the target being the Octave-core thread
> which the GUI knows because it is the one that launched the Octave-core
> thread and should have a record of process information.

My understanding is that signals are per-process, not per-thread, so
there is no way to direct the signal to a specific thread.  If there
were, then the solution would just be to direct the signal to the
correct thread.  But I don't see any way to do that.

jwe

Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

Michael Godfrey
In reply to this post by John W. Eaton
On 11/10/2013 12:07 PM, John W. Eaton wrote:
> Another question is whether we should always use this approach or
> continue to use the setjmp/longjmp method for the CLI version of
> Octave.
>
> Does anyone see a better way?
>
> jwe
John,

I do not have a better way, but maybe a suggestion.
First, my experience with Fedora 19 is:
octave:3> system('sleep 30')
^Cans =  2
octave:4>

Hangs until time count down:
octave:1> sleep(20)
^C^CPress Control-C again to abort.

and
octave:1> system(sleep(30))
^C^CPress Control-C again to abort.

============================
For sleep() would it be useful to implement code that does the sleep
to do the actual sleep which is not interruptable  in
short increments, checking  for interrupt at end of each increment?

Likely, you have a general solution that will work, which would
obviously be better.

Michael

Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

John W. Eaton
Administrator
In reply to this post by Daniel Sebald
On 11/10/2013 01:25 PM, Daniel J Sebald wrote:

> However, periodically checking some variable as regards to an interrupt
> signal doesn't feel elegant.

I agree, but I don't see a better way.  The pthreads interface allows
for signalling a thread with a "condition variable" but the pthread
documentation explicitly states that calling pthread_cond_signal from
a signal handler is not safe:

 
http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html

   It is not safe to use the pthread_cond_signal() function in a signal
   handler that is invoked asynchronously. Even if it were safe, there
   would still be a race between the test of the Boolean
   pthread_cond_wait() that could not be efficiently eliminated.

> One thing I wonder is whether the notion of an exception across threads
> is correct. Unlike threads sharing memory or function calls, signals
> sort of go back to the OS.

I'm not sure what you mean by "whether the notion of an exception
across threads is correct".  I'm fairly sure that the effect of
throwing a C++ exception from one thread and catching it in another is
undefined, but there appears to be a standard way to do this with
C++-11.  But even with that, I'm a bit unsure about calling longjmp
from one thread and what the effect is when the place you want to jump
to is supposed to be running in another thread.

> Long external functions inside separate threads I'm fine with (hey,
> could then maybe make use of multiple cores),

It wouldn't really help us with mulitiple cores.  The main thread
would just be waiting for the long running function to complete, or to
interrupt it if SIGINT is delievered.

> but why if they are run in
> the main thread are they not interruptable by the current mechanism?

Because the signal is (or may be) processed by a different thread, and
we aren't doing the right thing to throw an exception from one thread
to another.

jwe
Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

John W. Eaton
Administrator
In reply to this post by Daniel Sebald
On 11/10/2013 01:44 PM, Daniel J Sebald wrote:

> Instead of octave_interrupt_state, maybe there could be two threads in
> Octave core: one whose main purpose is to handle signal and thread flow,
> the other being the main Octave-core thread as it currently exists.

How does this new thread that handles signals interrupt the other thread?

jwe

Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

Michael Goffioul
In reply to this post by John W. Eaton
On Sun, Nov 10, 2013 at 3:55 PM, John W. Eaton <[hidden email]> wrote:
On 11/10/2013 01:25 PM, Daniel J Sebald wrote:
On 11/10/2013 11:07 AM, John W. Eaton wrote:

Yes, this doesn't sound good. I sort of like the way it already exists,
i.e., that the GUI interprets the SIGINT based upon what window is
active, and if it is the terminal window that is active issue an
interrupt back to the OS with the target being the Octave-core thread
which the GUI knows because it is the one that launched the Octave-core
thread and should have a record of process information.

My understanding is that signals are per-process, not per-thread, so there is no way to direct the signal to a specific thread.  If there were, then the solution would just be to direct the signal to the correct thread.  But I don't see any way to do that.

When reading this [1] it seems that pthread_sigprocmask may help in directing signal handlers in specific threads.

Michael.


Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

Michael Goffioul
On Sun, Nov 10, 2013 at 8:48 PM, Michael Goffioul <[hidden email]> wrote:
On Sun, Nov 10, 2013 at 3:55 PM, John W. Eaton <[hidden email]> wrote:
On 11/10/2013 01:25 PM, Daniel J Sebald wrote:
On 11/10/2013 11:07 AM, John W. Eaton wrote:

Yes, this doesn't sound good. I sort of like the way it already exists,
i.e., that the GUI interprets the SIGINT based upon what window is
active, and if it is the terminal window that is active issue an
interrupt back to the OS with the target being the Octave-core thread
which the GUI knows because it is the one that launched the Octave-core
thread and should have a record of process information.

My understanding is that signals are per-process, not per-thread, so there is no way to direct the signal to a specific thread.  If there were, then the solution would just be to direct the signal to the correct thread.  But I don't see any way to do that.

When reading this [1] it seems that pthread_sigprocmask may help in directing signal handlers in specific threads.

Sorry, I meant pthread_sigmask.

Michael.

Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

Daniel Sebald
In reply to this post by John W. Eaton
On 11/10/2013 03:16 PM, John W. Eaton wrote:

> On 11/10/2013 01:25 PM, Daniel J Sebald wrote:
>
>> However, periodically checking some variable as regards to an interrupt
>> signal doesn't feel elegant.
>
> I agree, but I don't see a better way. The pthreads interface allows
> for signalling a thread with a "condition variable" but the pthread
> documentation explicitly states that calling pthread_cond_signal from
> a signal handler is not safe:
>
>
> http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html

OK, interesting read.  This is about blocked threads (which isn't the
exact scenario) but I see your point about the asynchronous part of it.


On 11/10/2013 03:17 PM, John W. Eaton wrote:

> On 11/10/2013 01:44 PM, Daniel J Sebald wrote:
>
>> Instead of octave_interrupt_state, maybe there could be two threads in
>> Octave core: one whose main purpose is to handle signal and thread flow,
>> the other being the main Octave-core thread as it currently exists.
>
> How does this new thread that handles signals interrupt the other thread?
>
> jwe
>

What I said probably doesn't make sense after having read the pthreads.

Well, I'll toss out another idea.  From the pthread documentation it
sounds like all threads in a process can be set up to handle the same
signal, correct?  Before reading this, my (mis)understanding was that
there is just one thread that can handle some asynchronous signal coming
from the OS.  I'm not quite sure how it would work as I'm not an expert
in signal handling, but what if both the Octave core and the GUI had
their own signal handler for Cntrl-C and some type of Mutex were used to
coordinate signaling behavior.  For example,

1) GUI sets up a mutex so that Octave core (or whatever code indicates a
complete calculation) has control of it.

2) GUI launches Octave command.

3) When SIGINT comes to Octave core it does its normal Cntrl-C routine,
and when it is complete, somehow that mutex is freed.

4) When SIGINT comes to Octave GUI it

   a) looks to that mutex and waits until it is free under the
assumption that Octave core might be doing a little bit of cleanup
   b) when the mutex is free either the GUI does its own cleanup
appropriate for a core interrupt (update variables, this or that)
assuming it can identify that the Octave-core thread did a break, or it
proceeds to do the copy-to-clipboard step if no Octave-core break occurred.

Dan
Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

Daniel Sebald
In reply to this post by Michael Goffioul
On 11/10/2013 07:48 PM, Michael Goffioul wrote:

> On Sun, Nov 10, 2013 at 3:55 PM, John W. Eaton <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     On 11/10/2013 01:25 PM, Daniel J Sebald wrote:
>
>         On 11/10/2013 11:07 AM, John W. Eaton wrote:
>
>         Yes, this doesn't sound good. I sort of like the way it already
>         exists,
>         i.e., that the GUI interprets the SIGINT based upon what window is
>         active, and if it is the terminal window that is active issue an
>         interrupt back to the OS with the target being the Octave-core
>         thread
>         which the GUI knows because it is the one that launched the
>         Octave-core
>         thread and should have a record of process information.
>
>
>     My understanding is that signals are per-process, not per-thread, so
>     there is no way to direct the signal to a specific thread.  If there
>     were, then the solution would just be to direct the signal to the
>     correct thread.  But I don't see any way to do that.
>
>
> When reading this [1] it seems that pthread_sigprocmask may help in
> directing signal handlers in specific threads.
>
> Michael.
>
> [1]
> http://stackoverflow.com/questions/11679568/signal-handling-with-multiple-threads-in-linux

OK, now I'm not sure again whether multiple threads in a process can all
be set up to handle SIGINT.  It sounds like posix threads might allow
that, but generally not true?

Dan
Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

Michael Goffioul
In reply to this post by Daniel Sebald
On Sun, Nov 10, 2013 at 9:59 PM, Daniel J Sebald <[hidden email]> wrote:
On 11/10/2013 03:16 PM, John W. Eaton wrote:
On 11/10/2013 01:25 PM, Daniel J Sebald wrote:

However, periodically checking some variable as regards to an interrupt
signal doesn't feel elegant.

I agree, but I don't see a better way. The pthreads interface allows
for signalling a thread with a "condition variable" but the pthread
documentation explicitly states that calling pthread_cond_signal from
a signal handler is not safe:


http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html

OK, interesting read.  This is about blocked threads (which isn't the exact scenario) but I see your point about the asynchronous part of it.



On 11/10/2013 03:17 PM, John W. Eaton wrote:
On 11/10/2013 01:44 PM, Daniel J Sebald wrote:

Instead of octave_interrupt_state, maybe there could be two threads in
Octave core: one whose main purpose is to handle signal and thread flow,
the other being the main Octave-core thread as it currently exists.

How does this new thread that handles signals interrupt the other thread?

jwe


What I said probably doesn't make sense after having read the pthreads.

Well, I'll toss out another idea.  From the pthread documentation it sounds like all threads in a process can be set up to handle the same signal, correct?  Before reading this, my (mis)understanding was that there is just one thread that can handle some asynchronous signal coming from the OS.  I'm not quite sure how it would work as I'm not an expert in signal handling, but what if both the Octave core and the GUI had their own signal handler for Cntrl-C and some type of Mutex were used to coordinate signaling behavior.  For example,

1) GUI sets up a mutex so that Octave core (or whatever code indicates a complete calculation) has control of it.

2) GUI launches Octave command.

3) When SIGINT comes to Octave core it does its normal Cntrl-C routine, and when it is complete, somehow that mutex is freed.

4) When SIGINT comes to Octave GUI it

  a) looks to that mutex and waits until it is free under the assumption that Octave core might be doing a little bit of cleanup
  b) when the mutex is free either the GUI does its own cleanup appropriate for a core interrupt (update variables, this or that) assuming it can identify that the Octave-core thread did a break, or it proceeds to do the copy-to-clipboard step if no Octave-core break occurred.

The above seems to assume that multiple signal handlers will be called by the kernel, one in each thread. But I have a different reading of POSIX documentation. Especially "man 7 signal", section "Signal Mask and Pending Signals":

===
A process-directed signal may be delivered to any one of the  threads  that  does  not currently have the signal blocked.  If more than one of the threads has the signal unblocked, then the kernel chooses an arbitrary thread to which to deliver the signal.
===

So my understanding is that if you want to get SIGINT to be processed in the octave thread, the GUI thread must block the signal using pthread_sigmask.

Michael.

Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

Daniel Sebald
On 11/10/2013 09:25 PM, Michael Goffioul wrote:

> On Sun, Nov 10, 2013 at 9:59 PM, Daniel J Sebald <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     On 11/10/2013 03:16 PM, John W. Eaton wrote:
>
>         On 11/10/2013 01:25 PM, Daniel J Sebald wrote:
>
>             However, periodically checking some variable as regards to
>             an interrupt
>             signal doesn't feel elegant.
>
>
>         I agree, but I don't see a better way. The pthreads interface allows
>         for signalling a thread with a "condition variable" but the pthread
>         documentation explicitly states that calling pthread_cond_signal
>         from
>         a signal handler is not safe:
>
>
>         http://pubs.opengroup.org/__onlinepubs/009695399/__functions/pthread_cond_signal.__html
>         <http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html>
>
>
>     OK, interesting read.  This is about blocked threads (which isn't
>     the exact scenario) but I see your point about the asynchronous part
>     of it.
>
>
>
>     On 11/10/2013 03:17 PM, John W. Eaton wrote:
>
>         On 11/10/2013 01:44 PM, Daniel J Sebald wrote:
>
>             Instead of octave_interrupt_state, maybe there could be two
>             threads in
>             Octave core: one whose main purpose is to handle signal and
>             thread flow,
>             the other being the main Octave-core thread as it currently
>             exists.
>
>
>         How does this new thread that handles signals interrupt the
>         other thread?
>
>         jwe
>
>
>     What I said probably doesn't make sense after having read the pthreads.
>
>     Well, I'll toss out another idea.  From the pthread documentation it
>     sounds like all threads in a process can be set up to handle the
>     same signal, correct?  Before reading this, my (mis)understanding
>     was that there is just one thread that can handle some asynchronous
>     signal coming from the OS.  I'm not quite sure how it would work as
>     I'm not an expert in signal handling, but what if both the Octave
>     core and the GUI had their own signal handler for Cntrl-C and some
>     type of Mutex were used to coordinate signaling behavior.  For example,
>
>     1) GUI sets up a mutex so that Octave core (or whatever code
>     indicates a complete calculation) has control of it.
>
>     2) GUI launches Octave command.
>
>     3) When SIGINT comes to Octave core it does its normal Cntrl-C
>     routine, and when it is complete, somehow that mutex is freed.
>
>     4) When SIGINT comes to Octave GUI it
>
>        a) looks to that mutex and waits until it is free under the
>     assumption that Octave core might be doing a little bit of cleanup
>        b) when the mutex is free either the GUI does its own cleanup
>     appropriate for a core interrupt (update variables, this or that)
>     assuming it can identify that the Octave-core thread did a break, or
>     it proceeds to do the copy-to-clipboard step if no Octave-core break
>     occurred.
>
>
> The above seems to assume that multiple signal handlers will be called
> by the kernel, one in each thread. But I have a different reading of
> POSIX documentation. Especially "man 7 signal", section "Signal Mask and
> Pending Signals":
>
> ===
> A process-directed signal may be delivered to any one of the  threads
>   that  does  not currently have the signal blocked.  If more than one
> of the threads has the signal unblocked, then the kernel chooses an
> arbitrary thread to which to deliver the signal.
> ===
>
> So my understanding is that if you want to get SIGINT to be processed in
> the octave thread, the GUI thread must block the signal using
> pthread_sigmask.
>
> Michael.

Oh.  That is a good way to direct the SIGINT somewhere then, but sinks
the mutex idea.

The last answer at this link seems to know more than the rest of us:

http://stackoverflow.com/questions/12820765/can-i-send-signals-to-different-threads

Maybe there is something there.

Dan
Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

John W. Eaton
Administrator
In reply to this post by Daniel Sebald
On 11/10/2013 09:59 PM, Daniel J Sebald wrote:

>         http://pubs.opengroup.org/__onlinepubs/009695399/__functions/pthread_cond_signal.__html
>         <http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html>
>
>
> OK, interesting read.  This is about blocked threads (which isn't
> the exact scenario) but I see your point about the asynchronous part
> of it.

If the condition variable could be set in a signal handler, then the
way it would be used is

   * start the calculation thread

   * stop the main thread, waiting for either the calculation thread to
     finish, or for a signal to occur.  The notification would come
     from a condition variable.

This approach would be better than polling, but would only work if it
is OK to set a condition variable in a signal handler, which
apparently it is not.

jwe
Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

John W. Eaton
Administrator
In reply to this post by Daniel Sebald
On 11/10/2013 10:45 PM, Daniel J Sebald wrote:

> The last answer at this link seems to know more than the rest of us:
>
> http://stackoverflow.com/questions/12820765/can-i-send-signals-to-different-threads
>
> Maybe there is something there.

Yes, it mentions pthread_kill.  That appears to allow us to direct a
signal to a particular thread.

I'm attaching a patch that seems to at least partially work for me.
At least interrupts seem to work now inside sleep and long running
functions like "inv (large_matrix)", but now I also get random
segfaults when typing Ctrl-C in the command window after a few
interrupts have been processed (it seems random).

I don't expect it will work on Windows.  I suppose it just
happens to work for me because Qt is using pthreads on my system.
What if Qt doesn't use pthreads?

jwe


threading.diffs (7K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

Daniel Sebald
On 11/11/2013 12:35 AM, John W. Eaton wrote:

> On 11/10/2013 10:45 PM, Daniel J Sebald wrote:
>
>> The last answer at this link seems to know more than the rest of us:
>>
>> http://stackoverflow.com/questions/12820765/can-i-send-signals-to-different-threads
>>
>>
>> Maybe there is something there.
>
> Yes, it mentions pthread_kill. That appears to allow us to direct a
> signal to a particular thread.
>
> I'm attaching a patch that seems to at least partially work for me.
> At least interrupts seem to work now inside sleep and long running
> functions like "inv (large_matrix)", but now I also get random
> segfaults when typing Ctrl-C in the command window after a few
> interrupts have been processed (it seems random).

There is a lot there.  The only thing that seems somewhat suspicious
from first glance is the fact that

+  interpreter_thread = pthread_self ();
+

I.e., the fact that a thread might be interrupting itself.  On the other
hand, the pthread documentation says that is fine, but more than that it
looks like the GUI thread is actually initiating the pthread_kill()
using the above pointer so the thread really isn't interrupting itself.

I'm not sure what the problem might be for the random seg fault, and yes
pthread_kill might not be portable.


> I don't expect it will work on Windows. I suppose it just
> happens to work for me because Qt is using pthreads on my system.
> What if Qt doesn't use pthreads?

Have you looked at the QThread::exit() member function?

http://qt-project.org/doc/qt-4.7/qthread.html#signalSection

Could that be used instead of pthread_kill somehow?  The documentation
indicates this is not really an exit() in the conventional sense and
that the thread remains active, but needs to be restarted with exec().
Of course, this does nothing to clean up Octave core, so one would have
to figure out how to call the necessary code inside Octave-core upon
restarting it from the GUI.

Dan
Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

Michael Goffioul
In reply to this post by John W. Eaton



On Mon, Nov 11, 2013 at 1:35 AM, John W. Eaton <[hidden email]> wrote:
On 11/10/2013 10:45 PM, Daniel J Sebald wrote:

The last answer at this link seems to know more than the rest of us:

http://stackoverflow.com/questions/12820765/can-i-send-signals-to-different-threads

Maybe there is something there.

Yes, it mentions pthread_kill.  That appears to allow us to direct a
signal to a particular thread.

I'm attaching a patch that seems to at least partially work for me.
At least interrupts seem to work now inside sleep and long running
functions like "inv (large_matrix)", but now I also get random
segfaults when typing Ctrl-C in the command window after a few
interrupts have been processed (it seems random).

Does it make any difference if you block the SIGINT signal in the GUI thread with pthread_sigmask and continue using raise? 

 
I don't expect it will work on Windows.  I suppose it just
happens to work for me because Qt is using pthreads on my system.
What if Qt doesn't use pthreads?

I wouldn't bother too much about Windows here, as SIGINT handling is quite different and AFAIK *always* happen in a separate thread just created by the OS to handle the signal.

Michael.

Reply | Threaded
Open this post in threaded view
|

Re: interrupt handing and the GUI (bug #37672)

John W. Eaton
Administrator
On 11/11/2013 07:22 AM, Michael Goffioul wrote:

> I wouldn't bother too much about Windows here, as SIGINT handling is
> quite different and AFAIK *always* happen in a separate thread just
> created by the OS to handle the signal.

So what is the fix for Windows then?  We seem to have the same problem
there, that interrupting things like

   sleep (10);

or

   inv (large_matrix);

doesn't work.

jwe

12