From owner-freebsd-bugs Wed May 1 18:40:15 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 862F137B419 for ; Wed, 1 May 2002 18:40:01 -0700 (PDT) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g421e1M44993; Wed, 1 May 2002 18:40:01 -0700 (PDT) (envelope-from gnats) Received: from mailman.packetdesign.com (dns.packetdesign.com [65.192.41.10]) by hub.freebsd.org (Postfix) with ESMTP id 659A737B405 for ; Wed, 1 May 2002 18:30:42 -0700 (PDT) Received: from bubba.packetdesign.com (bubba.packetdesign.com [192.168.0.223]) by mailman.packetdesign.com (8.11.6/8.11.6) with ESMTP id g421Ugj60548 for ; Wed, 1 May 2002 18:30:42 -0700 (PDT) (envelope-from archie@packetdesign.com) Received: (from archie@localhost) by bubba.packetdesign.com (8.11.6/8.11.6) id g421UfB04028; Wed, 1 May 2002 18:30:41 -0700 (PDT) (envelope-from archie) Message-Id: <200205020130.g421UfB04028@bubba.packetdesign.com> Date: Wed, 1 May 2002 18:30:41 -0700 (PDT) From: Archie Cobbs Reply-To: Archie Cobbs To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: bin/37658: libc_r: poll(2) does not wake up when thread canceled Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >Number: 37658 >Category: bin >Synopsis: libc_r: poll(2) does not wake up when thread canceled >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed May 01 18:40:01 PDT 2002 >Closed-Date: >Last-Modified: >Originator: Archie Cobbs >Release: FreeBSD 4.5-RELEASE i386 >Organization: Packet Design >Environment: System: FreeBSD bubba.packetdesign.com 4.5-RELEASE FreeBSD 4.5-RELEASE #0: Sun Feb 3 10:00:07 PST 2002 archie@bubba.packetdesign.com:/usr/obj/usr/src/sys/BUBBA i386 >Description: Have a thread block in poll(2), which is a cancellation point. Have another thread cancel that thread with pthread_cancel(). Problem: the cancellation does not take effect until the poll(2) returns, which can be arbitrarily long in the future or even never! >How-To-Repeat: Run this program - it should exit in 2 seconds, but it actually takes 4 --------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #define MAIN_WAIT 2 #define THREAD_WAIT 4 static void thread_final(void *arg) { printf("Thread: exiting...\n"); } static void * thread_main(void *arg) { struct pollfd pfd; pthread_cleanup_push(thread_final, NULL); memset(&pfd, 0, sizeof(pfd)); pfd.fd = 0; pfd.events = POLLERR; printf("Thread: polling for %d seconds...\n", THREAD_WAIT); if (poll(&pfd, 1, THREAD_WAIT * 1000) == -1) err(1, "poll"); return (NULL); } int main(int argc, char **argv) { pthread_t tid; printf(" Demonstration of bug in poll(2) where canceling a thread doesn't immediately wake it up from a poll(2). "); /* Spawn thread */ printf("Main: spawning thread...\n"); if ((errno = pthread_create(&tid, NULL, thread_main, NULL)) != 0) err(1, "pthread_create"); /* Pause */ printf("Main: sleeping %d seconds...\n", MAIN_WAIT); sleep(MAIN_WAIT); /* Cancel thread */ printf("Main: canceling thread...\n"); pthread_cancel(tid); printf("Main: joining thread...\n"); pthread_join(tid, NULL); /* Done */ printf("Main: exiting...\n"); return (0); } --------------------------------------------------------------------------- >Fix: Looks like the PTHREAD_AT_CANCEL_POINT flag needs to be set for the current thread in the libc_r version of poll(2). NOTE: there may be other system calls with this same problem. Perhaps a quick audit should be done. >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message