What happens to the rest of the stack during a signal handler? - unix

I've set up a signal handler in my main thread. A separate thread then sends my main thread this signal. My signal handler is being called appropriately, but I'm not sure what the 'State' of the main thread is at this point, and whether it can be recovered. basically, my main thread was blocked on a read() call, and a different thread has sent it a signal due to an extraordinary event. I thus want the read() call to fail (EINTR?), hence my other thread sending the main thread this signal.

It depends on how you installed the signal handler. If the signal handler was installed using sigaction() and without specifying the SA_RESTART flag, then the read() will fail with EINTR if it has not transferred any data yet.
In general, the thread that has handled a signal can continue normally after the signal handler returns. That's really the whole point.
Remember though, that the signal might have arrived just after the read() had successfully returned, too - or worse, just before you called read() (in which case the read() will still block).

Related

when signal will be processed in unix?

When exactly signal will start execution in unix ?Does the signal will be processed when system turns into kernel mode? or immediately when it is receives signal? I assume it will be processed immediate when it receives.
A signal is the Unix mechanism for allowing a user space process to receive asynchronous notifications. As such, signals are always "delivered by" the kernel. And hence, it is impossible for a signal to be delivered without a transition into kernel mode. Therefore it doesn't make sense to talk of a process "receiving" a signal (or sending one) without the involvement of the kernel.
Signals can be generated in different ways.
They can be generated by a device driver within the kernel (for example, tty driver in response to the interrupt, kill, or stop keys or in response to input or output by a backgrounded process).
They can be generated by the kernel in response to an emergent out-of-memory condition.
They can be generated by a processor exception in response to something the process itself does during its execution (illegal instruction, divide by zero, reference an illegal address).
They can be generated directly by another process (or by the receiving process itself) via kill(2).
SIGPIPE can be generated as a result of writing to a pipe that has no reader.
But in every case, the signal is delivered to the receiving process by the kernel and hence through a kernel-mode transition.
The kernel might need to force that transition -- pre-empt the receiving process -- in order to deliver the signal (for example, in the case of a CPU-bound process running on processor A being sent a signal by a different process running on processor B).
In some cases, the signal may be handled for the process by the kernel itself (for example, with SIGKILL -- or several others when no signal handler is configured).
Actually invoking a process' signal handler is done by manipulating the process' user space stack so that the signal handler is invoked on return from kernel-mode and then, if/when the signal handler procedure returns, the originally executing code can be resumed.
As to when it is processed, that is subject to a number of different factors.
There are operating system (i.e. kernel) operations that are never interrupted by signals (these are generally relatively short duration operations), in which case the signal will be processed after their completion.
The process may have temporarily blocked signal delivery, in which case the signal will be "pending" until it is unblocked.
The process could be swapped out or non-runnable for any of a number of reasons -- in which case, its signal handler cannot be invoked until the process is runnable again.
Resuming the process in order to deliver the signal might be delayed by interrupts and higher priority tasks.
A signal will be immediately detected by the process which receives it.
Depending on the signal type, the process might treat it with the default handler, might ignore it or might execute a custom handler. It depends a lot on what the process is and what signal it receives. The exception is the kill signal (9) which is treated by the kernel and terminates the execution of the process which was supposed to receive it.

behaviour of unix process when a signal arrives and the process is already in signal handler?

I have a process which is already in signal handler , and called a process blocking call. What will happen if one more signal arrives for this process ?
By default signals don't block each other. A signal only blocks itself during its own delivery. So, in general, an handling code can be interrupted by another signal delivery.
You can control this behavior by setting the process signal mask relatively to each signal delivery. This means that you can block (or serialize) signal delivery. For instance you can declare that you accept to be interrupted with signal S1 while handling signal S2, but not the converse...
Remember that signal delivery introduces some concurrency into your code, so controlling the blocking is needed.
I'm pretty sure signals are blocked while a handler is being executed, but I'm having a hard time finding something that says that definitively.
Also, you may wish to see this question - some of the answers talk about what functions you should and shouldn't call from a signal handler.
In general, you should consider a signal handler like an interrupt handler - do the very least you can in the handler, and return quickly.

QThread::start: Thread termination error

