简体   繁体   中英

Adding signal handler to a function in C for a thread library

I am writing a basic user level thread library. The function prototype for thread creation is thr_create (start_func_pointer,arg) { make_context(context_1,start_func) }

start_func will be user defined and can change depending on user/program

once after creation of thread, if I start executing it using swapcontext(context_1,context_2)

the function start_func would start running. Now , if a signal comes in , I need to handle it. Unfortunately, I just have the handle to start_func so I cant really define signal action inside the start_func

is there a way I can add a signal handling structure inside the start_function and point it to my code. something like this

thr_create (start_func_pointer,arg) { start_func.add_signal_hanlding_Structure = my_signal_handler(); make_context(context_1,start_func) } thr_create (start_func_pointer,arg) { start_func.add_signal_hanlding_Structure = my_signal_handler(); make_context(context_1,start_func) } Does anybody know how posix does it ?

If you are talking about catching real signals from the actual operating system you are running on I believe that you are going to have to do this application wide and then pass the signals on down into each thread (more on this later). The problem with this is that it gets complicated if two (or more) of your threads are trying to use alarm which uses SIGALRM -- when the real signal happens you can catch it, but then who do you deliver it to (one or all of the threads?).

If you are talking about sending and catching signals just among the threads within a program using your library then sending a signal to a thread would cause it to be marked ready to run, even if it were waiting on something else previously, and then any signal handling functionality would be called from your thread resume code. If I remember from your previous questions you had a function called thread_yield which was called to allow the next thread to run. If this is the case then thread_yield needs to check a list of pending signals and preform their actions before returning to where ever thread_yield was called (unless one of the signal handlers involved killing the current thread, in which case you have to do something different).

As far as how to implement registering of signal handlers, in POSIX that is done by system calls made by the main function (either directly or indirectly). So you could have:

static int foo_flag = 0;

static void foo_handle(int sig) {
     foo_flag = 1;
}

int start_func(void * arg) {
    thread_sig_register(SIGFOO, foo_handle);

    thread_pause();
    // this is a function that you could write that would cause the current thread
    // to mark itself as not ready to run and then call thread_yield, so that
    // thread_pause() will return only after something else (a signal) causes the
    // thread to become ready to run again.


    if (foo_flag) {
        printf("I got SIGFOO\n");
    } else {
        printf("I don't know what woke me up\n");
    }
    return 0;
}

Now, from another thread you can send this thread a SIGFOO (which is just a signal I made up for demonstration purposes).

Each of your thread control blocks (or whatever you are calling them) will have to have a signal handler table (or list, or something) and a pending signal list or a way to mark the signals as pending. The pending signals will be examined (possibly in some priority based order) and the handler action is done for each pending signal before returning to that threads normal code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM