Date: Mon, 13 Aug 2001 12:04:55 -0400 From: Jonathan Chen <jon@freebsd.org> To: hackers@freebsd.org Subject: pthreads and poll() Message-ID: <20010813120455.A63309@enterprise.spock.org>
next in thread | raw e-mail | index | archive | help
Yesterday marked my first attempt at mixing poll() with pthreads. Needless to say, things did not work out the way I wanted them to. So, I began the task of finding out the behaviors of various OSes to see if my code would run fine on them. For your reference and amusement, my results and test code is included below. I think that waking only one thread up is the correct behavior, or is there something that toggles which behavior I want? Perhaps someone with access to the POSIX standard would care to confirm what the Right Thing is? Perhaps that someone would then proceed to fix all the incorrect implementations... or am I asking too much? :) Looks like I'm going to have to swear off mixing poll() with pthreads for at least two years if I want my code to be portable... Aside: I thought that linuxthreads == Linux's implementation of pthreads? Now why do they behave differently? -Jon FreeBSD4/5 OpenBSD Linux IRIX AIX Solaris8 sys lth 2.8 2.4.1 6.5 4.3 5.8 poll/tcpaccept N Y N N Y N Y poll/udp N Y N Y * N Y poll/file N Y N Y * N Y Legend: FreeBSD tested with system pthread (sys), linuxthreads (lth) and GNU pth (pth). poll/tcpaccept - poll() before accept() of a tcp socket poll/udp - poll() before recv() of a udp socket poll/file - poll() before read() of a named fifo socket Y: only 1 thread wakes up. N: all threads wake up. *: IRIX's behavior seems to be nondeterministic. Perhaps IRIX has some AI to detect the best behavior... Nah... #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <assert.h> #include <sys/types.h> #include <sys/socket.h> #include <poll.h> #include <fcntl.h> #include <netinet/in.h> #include <errno.h> #ifdef _THREAD_SAFE # include <pthread.h> #endif struct pollfd pfd; void* testcode(void* arg) { int ret; struct sockaddr_in addr; int len; char buf[1024]; fprintf(stderr,"thread %d: polling...\n", (int)arg); ret = poll(&pfd, 1, -1); if (ret != 1) fprintf(stderr,"thread %d: bad poll return %d\n", (int)arg, ret); fprintf(stderr,"thread %d: reading...\n", (int)arg); #if defined(TEST_TCP) len = sizeof(struct sockaddr_in); ret = accept(pfd.fd, (struct sockaddr*)&addr, &len); #elif defined(TEST_UDP) ret = recv(pfd.fd, buf, 1024, 0); #elif defined(TEST_READ) ret = read(pfd.fd, buf, 1024); #endif if (ret <= 0) fprintf(stderr,"thread %d: broken return %d %d %s\n", (int)arg, ret, errno, strerror(errno)); fprintf(stderr,"thread %d: exit\n", (int)arg); return 0; } int main(int argc, char* argv[]) { int tmp; #ifdef _THREAD_SAFE pthread_t threads[3]; #endif struct sockaddr_in addr; int len; srandom(time(NULL)); bzero(&addr, sizeof(struct sockaddr_in)); addr.sin_family=AF_INET; len=sizeof(struct sockaddr_in); addr.sin_port=htons(random()%10000+1024); pfd.events = POLLIN; #if defined(TEST_TCP) pfd.fd = socket(PF_INET, SOCK_STREAM, 0); bind(pfd.fd, (struct sockaddr*)&addr, len); listen(pfd.fd, 1); fprintf(stderr,"TCP listening on port %d\n", ntohs(addr.sin_port)); #elif defined(TEST_UDP) pfd.fd = socket(PF_INET, SOCK_DGRAM, 0); bind(pfd.fd, (struct sockaddr*)&addr, len); fprintf(stderr,"UDP listening on port %d\n", ntohs(addr.sin_port)); #elif defined(TEST_READ) pfd.fd = open("/tmp/testfile", O_RDONLY); fprintf(stderr,"File polling on /tmp/testfile\n", 94); #else assert(0); #endif tmp = fcntl(pfd.fd, F_SETFL, O_NONBLOCK); if (tmp != 0) fprintf(stderr, "fcntl returns %d %d %s\n", tmp, errno, strerror(errno)); #ifdef _THREAD_SAFE for (tmp = 0; tmp < 2; tmp++) { pthread_create(&(threads[tmp]), NULL, testcode, (void*)tmp); } #endif testcode((void*)-1); #ifdef _THREAD_SAFE for (tmp = 0; tmp < 2; tmp++) { pthread_join(threads[tmp], NULL); } #endif exit(0); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010813120455.A63309>