1 /* $OpenBSD: blocked_shutdown.c,v 1.2 2012/02/20 17:06:11 kurt Exp $ */ 2 /* 3 * Copyright (c) 2006 Kurt Miller <kurt@intricatesoftware.com> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /* 19 * Test shutdown() racing with other threads using the same file 20 * descriptor, with some of them blocking on data that will never 21 * arrive. 22 */ 23 24 #include <pthread.h> 25 #include <unistd.h> 26 #include <fcntl.h> 27 #include <time.h> 28 #include <sys/types.h> 29 #include <sys/socket.h> 30 #include <netinet/in.h> 31 #include "test.h" 32 33 #define ITERATIONS 100 34 #define WAITING_THREADS 5 35 36 static void * 37 deadlock_detector(void *arg) 38 { 39 sleep(15); 40 PANIC("deadlock detected"); 41 } 42 43 static void * 44 waiting_read(void *arg) 45 { 46 int fd = *(int *)arg; 47 struct sockaddr remote_addr; 48 char readBuf; 49 int n, remote_addr_len = sizeof(struct sockaddr); 50 51 n = recvfrom(fd, &readBuf, 1, 0, &remote_addr, &remote_addr_len); 52 53 if (n == -1) 54 return ((caddr_t)NULL + errno); 55 else 56 return (NULL); 57 } 58 59 int 60 main(int argc, char *argv[]) 61 { 62 pthread_t waiting_threads[WAITING_THREADS]; 63 pthread_t deadlock_thread; 64 struct sockaddr_in addr; 65 int fd, i, j; 66 void *value_ptr; 67 struct timespec rqtp; 68 69 rqtp.tv_sec = 0; 70 rqtp.tv_nsec = 1000000; 71 72 bzero((char *) &addr, sizeof addr); 73 addr.sin_family = AF_INET; 74 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 75 76 CHECKr(pthread_create(&deadlock_thread, NULL, 77 deadlock_detector, NULL)); 78 79 for (i = 0; i < ITERATIONS; i++) { 80 CHECKe(fd = socket(AF_INET, SOCK_DGRAM, 0)); 81 addr.sin_port = htons(0); 82 CHECKr(bind(fd, (struct sockaddr *)&addr, sizeof(addr))); 83 for (j = 0; j < WAITING_THREADS; j++) 84 CHECKr(pthread_create(&waiting_threads[j], NULL, 85 waiting_read, (void *)&fd)); 86 nanosleep(&rqtp, NULL); 87 CHECKr(shutdown(fd, SHUT_RDWR)); 88 for (j = 0; j < WAITING_THREADS; j++) { 89 CHECKr(pthread_join(waiting_threads[j], &value_ptr)); 90 ASSERT(value_ptr == NULL); 91 } 92 CHECKr(close(fd)); 93 } 94 SUCCEED; 95 } 96