| /* Test cancellation of a door_return call. */ |
| |
| #include <assert.h> |
| #include <door.h> |
| #include <errno.h> |
| #include <pthread.h> |
| #include <signal.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <sys/lwp.h> |
| #include <unistd.h> |
| |
| static volatile lwpid_t server_lwpid = 0; |
| |
| static void server_procedure(void *cookie, char *argp, size_t arg_size, |
| door_desc_t *dp, uint_t n_desc) |
| { |
| assert(0); |
| } |
| |
| static void *my_server_thread(void *arg) |
| { |
| server_lwpid = _lwp_self(); |
| door_return(NULL, 0, NULL, 0); |
| return NULL; |
| } |
| |
| static void create_door_thread(door_info_t *info) |
| { |
| static int called = 0; |
| pthread_t thread; |
| int res; |
| |
| /* Allow to create only one server door thread. */ |
| assert(!called); |
| called = 1; |
| |
| res = pthread_create(&thread, NULL, my_server_thread, NULL); |
| if (res) { |
| errno = res; |
| perror("pthread_create"); |
| exit(1); |
| } |
| } |
| |
| static void signal_handler(int signo, siginfo_t *info, void *uc) |
| { |
| const char str[] = "Signal caught.\n"; |
| size_t len = sizeof(str) - 1; |
| ssize_t res; |
| |
| res = write(STDOUT_FILENO, str, len); |
| assert(res == len); |
| } |
| |
| int main(void) |
| { |
| int res = 1; |
| int did = -1; |
| struct sigaction sa; |
| |
| sa.sa_sigaction = signal_handler; |
| sa.sa_flags = SA_RESTART; |
| if (sigfillset(&sa.sa_mask)) { |
| perror("sigfillset"); |
| return 1; |
| } |
| if (sigaction(SIGINT, &sa, NULL)) { |
| perror("sigaction"); |
| return 1; |
| } |
| |
| door_server_create(create_door_thread); |
| |
| if ((did = door_create(server_procedure, NULL, 0)) < 0) { |
| perror("door_create"); |
| return 1; |
| } |
| |
| /* Let the server thread to run. */ |
| sleep(2); |
| |
| /* Send a signal to the server thread that should be already created and |
| blocked in door_return. */ |
| if (_lwp_kill(server_lwpid, SIGINT)) { |
| perror("_lwp_kill"); |
| goto out; |
| } |
| |
| /* Let the other thread to run. */ |
| sleep(2); |
| |
| res = 0; |
| |
| out: |
| if (did >= 0 && door_revoke(did)) |
| perror("door_revoke"); |
| |
| return res; |
| } |
| |