| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- /** BEGIN COPYRIGHT BLOCK
- * This Program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; version 2 of the License.
- *
- * This Program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * In addition, as a special exception, Red Hat, Inc. gives You the additional
- * right to link the code of this Program with code not covered under the GNU
- * General Public License ("Non-GPL Code") and to distribute linked combinations
- * including the two, subject to the limitations in this paragraph. Non-GPL Code
- * permitted under this exception must only link to the code of this Program
- * through those well defined interfaces identified in the file named EXCEPTION
- * found in the source code files (the "Approved Interfaces"). The files of
- * Non-GPL Code may instantiate templates or use macros or inline functions from
- * the Approved Interfaces without causing the resulting work to be covered by
- * the GNU General Public License. Only Red Hat, Inc. may make changes or
- * additions to the list of Approved Interfaces. You must obey the GNU General
- * Public License in all respects for all of the Program code and other code used
- * in conjunction with the Program except the Non-GPL Code covered by this
- * exception. If you modify this file, you may extend this exception to your
- * version of the file, but you are not obligated to do so. If you do not wish to
- * provide this exception without modification, you must delete this exception
- * statement from your version and license this file solely under the GPL without
- * exception.
- *
- *
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * END COPYRIGHT BLOCK **/
- /*
- * systhr.c: Abstracted threading mechanisms
- *
- * Rob McCool
- */
- #include "systhr.h"
- #define USE_NSPR
- #ifdef USE_NSPR
- #include "nspr.h"
- #include "private/prpriv.h"
- #ifdef LINUX
- # include <sys/time.h>
- # include <sys/resource.h>
- #else
- /* This declaration should be removed when NSPR newer than v4.6 is picked up,
- which should have the fix for bug 326110
- */
- extern "C" {
- int32 PR_GetSysfdTableMax(void);
- int32 PR_SetSysfdTableSize(int table_size);
- }
- #endif
- #endif
- #include "systems.h"
- #ifdef THREAD_WIN32
- #include <process.h>
- typedef struct {
- HANDLE hand;
- DWORD id;
- } sys_thread_s;
- #endif
- #if defined (USE_NSPR)
- #if defined(__hpux) && defined(__ia64)
- #define DEFAULT_STACKSIZE (256*1024)
- #else
- #define DEFAULT_STACKSIZE (64*1024)
- #endif
- static unsigned long _systhr_stacksize = DEFAULT_STACKSIZE;
- NSAPI_PUBLIC
- void systhread_set_default_stacksize(unsigned long size)
- {
- _systhr_stacksize = size;
- }
- NSPR_BEGIN_EXTERN_C
- NSAPI_PUBLIC SYS_THREAD
- #ifdef UnixWare /* for ANSI C++ standard, see base/systrh.h */
- systhread_start(int prio, int stksz, ArgFn_systhread_start fn, void *arg)
- #else
- systhread_start(int prio, int stksz, void (*fn)(void *), void *arg)
- #endif
- {
- #if (defined(Linux) || defined(SNI) || defined(UnixWare)) && !defined(USE_PTHREADS)
- prio /= 8; /* quick and dirty fix for user thread priority scale problem */
- if (prio > 3) prio = 3;
- #endif
- PRThread *ret = PR_CreateThread(PR_USER_THREAD, (void (*)(void *))fn,
- (void *)arg, (PRThreadPriority)prio,
- PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
- stksz ? stksz : _systhr_stacksize);
- return (void *) ret;
- }
- NSPR_END_EXTERN_C
- NSAPI_PUBLIC SYS_THREAD systhread_current(void)
- {
- return PR_GetCurrentThread();
- }
- NSAPI_PUBLIC void systhread_yield(void)
- {
- /* PR_Yield(); */
- PR_Sleep(PR_INTERVAL_NO_WAIT);
- }
- NSAPI_PUBLIC void systhread_timerset(int usec)
- {
- /* This is an interesting problem. If you ever do turn on interrupts
- * on the server, you're in for lots of fun with NSPR Threads
- PR_StartEvents(usec); */
- }
- NSAPI_PUBLIC
- SYS_THREAD systhread_attach(void)
- {
- PRThread *ret;
- ret = PR_AttachThread(PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL);
- return (void *) ret;
- }
- NSAPI_PUBLIC
- void systhread_detach(SYS_THREAD thr)
- {
- /* XXXMB - this is not correct! */
- PR_DetachThread();
- }
- NSAPI_PUBLIC void systhread_terminate(SYS_THREAD thr)
- {
- /* Should never be here. PR_DestroyThread is no
- * longer used. */
- PR_ASSERT(0);
-
- /* PR_DestroyThread((PRThread *) thr); */
- }
- NSAPI_PUBLIC void systhread_sleep(int milliseconds)
- {
- PR_Sleep(milliseconds);
- }
- NSAPI_PUBLIC void systhread_init(char *name)
- {
- PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
- #ifdef XP_UNIX
- #ifdef LINUX
- /*
- * NSPR 4.6 does not export PR_SetSysfdTableSize
- * and PR_GetSysfdTableMax by mistake (NSPR Bugzilla
- * bug 326110) on platforms that use GCC with symbol
- * visibility, so we have to call the system calls
- * directly.
- */
- {
- struct rlimit rlim;
- if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
- return;
- rlim.rlim_cur = rlim.rlim_max;
- (void) setrlimit(RLIMIT_NOFILE, &rlim);
- }
- #else
- PR_SetSysfdTableSize(PR_GetSysfdTableMax());
- #endif
- #endif
- }
- NSAPI_PUBLIC int systhread_newkey()
- {
- uintn newkey;
- PR_NewThreadPrivateIndex(&newkey, NULL);
- return (newkey);
- }
- NSAPI_PUBLIC void *systhread_getdata(int key)
- {
- return PR_GetThreadPrivate(key);
- }
- NSAPI_PUBLIC void systhread_setdata(int key, void *data)
- {
- PR_SetThreadPrivate(key, data);
- }
- /*
- * Drag in the Java code, so our dynamic library full of it works
- * i.e. force these symbols to load.
- */
- NSAPI_PUBLIC void systhread_dummy(void)
- {
- #ifndef NSPR20
- /* nspr/gc.c */
- PR_InitGC(0,0);
- /* nspr/prsystem.c */
- PR_GetSystemInfo(PR_SI_SYSNAME, 0, 0);
- /* nspr/linker.c */
- PR_GetLibName(0, 0);
- /* nspr/file.c */
- PR_Mkdir(0, 0);
- /* nspr/prnetdb.c */
- PR_gethostbyname(0, 0, 0, 0, 0);
- /* nspr/longlong.c */
- LL_TO_S(LL_ZERO, 0, NULL, 0);
- #endif /* NSPR20 */
- }
- #elif defined(THREAD_WIN32)
- #include <nspr/prthread.h>
- #define DEFAULT_STACKSIZE 262144
- NSPR_BEGIN_EXTERN_C
- NSAPI_PUBLIC
- SYS_THREAD systhread_start(int prio, int stksz, void (*fn)(void *), void *arg)
- {
- sys_thread_s *ret = (sys_thread_s *) MALLOC(sizeof(sys_thread_s));
- if ((ret->hand = (HANDLE)_beginthreadex(NULL, stksz, (unsigned (__stdcall *)(void *))fn,
- arg, 0, &ret->id)) == 0) {
- FREE(ret);
- return NULL;
- }
- return (void *)ret;
- }
- NSPR_END_EXTERN_C
- NSAPI_PUBLIC SYS_THREAD systhread_current(void)
- {
- /* XXXrobm this is busted.... */
- return GetCurrentThread();
- }
- NSAPI_PUBLIC void systhread_timerset(int usec)
- {
- }
- NSAPI_PUBLIC SYS_THREAD systhread_attach(void)
- {
- return NULL;
- }
- NSAPI_PUBLIC void systhread_yield(void)
- {
- systhread_sleep(0);
- }
- NSAPI_PUBLIC void systhread_terminate(SYS_THREAD thr)
- {
- TerminateThread(((sys_thread_s *)thr)->hand, 0);
- }
- NSAPI_PUBLIC void systhread_sleep(int milliseconds)
- {
- /* XXXrobm there must be a better way to do this */
- HANDLE sem = CreateSemaphore(NULL, 1, 4, "sleeper");
- WaitForSingleObject(sem, INFINITE);
- WaitForSingleObject(sem, milliseconds);
- CloseHandle(sem);
- }
- NSAPI_PUBLIC void systhread_init(char *name)
- {
- PR_Init(PR_USER_THREAD, 1, 0);
- }
- NSAPI_PUBLIC int systhread_newkey()
- {
- return TlsAlloc();
- }
- NSAPI_PUBLIC void *systhread_getdata(int key)
- {
- return (void *)TlsGetValue(key);
- }
- NSAPI_PUBLIC void systhread_setdata(int key, void *data)
- {
- TlsSetValue(key, data);
- }
- #endif
|