nsprpub/pr/tests/foreign.c

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

     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/. */
     6 /*
     7 ** File:        foreign.c
     8 ** Description: Testing various functions w/ foreign threads
     9 **
    10 **      We create a thread and get it to call exactly one runtime function.
    11 **      The thread is allowed to be created by some other environment that
    12 **      NSPR, but it does not announce itself to the runtime prior to calling
    13 **      in.
    14 **
    15 **      The goal: try to survive.
    16 **      
    17 */
    19 #include "prcvar.h"
    20 #include "prenv.h"
    21 #include "prerror.h"
    22 #include "prinit.h"
    23 #include "prinrval.h"
    24 #include "prio.h"
    25 #include "prlock.h"
    26 #include "prlog.h"
    27 #include "prmem.h"
    28 #include "prthread.h"
    29 #include "prtypes.h"
    30 #include "prprf.h"
    31 #include "plgetopt.h"
    33 #include <stdio.h>
    34 #include <stdlib.h>
    36 static enum {
    37     thread_nspr, thread_pthread, thread_sproc, thread_win32
    38 } thread_provider;
    40 typedef void (*StartFn)(void*);
    41 typedef struct StartObject
    42 {
    43     StartFn start;
    44     void *arg;
    45 } StartObject;
    47 static PRFileDesc *output;
    49 static int _debug_on = 0;
    51 #define DEFAULT_THREAD_COUNT	10
    53 #define DPRINTF(arg)	if (_debug_on) PR_fprintf arg
    55 #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
    56 #include <pthread.h>
    57 #include "md/_pth.h"
    58 static void *pthread_start(void *arg)
    59 {
    60     StartFn start = ((StartObject*)arg)->start;
    61     void *data = ((StartObject*)arg)->arg;
    62     PR_Free(arg);
    63     start(data);
    64     return NULL;
    65 }  /* pthread_start */
    66 #endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */
    68 #if defined(IRIX) && !defined(_PR_PTHREADS)
    69 #include <sys/types.h>
    70 #include <sys/prctl.h>
    71 static void sproc_start(void *arg, PRSize size)
    72 {
    73     StartObject *so = (StartObject*)arg;
    74     StartFn start = so->start;
    75     void *data = so->arg;
    76     PR_Free(so);
    77     start(data);
    78 }  /* sproc_start */
    79 #endif  /* defined(IRIX) && !defined(_PR_PTHREADS) */
    81 #if defined(WIN32)
    82 #include <windows.h>
    83 #include <process.h>  /* for _beginthreadex() */
    85 static PRUintn __stdcall windows_start(void *arg)
    86 {
    87     StartObject *so = (StartObject*)arg;
    88     StartFn start = so->start;
    89     void *data = so->arg;
    90     PR_Free(so);
    91     start(data);
    92     return 0;
    93 }  /* windows_start */
    94 #endif /* defined(WIN32) */
    96 static PRStatus NSPRPUB_TESTS_CreateThread(StartFn start, void *arg)
    97 {
    98     PRStatus rv;
   100     switch (thread_provider)
   101     {
   102     case thread_nspr:
   103         {
   104             PRThread *thread = PR_CreateThread(
   105                 PR_USER_THREAD, start, arg,
   106                 PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
   107                 PR_UNJOINABLE_THREAD, 0);
   108             rv = (NULL == thread) ? PR_FAILURE : PR_SUCCESS;
   109         }
   110         break;
   111     case thread_pthread:
   112 #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
   113         {
   114             int rv;
   115             pthread_t id;
   116             pthread_attr_t tattr;
   117             StartObject *start_object;
   118             start_object = PR_NEW(StartObject);
   119             PR_ASSERT(NULL != start_object);
   120             start_object->start = start;
   121             start_object->arg = arg;
   123             rv = _PT_PTHREAD_ATTR_INIT(&tattr);
   124             PR_ASSERT(0 == rv);
   126             rv = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
   127             PR_ASSERT(0 == rv);
   129             rv = pthread_attr_setstacksize(&tattr, 64 * 1024);
   130             PR_ASSERT(0 == rv);
   132             rv = _PT_PTHREAD_CREATE(&id, tattr, pthread_start, start_object);
   133             (void)_PT_PTHREAD_ATTR_DESTROY(&tattr);
   134             return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
   135         }
   136 #else
   137         PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
   138         rv = PR_FAILURE;
   139         break;
   140 #endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */
   142     case thread_sproc:
   143 #if defined(IRIX) && !defined(_PR_PTHREADS)
   144         {
   145             PRInt32 pid;
   146             StartObject *start_object;
   147             start_object = PR_NEW(StartObject);
   148             PR_ASSERT(NULL != start_object);
   149             start_object->start = start;
   150             start_object->arg = arg;
   151             pid = sprocsp(
   152                 sproc_start, PR_SALL, start_object, NULL, 64 * 1024);
   153             rv = (0 < pid) ? PR_SUCCESS : PR_FAILURE;
   154         }
   155 #else
   156         PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
   157         rv = PR_FAILURE;
   158 #endif  /* defined(IRIX) && !defined(_PR_PTHREADS) */
   159         break;
   160     case thread_win32:
   161 #if defined(WIN32)
   162         {
   163             void *th;
   164             PRUintn id;       
   165             StartObject *start_object;
   166             start_object = PR_NEW(StartObject);
   167             PR_ASSERT(NULL != start_object);
   168             start_object->start = start;
   169             start_object->arg = arg;
   170             th = (void*)_beginthreadex(
   171                 NULL, /* LPSECURITY_ATTRIBUTES - pointer to thread security attributes */  
   172                 0U, /* DWORD - initial thread stack size, in bytes */
   173                 windows_start, /* LPTHREAD_START_ROUTINE - pointer to thread function */
   174                 start_object, /* LPVOID - argument for new thread */
   175                 STACK_SIZE_PARAM_IS_A_RESERVATION, /*DWORD dwCreationFlags - creation flags */
   176                 &id /* LPDWORD - pointer to returned thread identifier */ );
   178             rv = (NULL == th) ? PR_FAILURE : PR_SUCCESS;
   179         }
   180 #else
   181         PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
   182         rv = PR_FAILURE;
   183 #endif
   184         break;
   185     default:
   186         PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
   187         rv = PR_FAILURE;
   188     }
   189     return rv;
   190 }  /* NSPRPUB_TESTS_CreateThread */
   192 static void PR_CALLBACK lazyEntry(void *arg)
   193 {
   194     PR_ASSERT(NULL == arg);
   195 }  /* lazyEntry */
   198 static void OneShot(void *arg)
   199 {
   200     PRUintn pdkey;
   201     PRLock *lock;
   202     PRFileDesc *fd;
   203     PRDir *dir;
   204     PRFileDesc *pair[2];
   205     PRIntn test = (PRIntn)arg;
   207 	for (test = 0; test < 12; ++test) {
   209     switch (test)
   210     {
   211         case 0:
   212             lock = PR_NewLock(); 
   213 			DPRINTF((output,"Thread[0x%x] called PR_NewLock\n",
   214 			PR_GetCurrentThread()));
   215             PR_DestroyLock(lock);
   216             break;
   218         case 1:
   219             (void)PR_SecondsToInterval(1);
   220 			DPRINTF((output,"Thread[0x%x] called PR_SecondsToInterval\n",
   221 			PR_GetCurrentThread()));
   222             break;
   224         case 2: (void)PR_CreateThread(
   225             PR_USER_THREAD, lazyEntry, NULL, PR_PRIORITY_NORMAL,
   226             PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); 
   227 			DPRINTF((output,"Thread[0x%x] called PR_CreateThread\n",
   228 			PR_GetCurrentThread()));
   229             break;
   231         case 3:
   232             fd = PR_Open("foreign.tmp", PR_CREATE_FILE | PR_RDWR, 0666); 
   233 			DPRINTF((output,"Thread[0x%x] called PR_Open\n",
   234 			PR_GetCurrentThread()));
   235             PR_Close(fd);
   236             break;
   238         case 4:
   239             fd = PR_NewUDPSocket(); 
   240 			DPRINTF((output,"Thread[0x%x] called PR_NewUDPSocket\n",
   241 			PR_GetCurrentThread()));
   242             PR_Close(fd);
   243             break;
   245         case 5:
   246             fd = PR_NewTCPSocket(); 
   247 			DPRINTF((output,"Thread[0x%x] called PR_NewTCPSocket\n",
   248 			PR_GetCurrentThread()));
   249             PR_Close(fd);
   250             break;
   252         case 6:
   253 #ifdef SYMBIAN
   254 #define TEMP_DIR "c:\\data\\"
   255 #else
   256 #define TEMP_DIR "/tmp/"
   257 #endif
   258             dir = PR_OpenDir(TEMP_DIR);
   259 			DPRINTF((output,"Thread[0x%x] called PR_OpenDir\n",
   260 			PR_GetCurrentThread()));
   261             PR_CloseDir(dir);
   262             break;
   264         case 7:
   265             (void)PR_NewThreadPrivateIndex(&pdkey, NULL);
   266 			DPRINTF((output,"Thread[0x%x] called PR_NewThreadPrivateIndex\n",
   267 			PR_GetCurrentThread()));
   268             break;
   270         case 8:
   271             (void)PR_GetEnv("PATH");
   272 			DPRINTF((output,"Thread[0x%x] called PR_GetEnv\n",
   273 			PR_GetCurrentThread()));
   274             break;
   276         case 9:
   277             (void)PR_NewTCPSocketPair(pair);
   278 			DPRINTF((output,"Thread[0x%x] called PR_NewTCPSocketPair\n",
   279 			PR_GetCurrentThread()));
   280             PR_Close(pair[0]);
   281             PR_Close(pair[1]);
   282             break;
   284         case 10:
   285             PR_SetConcurrency(2);
   286 			DPRINTF((output,"Thread[0x%x] called PR_SetConcurrency\n",
   287 			PR_GetCurrentThread()));
   288             break;
   290         case 11:
   291             PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_HIGH);
   292 			DPRINTF((output,"Thread[0x%x] called PR_SetThreadPriority\n",
   293 			PR_GetCurrentThread()));
   294             break;
   296         default: 
   297             break;
   298     } /* switch() */
   299 	}
   300 }  /* OneShot */
   302 int main(int argc, char **argv)
   303 {
   304     PRStatus rv;
   305 	PRInt32	thread_cnt = DEFAULT_THREAD_COUNT;
   306 	PLOptStatus os;
   307 	PLOptState *opt = PL_CreateOptState(argc, argv, "dt:");
   309 #if defined(WIN32)
   310 	thread_provider = thread_win32;
   311 #elif defined(_PR_PTHREADS)
   312 	thread_provider = thread_pthread;
   313 #elif defined(IRIX)
   314 	thread_provider = thread_sproc;
   315 #else
   316     thread_provider = thread_nspr;
   317 #endif
   320 	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
   321     {
   322 		if (PL_OPT_BAD == os) continue;
   323         switch (opt->option)
   324         {
   325         case 'd':  /* debug mode */
   326 			_debug_on = 1;
   327             break;
   328         case 't':  /* thread count */
   329             thread_cnt = atoi(opt->value);
   330             break;
   331          default:
   332             break;
   333         }
   334     }
   335 	PL_DestroyOptState(opt);
   337 	PR_SetConcurrency(2);
   339 	output = PR_GetSpecialFD(PR_StandardOutput);
   341     while (thread_cnt-- > 0)
   342     {
   343         rv = NSPRPUB_TESTS_CreateThread(OneShot, (void*)thread_cnt);
   344         PR_ASSERT(PR_SUCCESS == rv);
   345         PR_Sleep(PR_MillisecondsToInterval(5));
   346     }
   347     PR_Sleep(PR_SecondsToInterval(3));
   348     return (PR_SUCCESS == PR_Cleanup()) ? 0 : 1;
   349 }  /* main */
   351 /* foreign.c */

mercurial