Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
poll_nm.c File Reference
#include "plgetopt.h"
#include "prinit.h"
#include "prio.h"
#include "prlog.h"
#include "prprf.h"
#include "prnetdb.h"
#include "obsolete/probslet.h"
#include "private/pprio.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

Go to the source code of this file.

Defines

#define NUM_ITERATIONS   5

Functions

static void PR_CALLBACK clientThreadFunc (void *arg)
int main (int argc, char **argv)
 The Xalan testcases app.

Variables

PRIntn failed_already = 0
PRIntn debug_mode

Define Documentation

Definition at line 84 of file poll_nm.c.


Function Documentation

static void PR_CALLBACK clientThreadFunc ( void arg) [static]

Definition at line 97 of file poll_nm.c.

{
    PRUintn port = (PRUintn) arg;
    PRFileDesc *sock;
    PRNetAddr addr;
    char buf[128];
    int i;
    PRStatus sts;
    PRInt32 n;

    addr.inet.family = PR_AF_INET;
    addr.inet.port = PR_htons((PRUint16)port);
    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
    memset(buf, 0, sizeof(buf));
    PR_snprintf(buf, sizeof(buf), "%hu", port);

    for (i = 0; i < NUM_ITERATIONS; i++) {
       sock = PR_NewTCPSocket();
       PR_ASSERT(sock != NULL);
       
    sts = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
       PR_ASSERT(sts == PR_SUCCESS);

       n = PR_Write(sock, buf, sizeof(buf));
       PR_ASSERT(n >= 0);

       sts = PR_Close(sock);
       PR_ASSERT(sts == PR_SUCCESS);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

The Xalan testcases app.

Definition at line 128 of file poll_nm.c.

{
    PRFileDesc *listenSock1 = NULL, *listenSock2 = NULL;
    PRUint16 listenPort1, listenPort2;
    PRNetAddr addr;
    char buf[128];
    PRThread *clientThread;
    PRPollDesc pds0[20], pds1[20], *pds, *other_pds;
    PRIntn npds;
    PRInt32 retVal;
    PRIntn i, j;
    PRSocketOptionData optval;

       /* The command line argument: -d is used to determine if the test is being run
       in debug mode. The regress tool requires only one line output:PASS or FAIL.
       All of the printfs associated with this test has been handled with a if (debug_mode)
       test.
       Usage: test_name -d
       */
       PLOptStatus os;
       PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
       while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
              if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 'd':  /* debug mode */
                     debug_mode = 1;
            break;
         default:
            break;
        }
    }
       PL_DestroyOptState(opt);

 /* main test */
       
    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    PR_STDIO_INIT();

#ifdef XP_MAC
       debug_mode = 1;
       SetupMacPrintfLog("poll_nm.log");
#endif

    if (debug_mode) {
              printf("This program tests PR_Poll with sockets.\n");
              printf("Normal operation are tested.\n\n");
       }

    /* Create two listening sockets */
    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
       fprintf(stderr, "Can't create a new TCP socket\n");
       failed_already=1;
       goto exit_now;
    }
    memset(&addr, 0, sizeof(addr));
    addr.inet.family = PR_AF_INET;
    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
    addr.inet.port = PR_htons(0);
    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
       fprintf(stderr, "Can't bind socket\n");
       failed_already=1;
       goto exit_now;
    }
    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
       fprintf(stderr, "PR_GetSockName failed\n");
       failed_already=1;
       goto exit_now;
    }
    listenPort1 = PR_ntohs(addr.inet.port);
    optval.option = PR_SockOpt_Nonblocking;
    optval.value.non_blocking = PR_TRUE;
    PR_SetSocketOption(listenSock1, &optval);
    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
       fprintf(stderr, "Can't listen on a socket\n");
       failed_already=1;
       goto exit_now;
    }

    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
       fprintf(stderr, "Can't create a new TCP socket\n");
       failed_already=1;    
       goto exit_now;
    }
    addr.inet.family = PR_AF_INET;
    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
    addr.inet.port = PR_htons(0);
    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
       fprintf(stderr, "Can't bind socket\n");
       failed_already=1;    
       goto exit_now;
    }
    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
       fprintf(stderr, "PR_GetSockName failed\n");
       failed_already=1;    
       goto exit_now;
    }
    listenPort2 = PR_ntohs(addr.inet.port);
    PR_SetSocketOption(listenSock2, &optval);
    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
       fprintf(stderr, "Can't listen on a socket\n");
       failed_already=1;    
       goto exit_now;
    }
    PR_snprintf(buf, sizeof(buf),
           "The server thread is listening on ports %hu and %hu\n\n",
           listenPort1, listenPort2);
    if (debug_mode) 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;
    /* Add some unused entries to test if they are ignored by PR_Poll() */
    memset(&pds[2], 0, sizeof(pds[2]));
    memset(&pds[3], 0, sizeof(pds[3]));
    memset(&pds[4], 0, sizeof(pds[4]));
    npds = 5;

    clientThread = PR_CreateThread(PR_USER_THREAD,
           clientThreadFunc, (void *) listenPort1,
           PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
           PR_UNJOINABLE_THREAD, 0);
    if (clientThread == NULL) {
       fprintf(stderr, "can't create thread\n");
       failed_already=1;    
       goto exit_now;
    }

    clientThread = PR_CreateThread(PR_USER_THREAD,
           clientThreadFunc, (void *) listenPort2,
           PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
           PR_UNJOINABLE_THREAD, 0);
    if (clientThread == NULL) {
       fprintf(stderr, "can't create thread\n");
       failed_already=1;           
       goto exit_now;
    }

    if (debug_mode) {
              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");
              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");
       }

    /* two clients, three events per iteration: accept, read, close */
    i = 0;
    while (i < 2 * 3 * NUM_ITERATIONS) {
       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");
              failed_already=1;                  
           goto exit_now;
       }

       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");
                     failed_already=1;    
                  goto exit_now;
              }
              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");
              failed_already=1;    
              goto exit_now;
           } 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));
              failed_already=1;    
              goto exit_now;
           }
       }

       for (j = 2; j < npds; j++) {
            if (NULL == pds[j].fd) {
                /*
                 * Keep the unused entries in the poll descriptor array
                 * for testing purposes.
                 */
                other_pds[nextIndex] = pds[j];
                nextIndex++;
                continue;
            }

           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 nAvail;
              PRInt32 nRead;

              nEvents++;
                nAvail = PR_Available(pds[j].fd);
              nRead = PR_Read(pds[j].fd, buf, sizeof(buf));
                PR_ASSERT(nAvail == nRead);
              if (nRead == -1) {
                  fprintf(stderr, "PR_Read() failed\n");
                     failed_already=1;    
                  goto exit_now;
                } else if (nRead == 0) {
                    PR_Close(pds[j].fd);
                    continue;
                } else {
                    /* Just to be safe */
                    buf[127] = '\0';
                    if (debug_mode) 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");
              failed_already=1;                  
              goto exit_now;
           } else if (pds[j].out_flags & PR_POLL_NVAL) {
              fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n");
              failed_already=1;                  
              goto exit_now;
           }
            other_pds[nextIndex] = pds[j];
            nextIndex++;
       }

       PR_ASSERT(retVal == nEvents);
       /* swap */
       tmp = pds;
       pds = other_pds;
       other_pds = tmp;
       npds = nextIndex;
       i += nEvents;
    }

    if (debug_mode) printf("Tests passed\n");

exit_now:

    if (listenSock1) {
        PR_Close(listenSock1);
    }
    if (listenSock2) {
        PR_Close(listenSock2);
    }

    PR_Cleanup();
       
       if(failed_already)   
              return 1;
       else
              return 0;

}

Here is the call graph for this function:


Variable Documentation

PRIntn debug_mode

Definition at line 82 of file poll_nm.c.

PRIntn failed_already = 0

Definition at line 81 of file poll_nm.c.