Skip site navigation (1)Skip section navigation (2)
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>