prpollml.c 4.2 KB

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