From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 794 invoked by alias); 15 Apr 2004 03:17:24 -0000 Mailing-List: contact cygwin-help@cygwin.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner@cygwin.com Mail-Followup-To: cygwin@cygwin.com Received: (qmail 776 invoked from network); 15 Apr 2004 03:17:22 -0000 Received: from unknown (HELO emethist.hknet.com) (202.67.240.233) by sources.redhat.com with SMTP; 15 Apr 2004 03:17:22 -0000 Received: from em.no-ip.com (vp187108.hk.uac65.hknet.com [203.169.187.108]) by emethist.hknet.com (Postfix) with ESMTP id AA35C443FF; Thu, 15 Apr 2004 11:17:19 +0800 (HKT) Received: from emnb (emnb [192.168.0.2]) by em.no-ip.com (8.11.6/8.8.7) with SMTP id i3F3Gui09844; Thu, 15 Apr 2004 11:16:56 +0800 Message-ID: <011301c42298$19414da0$0200a8c0@em.noip.com> From: "Enzo Michelangeli" To: Cc: "\"Brian Ford\"" References: <00c901c4220d$47f6eaa0$0200a8c0@em.noip.com> Subject: Re: 1.5.9-1: socket() appears NOT to be thread-safe Date: Thu, 15 Apr 2004 03:17:00 -0000 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-SW-Source: 2004-04/txt/msg00518.txt.bz2 ----- Original Message ----- From: "Brian Ford" To: "Enzo Michelangeli" Cc: Sent: Thursday, April 15, 2004 1:05 AM Subject: Re: 1.5.9-1: socket() appears NOT to be thread-safe > On Wed, 14 Apr 2004, Enzo Michelangeli wrote: > > > While porting to Cygwin the Linux application "sipd" > > (http://www.sxdesign.com/index.php?page=developer&submnu=sipd ), > > which uses pthreads, I noticed that socket() calls issued > > concurrently by several threads often failed, with > > strerror(errno) saying "operation not permitted". Once I > > protected all the calls with mutex locks, such errors > > went away. Is Cygwin's implementation of socket() known to be > > thread-unsafe? > > FWIW, I have seen this symptom as well, primarily on a dual CPU, > Hyperthreaded XP box under 1.5.[8|9]+. In fact, I just confirmed > it still exists in a current CVS build from this morning. > > It seems like a race condition. Running under strace fixes it, > so it has been difficult to isolate. If I have time, I'll try > to look at it again soon. Would you like to work on it together? What I can do for the time being is to provide the testcase that Corinna asked for (attached below). Here are the results: em@emnb ~/unsafesocket $ cc -o unsafesocket unsafesocket.c em@emnb ~/unsafesocket $ ./unsafesocket usage: ./unsafesocket [n|y] em@emnb ~/unsafesocket $ ./unsafesocket n NOT protecting socket() call with mutex: Thread 0: socket() returned 3, strerror(errno)="No error" Thread 1: socket() returned -1, strerror(errno)="Operation not permitted" Thread 2: socket() returned -1, strerror(errno)="Operation not permitted" Thread 3: socket() returned 3, strerror(errno)="No error" em@emnb ~/unsafesocket $ ./unsafesocket n NOT protecting socket() call with mutex: Thread 0: socket() returned -1, strerror(errno)="Operation not permitted" Thread 1: socket() returned 3, strerror(errno)="No error" Thread 2: socket() returned -1, strerror(errno)="Operation not permitted" Thread 3: socket() returned -1, strerror(errno)="Operation not permitted" em@emnb ~/unsafesocket $ ./unsafesocket y Protecting socket() call with mutex: Thread 0: socket() returned 3, strerror(errno)="No error" Thread 1: socket() returned 4, strerror(errno)="No error" Thread 2: socket() returned 5, strerror(errno)="No error" Thread 3: socket() returned 6, strerror(errno)="No error" em@emnb ~/unsafesocket $ By the way, even in case of no error the socket calls return the same value of fd. Is this OK?? Cheers -- Enzo --------- begin unsafesocket.c --------- #include #include #include #include #include #define MAXTHREADS 4 static int sync_with_mutex = 0; struct thrdata { int thrnum; pthread_t t; int socket_fd; int socket_errno; } th[MAXTHREADS]; static void *thread_code(void *p); main(int argc, char *argv[]) { int i; if(argc == 1) { printf("usage: %s [n|y]\n", argv[0]); exit(1); } if(argv[1][0] == 'y' || argv[1][0] == 'Y') { printf("Protecting socket() call with mutex:\n"); sync_with_mutex = 1; } else { printf("NOT protecting socket() call with mutex:\n"); sync_with_mutex = 0; } for(i=0; i 0) close(th[i].socket_fd); } exit(0); } static void *thread_code(void *p) { struct thrdata *pt = (struct thrdata *)p; int fd; struct sockaddr_in sa; static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER; bzero(&(sa), sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port = 1024 + pt->thrnum; if(sync_with_mutex) { pthread_mutex_lock(&__mutex); /* begin critical area */ } fd = socket(AF_INET, SOCK_DGRAM, 0); if(sync_with_mutex) { pthread_mutex_unlock(&__mutex); /* begin critical area */ } /* report results to main thread */ pt->socket_fd = fd; pt->socket_errno = errno; return(NULL); } --------- end unsafesocket.c --------- -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/