Jeff, On Mon, 26 Jan 2004 Jeff Trawick wrote : > bug was that there were two places where we tried to close a single file > descriptor... 2nd close would fail with EBADF unless some other thread > had that file descriptor assigned to another file because it got a > socket or file or pipe or whatever after the first close() but before > the second close()... that could cause the 2nd thread to fail to write > data (getting EBADF) or even worse write to some other thread's > socket/pipe/file/whatever if thread 3 got that fd assigned in the mean time
Thanks for your detailed explanation. I really appreciate it. Since then I try to repeat this bug on a real server with 12 CPUs. I wrote a driver program that repeatedly fetch a cgi URL with each time with unique parameters. The server is configured with worker MPM and cgid module. The driver matches the cgi (in fact, "test-cgi" in cgi-bin directory) output with the unique parameter sent and raise error if they don't match. However, I couldn't repeat the bug with such setup. I didn't see any mismatch of cgi output from the driver neither do I saw any error message of bad file descriptor being closed in the error log. I wonder what's wrong with my setup? Maybe the test-cgi isn't running long enough? In fact, I try to understand the cgid source code to understand this file descriptor mishandling. However, I couldn't find any place where this file descriptor, which I assume is tempsock in cgid_handler(), is passed to another thread. The closest place I found was the place where tempsock is placed into a bucket b, and then added to the tail of a brigade bb, then ap_pass_brigade (r->output_filters, bb) is called to pass tempsock to next filter. However, it seems ap_pass_brigade() still executes the filter function within the same thread. In other words, tempsock never escaped this thread. How could a second thread get this file descriptor? Thanks a lot again. -Min
