'Signal'에 해당되는 글 1건

  1. 2010.10.29 [Linux][C/C++] Understanding Signals – User Signal Handler

[Linux][C/C++] Understanding Signals – User Signal Handler

Language/C&C++ 2010.10.29 17:30

Signal is used for interaction between User Mode processes(henceforth UMP) and for kernel to notify processes of system events.
There are lots of materials you can find to understand what Signal is. So, let's skip it.
The point of this article is "How user signal handler(henceforth USH) is executed?" in Linux.

The core what Linux Kernel does to deliver signal, is modifying stack of UMP - usually adding data.
This is very important! UMP's stack itself is changed!
Kernel changes UMP' stack and register values as if  USH is called from specific function - let's call it F.
(For example, PC is set to USH. Return address in stack is set to function F.)
And, usually, F is just system call - sigreturn. At this system call, Kernel back UMP's stack to original values.
Here is simplified flow.

Signal is issued --> Kernel changes UMP's stack -> USH is executed -> return to function F -> System call (sigreturn) -> UMP's stack is restored -> UMP is executed in normal.

In case of multi-threaded process, thread stack is changed. Nothing different.
Understood? Than what is point?
Yes, USH is run at issued process's / thread's context in User Mode.
Let's see following codes.

/* Timer is used for example */
static pthread_mutex_t _m;
...
static void
_signal_handler(int sig, siginfo_t* si, void* uc) {
    pthread_mutex_lock(&_m);
    ...
    pthread_mutex_unlock(&_m);
}

int main(...) {
    ... /* signal is requested (ex timer) somewhere here */
    pthread_mutex_lock(&_m);
    ... /* <--- *a */
    pthread_mutex_unlock(&_m);
    ...
    return 0;
}

Can you image what I am going to talk about?
As I mentioned above signal handler is run in issued thread's context. So, if signal is issued at (*a), program is stuck due to deadlock!
So, signal handler of above codes should be like follows

static void*
_signal_handler_thread(void* arg) {
    pthread_mutex_lock(&_m);
    ...
    pthread_mutex_unlock(&_m);
}

static void
_signal_handler(int sig, siginfo_t* si, void* uc) {
    pthread_t thd;
    pthread_create(&thd, NULL, &_signal_handler_thread, NULL);
}

Done!

신고
tags :
Trackback 0 : Comment 0

티스토리 툴바