> If you edit net/ipv4/tcp.c:tcp_close() and move the
>
> sk->shutdown = SHUTDOWN_MSK
>
> above the
> if (sk->state == LISTEN)
>
> Then I think it will work. Let me know
No, Alan, it will not work. tcp_close() is even never called
in this situation. It will be closed only after select() will
exit 8) And select() will not exit until file will not be closed 8)
The bug is not in networking but in broken file tables design.
The mistake is evident: single fget() for grabbing references
from "users" and for "service" does not work.
The most clean solution is to add second refcnt: f_clntref,
which is grabbed only by clients (f.e. references from file descriptor
tables, from flying via AF_UNIX descriptors, for intrakernel clients etc.)
When f_clntref hits zero, but f_count is not zero, the file is marked
dead and a special method: fops->shutdown() is called, which in the case
of networking equivalent to shutdown(2) (a bit changed to handle
all socket states correctly).
And real fops->release() destroys file after f_count hits zero.
Probably, this way is not the simplest one.
The bug is really disasterous, it prevents porting of wide
class of multithreaded applications. Closing by a monitor thread
is a standard programming technique there. It should be fixed
in one way or another. Actually, I would fix it in softnet, if
not absense of rigid certainty that double refcnt is reallly the best
solution.
Alexey
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/