tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

prpollml.c (3956B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 /*
      7 * This test exercises the code that allocates and frees the syspoll_list
      8 * array of PRThread in the pthreads version.  This test is intended to be
      9 * run under Purify to verify that there is no memory leak.
     10 */
     11 
     12 #include "nspr.h"
     13 
     14 #include <stdio.h>
     15 #include <stdlib.h>
     16 #include <string.h>
     17 
     18 #define POLL_DESC_COUNT                  \
     19  256 /* This should be greater than the \
     20       * STACK_POLL_DESC_COUNT macro in  \
     21       * ptio.c to cause syspoll_list to \
     22       * be created. */
     23 
     24 static PRPollDesc pd[POLL_DESC_COUNT];
     25 
     26 static void Test(void) {
     27  int i;
     28  PRInt32 rv;
     29  PRIntervalTime timeout;
     30 
     31  timeout = PR_MillisecondsToInterval(10);
     32  /* cause syspoll_list to grow */
     33  for (i = 1; i <= POLL_DESC_COUNT; i++) {
     34    rv = PR_Poll(pd, i, timeout);
     35    if (rv != 0) {
     36      fprintf(stderr, "PR_Poll should time out but returns %d (%d, %d)\n",
     37              (int)rv, (int)PR_GetError(), (int)PR_GetOSError());
     38      exit(1);
     39    }
     40  }
     41  /* syspoll_list should be large enough for all these */
     42  for (i = POLL_DESC_COUNT; i >= 1; i--) {
     43    rv = PR_Poll(pd, i, timeout);
     44    if (rv != 0) {
     45      fprintf(stderr, "PR_Poll should time out but returns %d\n", (int)rv);
     46      exit(1);
     47    }
     48  }
     49 }
     50 
     51 static void ThreadFunc(void* arg) { Test(); }
     52 
     53 int main(int argc, char** argv) {
     54  int i;
     55  PRThread* thread;
     56  PRFileDesc* sock;
     57  PRNetAddr addr;
     58 
     59  memset(&addr, 0, sizeof(addr));
     60  addr.inet.family = PR_AF_INET;
     61  addr.inet.port = PR_htons(0);
     62  addr.inet.ip = PR_htonl(PR_INADDR_ANY);
     63  for (i = 0; i < POLL_DESC_COUNT; i++) {
     64    sock = PR_NewTCPSocket();
     65    if (sock == NULL) {
     66      fprintf(stderr, "PR_NewTCPSocket failed (%d, %d)\n", (int)PR_GetError(),
     67              (int)PR_GetOSError());
     68      fprintf(stderr,
     69              "Ensure the per process file descriptor limit "
     70              "is greater than %d.",
     71              POLL_DESC_COUNT);
     72      exit(1);
     73    }
     74    if (PR_Bind(sock, &addr) == PR_FAILURE) {
     75      fprintf(stderr, "PR_Bind failed (%d, %d)\n", (int)PR_GetError(),
     76              (int)PR_GetOSError());
     77      exit(1);
     78    }
     79    if (PR_Listen(sock, 5) == PR_FAILURE) {
     80      fprintf(stderr, "PR_Listen failed (%d, %d)\n", (int)PR_GetError(),
     81              (int)PR_GetOSError());
     82      exit(1);
     83    }
     84 
     85    pd[i].fd = sock;
     86    pd[i].in_flags = PR_POLL_READ;
     87  }
     88 
     89  /* first run the test on the primordial thread */
     90  Test();
     91 
     92  /* then run the test on all three kinds of threads */
     93  thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL, PR_PRIORITY_NORMAL,
     94                           PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
     95  if (NULL == thread) {
     96    fprintf(stderr, "PR_CreateThread failed\n");
     97    exit(1);
     98  }
     99  if (PR_JoinThread(thread) == PR_FAILURE) {
    100    fprintf(stderr, "PR_JoinThread failed\n");
    101    exit(1);
    102  }
    103  thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL, PR_PRIORITY_NORMAL,
    104                           PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
    105  if (NULL == thread) {
    106    fprintf(stderr, "PR_CreateThread failed\n");
    107    exit(1);
    108  }
    109  if (PR_JoinThread(thread) == PR_FAILURE) {
    110    fprintf(stderr, "PR_JoinThread failed\n");
    111    exit(1);
    112  }
    113  thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL, PR_PRIORITY_NORMAL,
    114                           PR_GLOBAL_BOUND_THREAD, PR_JOINABLE_THREAD, 0);
    115  if (NULL == thread) {
    116    fprintf(stderr, "PR_CreateThread failed\n");
    117    exit(1);
    118  }
    119  if (PR_JoinThread(thread) == PR_FAILURE) {
    120    fprintf(stderr, "PR_JoinThread failed\n");
    121    exit(1);
    122  }
    123  for (i = 0; i < POLL_DESC_COUNT; i++) {
    124    if (PR_Close(pd[i].fd) == PR_FAILURE) {
    125      fprintf(stderr, "PR_Close failed\n");
    126      exit(1);
    127    }
    128  }
    129  PR_Cleanup();
    130  printf("PASS\n");
    131  return 0;
    132 }