I'm using an OpenSSL library in multi-threading application.
For various reasons I'm using blocking SSL connection. And there is a situation when client hangs on
SSL_connect
function.
I moved connection procedure to another thread and created timer. On timeout connection thread is terminated using:
QThread::terminate()
The thread is terminable, but on the next attempt to start thread I get:
QThread::start: Thread termination error:
I checked the "max thread issue" and that's not the case.
I'm working on CentOS 6.0 with QT 4.5, OpenSSL 1.0
The question is how to completely terminate a thread.
The Qt Documentation about terminate() tells:
The thread may or may not be terminated immediately, depending on the operating systems scheduling policies. Use QThread::wait() after terminate() for synchronous termination.
but also:
Warning: This function is dangerous and its use is discouraged. The thread can be terminated at any point in its code path. Threads can be terminated while modifying data. There is no chance for the thread to clean up after itself, unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
Assuming you didn't reimplement QThread::run() (which is usually not necessary) - or if you actually reimplemented run and called exec() yourself, the usual way to stop a thread would be:
_thread->quit();
_thread->wait();
The first line tells the thread asynchronously to stop execution which usually means the thread will finish whatever it is currently doing and then return from it's event loop. However, quit() always instantly returns which is why you need to call wait() so the main thread is blocked until _thread was actually ended. After that, you can safely start() the thread again.
If you really want to get rid of the thread as quickly as possible, you can also call wait() after terminate() or at least before you call start() again

emit and slots order execution

One thread do an emit signal1();
A second thread do an emit signal2(); after that first thread has sent its signal ( there is the same mutex locked before emit call on both thread and I logged it, I can see in my log that first thread acquire lock before second thread)
first thread and second thread or not the GUI thread.
Is there any guarentees that signal1's slot will be call before signal2's slot ?
As the emitter and the receiver objects are running in different threads, the slots will not be executed synchronously: Qt is using a queued connection by default instead of a direct connection. You can however force a synchronous execution by using a blocking queued connection (see also http://qt-project.org/doc/qt-4.8/qt.html#ConnectionType-enum for the description of the different connection types) when connecting signals and slots.
But a blocking queue connection has a cost: the emitter thread is blocked until all the connected slots are executed, which is not necessarily a good idea. If you want to use a non-blocking connection, however, the order of execution depends on the objects were the slots are executed.
The important thing to consider is that each QThread has its own event queue. It means that the order of execution is only guaranteed for the slots of a given thread. This means that you have to consider the following cases:
signal1's slot and signal2's slot are defined in QObject's living in the same thread: in that case, you can be sure that the slots are executed in the expected order because they are triggered by the same event queue
both slots are running in different threads: here you have no control over the order of execution as the signals are posted to 2 independent event queues. If this is the case, you have to use mutexes or wait conditions (or use a blocking connection).
emit is just syntactic sugar, look at the .cpp generated by the Meta Object Compiler (moc).
So, emit signal1(); is compiled as signal1();, and the answer to your question is YES, but of course you have no guarentees that signal1() execution ends before signal2() invocation.
I am not sure if I understand you correctly, but this might help you:
When a signal is emitted, the slots connected to it are usually executed immediately, just like a normal function call.
from http://doc.qt.io/qt-5/signalsandslots.html
So think of calling emit() as calling any other function.

How to interrupt a blocking accept() call

I have written a multithreaded application in C. I have two threads created, one for catching all the signals and another for accept()-ing client connections. When I kill the appilcation using killproc, the thread with the accept call is not interrupted. How can I fix that?
The code looks like:
int stop_exec=0;
sigCatcherThread()
{
int sig
sigset_t allsignals;
sigfillset(allsignals);
do{
sigwait(&allsignals, &sig);
if(sig==SIGTERM)
stop_exec=1;
}while(!stop_exec)
}
clientHandler()
{
...
while(!stop_exec)
{
accept(...);
}
main()
{
pthread_create(..., sigCatcherThread,..);
pthread_create(..., clientHandler,...);
}
Here you see the use of interrupted system calls. But the convenience of a signal handling thread is probably higher than the use of interrupted systems calls.
So you need you client handler to block until it can accept an incoming connection or the signal occurs. Waiting for potential input means either signal driven IO -- a path I wouldn't follow -- or select(2) (or pool). But select(2) can wait only on IO. So transform your signal occurrence in IO: open a pipe, have your signal handling thread write to the pipe when SIGQUIT occurs and have your client thread select(2) for the socket and the other end of the pipe.
Only one thread receives a signal targeted to a process. So, it must be not the thread blocked on accept(). See signal concepts for more details.
As already mentioned here, you should probably be using an event loop based on select(). I would suggest using libevent.
There's no need to interrupt the blocking accept call. Just make sure that if the thread does return from accept, say by receiving an actual connection, it won't do anything harmful.
If there's some specific reason you need the accept call to interrupt, explain what it is. Likely there's a simple way to remove the requirement.

Resources