Open Bug 347963 Opened 19 years ago Updated 2 years ago

PR_Interrupt does not interrupt PR_Accept when targetting NT

Categories

(NSPR :: NSPR, defect)

4.6.2
x86
Windows 2000
defect

Tracking

(Not tracked)

People

(Reporter: julien.pierre, Unassigned)

References

(Blocks 1 open bug)

Details

Attachments

(1 file)

I have reason to believe that PR_Interrupt may have problems with other I/O calls as well on the WINNT target. But for now, it should suffice to inspect the function _nt_nonblock_accept in ntio.c . It calls _PR_NTFiberSafeSelect with a NULL timeout argument, which causes it to invoke the native select system call with no timeout, and thus block, without any possibility of NSPR interruption. By contrast, when targetting WIN95 or Unix platforms, this problem does not occur. I have attached a test program that shows the problem. PR_Accept and the program should end within 5 seconds as per NSPR documentation for PR_Interrupt, but they do not.
Code inspection shows that the function socket_io_wait in w95sock.c has provision for interruption by polling every 5 seconds . But the similar function _PR_NTFiberSafeSelect in w32poll.c has no provision for interruption and waits up to the maximum specified timeout, which can be infinite.
In the WINNT configuration, PR_Accept eventually calls the _PR_MD_FAST_ACCEPT function in ntio.c. Then the code may take two paths. One is _nt_nonblock_accept, and the other is AcceptEx. Have you confirmed that this test program and the NSS selfserv test program take the _nt_nonblock_accept code path?
Wan-Teh, Yes, I confirmed that PR_Accept invokes _nt_nonblock_accept in the WINNT configuration.
Blocks: 331413
FYI, this is the stack at which the native accept call is made . _PR_NTFiberSafeSelect(int 0, fd_set * 0x0012fce0, fd_set * 0x00000000, fd_set * 0x00000000, const timeval * 0x00000000) line 79 _nt_nonblock_accept(PRFileDesc * 0x002f61a0, sockaddr * 0x0012ff14, int * 0x0012fe98, unsigned int 4294967295) line 3824 + 20 bytes _PR_MD_FAST_ACCEPT(PRFileDesc * 0x002f61a0, PRNetAddr * 0x0012ff14, unsigned int * 0x0012fe98, unsigned int 4294967295, int 0, void (void *)* 0x00000000, void * 0x00000000) line 1299 + 21 bytes SocketAccept(PRFileDesc * 0x002f61a0, PRNetAddr * 0x0012ff14, unsigned int 4294967295) line 424 + 27 bytes PR_Accept(PRFileDesc * 0x002f61a0, PRNetAddr * 0x0012ff14, unsigned int 4294967295) line 199 + 20 bytes main(int 1, char * * 0x002f4058) line 145 + 16 bytes SELFSERV! mainCRTStartup + 227 bytes KERNEL32! 7c598989() The block of code is if (_PR_IS_NATIVE_THREAD(me)) { ready = _MD_SELECT(nfds, readfds, writefds, exceptfds, timeout); } And _MD_SELECT is #defined to select . I did have NSPR_USE_NATIVE_THREADS_ONLY defined, to make debugging easier. But the hang happens without it too .
passing zero for nfds seems suspect. The block of code I see is 3819 if (timeout == PR_INTERVAL_NO_TIMEOUT) { 3820 while ((sock = accept(osfd, addr, addrlen)) == -1) { 3821 if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 3822 && (!fd->secret->nonblocking)) { 3823 if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL, 3824 NULL)) == -1) { Seems like it might be safer to pass osfd+1 rather than 0 for that first argument to _PR_NTFiberSafeSelect.
In Winsock, fd_set is an array of socket handles rather than a bitmap, so select() ignores the first argument. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/select_2.asp osfd + 1 has the type SOCKET, which is 64-bit in WIN64: [winsock2.h] /* * The new type to be used in all * instances which refer to sockets. */ typedef UINT_PTR SOCKET; and needs to be cast to 'int' for select(). This is why I just pass 0 now.
I also tested with PR_Connect going to an invalid IP address and an infinite timeout. PR_Interrupt was successful interrupting it. Without the interrupting thread, the PR_Connect does not not return. This is even on WINNT. So, this bug may be isolated to PR_Accept; or at least not all I/O functions are uninterruptible on WINNT.
QA Contact: wtchang → nspr

The bug assignee is inactive on Bugzilla, so the assignee is being reset.

Assignee: wtc → nobody
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: