home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / pr / tests / io_timeout.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  6.1 KB  |  218 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /*
  20. ** Test socket IO timeouts
  21. **
  22. **
  23. **
  24. **
  25. ** Modification History:
  26. ** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
  27. **             The debug mode will print all of the printfs associated with this test.
  28. **             The regress mode will be the default mode. Since the regress tool limits
  29. **           the output to a one line status:PASS or FAIL,all of the printf statements
  30. **             have been handled with an if (debug_mode) statement. 
  31. ***********************************************************************/
  32. /***********************************************************************
  33. ** Includes
  34. ***********************************************************************/
  35. /* Used to get the command line option */
  36. #include "plgetopt.h"
  37. #include "prttools.h"
  38.  
  39. #include <stdio.h>
  40. #include "nspr.h"
  41.  
  42. #ifdef XP_MAC
  43. #include "prlog.h"
  44. #define printf PR_LogPrint
  45. extern void SetupMacPrintfLog(char *logFile);
  46. #endif
  47.  
  48. #define NUM_THREADS 1
  49. #define BASE_PORT   8000
  50. #define DEFAULT_ACCEPT_TIMEOUT 2
  51.  
  52. typedef struct threadInfo {
  53.     PRInt16 id;
  54.     PRInt16 accept_timeout;
  55.     PRLock *dead_lock;
  56.     PRCondVar *dead_cv;
  57.     PRInt32   *alive;
  58. } threadInfo;
  59.  
  60. void 
  61. thread_main(void *_info)
  62. {
  63.     threadInfo *info = (threadInfo *)_info;
  64.     PRNetAddr listenAddr;
  65.     PRNetAddr clientAddr;
  66.     PRFileDesc *listenSock = NULL;
  67.     PRFileDesc *clientSock;
  68.     PRStatus rv;
  69.  
  70.     printf("thread %d is alive\n", info->id);
  71.  
  72.     listenSock = PR_NewTCPSocket();
  73.     if (!listenSock) {
  74.         printf("unable to create listen socket\n");
  75.         goto dead;
  76.     }
  77.   
  78.     listenAddr.inet.family = AF_INET;
  79.     listenAddr.inet.port = PR_htons(BASE_PORT + info->id);
  80.     listenAddr.inet.ip = PR_htonl(INADDR_ANY);
  81.     rv = PR_Bind(listenSock, &listenAddr);
  82.     if (rv == PR_FAILURE) {
  83.         printf("unable to bind\n");
  84.         goto dead;
  85.     }
  86.  
  87.     rv = PR_Listen(listenSock, 4);
  88.     if (rv == PR_FAILURE) {
  89.         printf("unable to listen\n");
  90.         goto dead;
  91.     }
  92.  
  93.     printf("thread %d going into accept for %d seconds\n", 
  94.         info->id, info->accept_timeout + info->id);
  95.  
  96.     clientSock = PR_Accept(listenSock, &clientAddr, PR_SecondsToInterval(info->accept_timeout +info->id));
  97.  
  98.     if (clientSock == NULL) {
  99.         if (PR_GetError() == PR_IO_TIMEOUT_ERROR)
  100.             printf("PR_Accept() timeout worked!\n");
  101.         else
  102.             printf("TEST FAILED! PR_Accept() returned error %d\n", PR_GetError());
  103.     } else {
  104.         printf ("TEST FAILED! PR_Accept() succeeded?\n");
  105.     PR_Close(clientSock);
  106.     }
  107.  
  108. dead:
  109.     if (listenSock) {
  110.     PR_Close(listenSock);
  111.     }
  112.     PR_Lock(info->dead_lock);
  113.     (*info->alive)--;
  114.     PR_NotifyCondVar(info->dead_cv);
  115.     PR_Unlock(info->dead_lock);
  116.  
  117.     printf("thread %d is dead\n", info->id);
  118. }
  119.  
  120. void
  121. thread_test(PRThreadScope scope, PRInt32 num_threads)
  122. {
  123.     PRInt32 index;
  124.     PRThread *thr;
  125.     PRLock *dead_lock;
  126.     PRCondVar *dead_cv;
  127.     PRInt32 alive;
  128.  
  129.     printf("IO Timeout test started with %d threads\n", num_threads);
  130.  
  131.     dead_lock = PR_NewLock();
  132.     dead_cv = PR_NewCondVar(dead_lock);
  133.     alive = num_threads;
  134.     
  135.     for (index = 0; index < num_threads; index++) {
  136.         threadInfo *info = (threadInfo *)PR_Malloc(sizeof(threadInfo));
  137.  
  138.         info->id = index;
  139.         info->dead_lock = dead_lock;
  140.         info->dead_cv = dead_cv;
  141.         info->alive = &alive;
  142.         info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT;
  143.         
  144.         thr = PR_CreateThread( PR_USER_THREAD,
  145.                                thread_main,
  146.                                (void *)info,
  147.                                PR_PRIORITY_NORMAL,
  148.                                scope,
  149.                                PR_UNJOINABLE_THREAD,
  150.                                0);
  151.  
  152.         if (!thr) {
  153.             PR_Lock(dead_lock);
  154.             alive--;
  155.             PR_Unlock(dead_lock);
  156.         }
  157.     }
  158.  
  159.     PR_Lock(dead_lock);
  160.     while(alive) {
  161.         printf("main loop awake; alive = %d\n", alive);
  162.         PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT);
  163.     }
  164.     PR_Unlock(dead_lock);
  165. }
  166.  
  167. int main(int argc, char **argv)
  168. {
  169.     PRInt32 num_threads = 0;
  170.  
  171.     /* The command line argument: -d is used to determine if the test is being run
  172.     in debug mode. The regress tool requires only one line output:PASS or FAIL.
  173.     All of the printfs associated with this test has been handled with a if (debug_mode)
  174.     test.
  175.     Usage: test_name [-d] [-t <threads>]
  176.     */
  177.     PLOptStatus os;
  178.     PLOptState *opt = PL_CreateOptState(argc, argv, "dt:");
  179.     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
  180.     {
  181.         if (PL_OPT_BAD == os) continue;
  182.         switch (opt->option)
  183.         {
  184.         case 'd':  /* debug mode */
  185.             debug_mode = 1;
  186.             break;
  187.         case 't':  /* threads to involve */
  188.             num_threads = atoi(opt->value);
  189.             break;
  190.          default:
  191.             break;
  192.         }
  193.     }
  194.     PL_DestroyOptState(opt);
  195.  
  196.  /* main test */
  197.     
  198.     if (0 == num_threads)
  199.         num_threads = NUM_THREADS;
  200.  
  201.     PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0);
  202.     PR_STDIO_INIT();
  203.  
  204. #ifdef XP_MAC
  205.     SetupMacPrintfLog("io_timeout.log");
  206.     debug_mode = 1;
  207. #endif
  208.  
  209.     printf("user level test\n");
  210.     thread_test(PR_LOCAL_THREAD, num_threads);
  211.  
  212.     printf("kernel level test\n");
  213.     thread_test(PR_GLOBAL_THREAD, num_threads);
  214.  
  215.     PR_Cleanup();
  216.     return 0;
  217. }
  218.