Date: Thu, 10 Sep 98 13:56:01 -0500 From: "Richard Seaman, Jr." <lists@tar.com> To: "HighWind Software Information" <info@highwind.com> Cc: "freebsd-current@freebsd.org" <freebsd-current@FreeBSD.ORG> Subject: Re: Thread Problems Message-ID: <199809101856.NAA26658@ns.tar.com>
next in thread | raw e-mail | index | archive | help
On Thu, 10 Sep 1998 09:46:24 -0400 (EDT), HighWind Software Information wrote: > >Okay, I coded up a test program that ALWAYS reproduces this accept() >blocking problem we have been talking about. > >Check it out: > >% uname -a >FreeBSD zonda.highwind.com 3.0-19980831-SNAP FreeBSD 3.0-19980831-SNAP #0: Mon Aug 31 14:03:19 GMT 1998 root@make.ican.net:/usr/src/sys/compile/GENERIC i386 > >My libc_r is EXTREMELY up-to-date. ~2 days old. > >The program does the following: > >1. spawns an a thread to loop on "accept" >2. fork/exec's a child talking down a socket pair >3. loops in main() > >To compile: > >g++ -o fbsd -D_REENTRANT -D_THREAD_SAFE -Wall -Werror -g fbsdtest.C -pthread > >To run: > >./fbsd 10000 > >It'll bind to port 10000, and start printing messages on stdout, then >from another window: "telnet localhost 10000". You'll see the main() >thread STOP printing. ONLY the accept() thread will continue to work. > >Help would be greatly appreciated... As indicated in private mail to you earlier, the problem appears to lie in the exec call. Normally the pthreads routines make all fds non-blocking, and simulates blocking via calls to select within the scheduler. The exec call sets the underlying "real" fd to blocking. If you eliminate the forkExec call, it works. If you reverse the order of the forkExec call and the spawnBoundThread call, it works since the fd used in the accept call is created after the exec call, so it is not affected. But, there is a hidden problem in this case in that any fds you might create before the exec call will have had their "true" state set to blocking. Counter intuitively, if you add an fcntl call just before the accept, setting the fd to *blocking*, it works. (This is because the pthread wrapper for fcntl will actually reset the underlying fd to non-blocking so the threads can proceeed). A general work around would appear to be to call fcntl for each open fd after an exec call to gets its state (as maintained by pthreads) set correctly again. Incidentally, the reason this problem doesn't show up before the first accept call is that thread_sys_accept doesn't get called after the exec call until the select call in the scheduler indicates the fd is ready for reading. Once the call to the pthread accept routine is made again the blocking mode takes over. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199809101856.NAA26658>