summaryrefslogtreecommitdiffstats
path: root/lib/base/systhr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/base/systhr.cpp')
-rw-r--r--lib/base/systhr.cpp256
1 files changed, 256 insertions, 0 deletions
diff --git a/lib/base/systhr.cpp b/lib/base/systhr.cpp
new file mode 100644
index 00000000..ac29121a
--- /dev/null
+++ b/lib/base/systhr.cpp
@@ -0,0 +1,256 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/*
+ * systhr.c: Abstracted threading mechanisms
+ *
+ * Rob McCool
+ */
+
+#include "systhr.h"
+#include "ereport.h"
+
+#define USE_NSPR
+#ifdef USE_NSPR
+#include "nspr.h"
+#include "private/prpriv.h"
+extern "C" {
+int32 PR_GetSysfdTableMax(void);
+int32 PR_SetSysfdTableSize(int table_size);
+}
+#endif
+#include "systems.h"
+
+#ifdef THREAD_WIN32
+#include <process.h>
+
+typedef struct {
+ HANDLE hand;
+ DWORD id;
+} sys_thread_s;
+
+#endif
+
+
+
+#if defined (USE_NSPR)
+
+
+#define DEFAULT_STACKSIZE (64*1024)
+
+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
+ /* XXXrobm allocate all the fd's we can... */
+ PR_SetSysfdTableSize(PR_GetSysfdTableMax());
+#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
+