diff --git a/nsprpub/pr/tests/prpoll.c b/nsprpub/pr/tests/prpoll.c index 5aa86e0bc42..901231600f3 100644 --- a/nsprpub/pr/tests/prpoll.c +++ b/nsprpub/pr/tests/prpoll.c @@ -16,6 +16,10 @@ * Reserved. */ +#ifdef WIN32 +#include +#endif + #include "prinit.h" #include "prio.h" #include "prlog.h" @@ -28,6 +32,9 @@ #include "pprio.h" #endif +#define CLIENT_LOOPS 5 +#define BUF_SIZE 128 + #include #include #include @@ -38,7 +45,7 @@ clientThreadFunc(void *arg) PRUint16 port = (PRUint16) arg; PRFileDesc *sock; PRNetAddr addr; - char buf[128]; + char buf[BUF_SIZE]; int i; addr.inet.family = PR_AF_INET; @@ -61,11 +68,16 @@ int main(int argc, char **argv) PRFileDesc *badFD; PRUint16 listenPort1, listenPort2; PRNetAddr addr; - char buf[128]; + char buf[BUF_SIZE]; PRThread *clientThread; PRPollDesc pds0[10], pds1[10], *pds, *other_pds; PRIntn npds; PRInt32 retVal; + PRInt32 sd, rv; + struct sockaddr_in saddr; + PRIntn saddr_len; + PRUint16 listenPort3; + PRFileDesc *socket_poll_fd; PRIntn i, j; PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); @@ -116,20 +128,42 @@ int main(int argc, char **argv) fprintf(stderr, "Can't listen on a socket\n"); exit(1); } - PR_snprintf(buf, sizeof(buf), - "The server thread is listening on ports %hu and %hu\n\n", - listenPort1, listenPort2); - printf("%s", buf); - /* Set up the poll descriptor array */ pds = pds0; other_pds = pds1; memset(pds, 0, sizeof(pds)); - pds[0].fd = listenSock1; - pds[0].in_flags = PR_POLL_READ; - pds[1].fd = listenSock2; - pds[1].in_flags = PR_POLL_READ; - npds = 2; + npds = 0; + pds[npds].fd = listenSock1; + pds[npds].in_flags = PR_POLL_READ; + npds++; + pds[npds].fd = listenSock2; + pds[npds].in_flags = PR_POLL_READ; + npds++; + + sd = socket(AF_INET, SOCK_STREAM, 0); + PR_ASSERT(sd >= 0); + memset((char *) &saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = htonl(INADDR_ANY); + saddr.sin_port = htons(0); + + rv = bind(sd, (struct sockaddr *)&saddr, sizeof(saddr)); + PR_ASSERT(rv == 0); + saddr_len = sizeof(saddr); + rv = getsockname(sd, (struct sockaddr *) &saddr, &saddr_len); + PR_ASSERT(rv == 0); + listenPort3 = ntohs(saddr.sin_port); + + rv = listen(sd, 5); + PR_ASSERT(rv == 0); + pds[npds].fd = socket_poll_fd = PR_CreateSocketPollFd(sd); + PR_ASSERT(pds[npds].fd); + pds[npds].in_flags = PR_POLL_READ; + npds++; + PR_snprintf(buf, sizeof(buf), + "The server thread is listening on ports %hu, %hu and %hu\n\n", + listenPort1, listenPort2, listenPort3); + printf("%s", buf); /* Testing timeout */ printf("PR_Poll should time out in 5 seconds\n"); @@ -150,19 +184,21 @@ int main(int argc, char **argv) exit(1); } - pds[2].fd = badFD; - pds[2].in_flags = PR_POLL_READ; - npds = 3; + pds[npds].fd = badFD; + pds[npds].in_flags = PR_POLL_READ; + npds++; PR_Close(badFD); /* make the fd bad */ +#if 0 retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT); if (retVal != 1 || (unsigned short) pds[2].out_flags != PR_POLL_NVAL) { fprintf(stderr, "Failed to detect the bad fd: " "PR_Poll returns %d, out_flags is 0x%hx\n", - retVal, pds[2].out_flags); + retVal, pds[npds - 1].out_flags); exit(1); } printf("PR_Poll detected the bad fd. Test passed.\n\n"); - npds = 2; +#endif + npds--; clientThread = PR_CreateThread(PR_USER_THREAD, clientThreadFunc, (void *) listenPort1, @@ -175,97 +211,137 @@ int main(int argc, char **argv) clientThread = PR_CreateThread(PR_USER_THREAD, clientThreadFunc, (void *) listenPort2, - PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); if (clientThread == NULL) { fprintf(stderr, "can't create thread\n"); exit(1); } - printf("Two client threads are created. Each of them will\n"); - printf("send data to one of the two ports the server is listening on.\n"); + clientThread = PR_CreateThread(PR_USER_THREAD, + clientThreadFunc, (void *) listenPort3, + PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (clientThread == NULL) { + fprintf(stderr, "can't create thread\n"); + exit(1); + } + + + printf("Three client threads are created. Each of them will\n"); + printf("send data to one of the three ports the server is listening on.\n"); printf("The data they send is the port number. Each of them send\n"); printf("the data five times, so you should see ten lines below,\n"); printf("interleaved in an arbitrary order.\n"); - /* 20 events total */ + /* 30 events total */ i = 0; - while (i < 20) { - PRPollDesc *tmp; - int nextIndex; - int nEvents = 0; + while (i < 30) { + PRPollDesc *tmp; + int nextIndex; + int nEvents = 0; - retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(retVal != 0); /* no timeout */ - if (retVal == -1) { - fprintf(stderr, "PR_Poll failed\n"); - exit(1); - } - - nextIndex = 2; - /* the two listening sockets */ - for (j = 0; j < 2; j++) { - other_pds[j] = pds[j]; - PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 - && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); - if (pds[j].out_flags & PR_POLL_READ) { - PRFileDesc *sock; - - nEvents++; - sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT); - if (sock == NULL) { - fprintf(stderr, "PR_Accept() failed\n"); - exit(1); + retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(retVal != 0); /* no timeout */ + if (retVal == -1) { + fprintf(stderr, "PR_Poll failed\n"); + exit(1); } - other_pds[nextIndex].fd = sock; - other_pds[nextIndex].in_flags = PR_POLL_READ; - nextIndex++; - } else if (pds[j].out_flags & PR_POLL_ERR) { - fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); - exit(1); - } else if (pds[j].out_flags & PR_POLL_NVAL) { - fprintf(stderr, "PR_Poll() indicates that fd %d is invalid\n", - PR_FileDesc2NativeHandle(pds[j].fd)); - exit(1); - } - } - for (j = 2; j < npds; j++) { - PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 - && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); - if (pds[j].out_flags & PR_POLL_READ) { - PRInt32 nBytes; + nextIndex = 3; + /* the three listening sockets */ + for (j = 0; j < 3; j++) { + other_pds[j] = pds[j]; + PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 + && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); + if (pds[j].out_flags & PR_POLL_READ) { + PRFileDesc *sock; - nEvents++; - nBytes = PR_Read(pds[j].fd, buf, sizeof(buf)); - if (nBytes == -1) { - fprintf(stderr, "PR_Read() failed\n"); - exit(1); + nEvents++; + if (j == 2) { + int newsd; + newsd = accept(PR_FileDesc2NativeHandle(pds[j].fd), NULL, 0); + if (newsd == -1) { + fprintf(stderr, "accept() failed\n"); + exit(1); + } + other_pds[nextIndex].fd = PR_CreateSocketPollFd(newsd); + PR_ASSERT(other_pds[nextIndex].fd); + other_pds[nextIndex].in_flags = PR_POLL_READ; + } else { + sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT); + if (sock == NULL) { + fprintf(stderr, "PR_Accept() failed\n"); + exit(1); + } + other_pds[nextIndex].fd = sock; + other_pds[nextIndex].in_flags = PR_POLL_READ; + } + nextIndex++; + } else if (pds[j].out_flags & PR_POLL_ERR) { + fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); + exit(1); + } else if (pds[j].out_flags & PR_POLL_NVAL) { + fprintf(stderr, "PR_Poll() indicates that fd %d is invalid\n", + PR_FileDesc2NativeHandle(pds[j].fd)); + exit(1); + } } - /* Just to be safe */ - buf[127] = '\0'; - PR_Close(pds[j].fd); - printf("The server received \"%s\" from a client\n", buf); - } else if (pds[j].out_flags & PR_POLL_ERR) { - fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); - exit(1); - } else if (pds[j].out_flags & PR_POLL_NVAL) { - fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n"); - exit(1); - } else { - other_pds[nextIndex] = pds[j]; - nextIndex++; - } - } - PR_ASSERT(retVal == nEvents); - /* swap */ - tmp = pds; - pds = other_pds; - other_pds = tmp; - npds = nextIndex; - i += nEvents; + for (j = 3; j < npds; j++) { + PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 + && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); + if (pds[j].out_flags & PR_POLL_READ) { + PRInt32 nBytes; + + nEvents++; + if (PR_GetDescType(pds[j].fd) == PR_DESC_SOCKET_POLL) { + nBytes = recv(PR_FileDesc2NativeHandle(pds[j].fd), buf, + sizeof(buf), 0); + if (nBytes == -1) { + fprintf(stderr, "recv() failed\n"); + exit(1); + } + printf("Server read %d bytes from native fd %d\n",nBytes, + PR_FileDesc2NativeHandle(pds[j].fd)); +#ifdef WIN32 + closesocket((SOCKET)PR_FileDesc2NativeHandle(pds[j].fd)); +#else + close(PR_FileDesc2NativeHandle(pds[j].fd)); +#endif + PR_DestroySocketPollFd(pds[j].fd); + } else { + nBytes = PR_Read(pds[j].fd, buf, sizeof(buf)); + if (nBytes == -1) { + fprintf(stderr, "PR_Read() failed\n"); + exit(1); + } + PR_Close(pds[j].fd); + } + /* Just to be safe */ + buf[BUF_SIZE - 1] = '\0'; + printf("The server received \"%s\" from a client\n", buf); + } else if (pds[j].out_flags & PR_POLL_ERR) { + fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); + exit(1); + } else if (pds[j].out_flags & PR_POLL_NVAL) { + fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n"); + exit(1); + } else { + other_pds[nextIndex] = pds[j]; + nextIndex++; + } + } + + PR_ASSERT(retVal == nEvents); + /* swap */ + tmp = pds; + pds = other_pds; + other_pds = tmp; + npds = nextIndex; + i += nEvents; } + PR_DestroySocketPollFd(socket_poll_fd); printf("All tests finished\n"); PR_Cleanup();