diff --git a/src/sbbs3/threadwrap.c b/src/sbbs3/threadwrap.c
new file mode 100644
index 0000000000000000000000000000000000000000..097f947d95c1b68fa4595024ea9ec2812ee456f7
--- /dev/null
+++ b/src/sbbs3/threadwrap.c
@@ -0,0 +1,91 @@
+/* threadwrap.c */
+
+/* Thread-related cross-platform development wrappers */
+
+/* $Id$ */
+
+/****************************************************************************
+ * @format.tab-size 4		(Plain Text/Source Code File Header)			*
+ * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
+ *																			*
+ * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html		*
+ *																			*
+ * 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; either version 2			*
+ * of the License, or (at your option) any later version.					*
+ * See the GNU General Public License for more details: gpl.txt or			*
+ * http://www.fsf.org/copyleft/gpl.html										*
+ *																			*
+ * Anonymous FTP access to the most recent released source is available at	*
+ * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*
+ *																			*
+ * Anonymous CVS access to the development source and modification history	*
+ * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*
+ * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*
+ *     (just hit return, no password is necessary)							*
+ * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*
+ *																			*
+ * For Synchronet coding style and modification guidelines, see				*
+ * http://www.synchro.net/source.html										*
+ *																			*
+ * You are encouraged to submit any modifications (preferably in Unix diff	*
+ * format) via e-mail to mods@synchro.net									*
+ *																			*
+ * Note: If this box doesn't appear square, then you need to fix your tabs.	*
+ ****************************************************************************/
+
+#include "threadwrap.h"	/* DLLCALL */
+
+/****************************************************************************/
+/* Wrapper for Win32 create/begin thread function							*/
+/* Uses POSIX threads														*/
+/****************************************************************************/
+#if defined(__unix__) && defined(SBBS)
+#if defined(_POSIX_THREADS)
+ulong _beginthread(void( *start_address )( void * )
+		,unsigned stack_size, void *arglist)
+{
+	pthread_t	thread;
+	pthread_attr_t attr;
+
+	pthread_attr_init(&attr);     /* initialize attribute structure */
+
+	/* set thread attributes to PTHREAD_CREATE_DETACHED which will ensure
+	   that thread resources are freed on exit() */
+	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+	if(pthread_create(&thread
+		,&attr	/* default attributes */
+		/* POSIX defines this arg as "void *(*start_address)" */
+		,(void *) start_address
+		,arglist)==0)
+		return((int) thread /* thread handle */);
+
+	return(-1);	/* error */
+}
+#else
+
+#error "Need _beginthread implementation for non-POSIX thread library."
+
+#endif
+
+#endif	/* __unix__ */
+
+/****************************************************************************/
+/* Win32 implementation of POSIX sem_getvalue() function					*/
+/****************************************************************************/
+#ifdef _WIN32
+int DLLCALL sem_getvalue(sem_t* psem, int* val)
+{
+	if(psem==NULL || val==NULL)
+		return(-1);
+
+	if(WaitForSingleObject(*(psem),0)==WAIT_OBJECT_0)
+		*val=1;
+	else
+		*val=0;
+
+	return(0);
+}
+#endif
diff --git a/src/sbbs3/threadwrap.h b/src/sbbs3/threadwrap.h
new file mode 100644
index 0000000000000000000000000000000000000000..24c9fbe18d64baf483b031b352a02067fe26c21c
--- /dev/null
+++ b/src/sbbs3/threadwrap.h
@@ -0,0 +1,105 @@
+/* threadwrap.h */
+
+/* Thread-related cross-platform development wrappers */
+
+/* $Id$ */
+
+/****************************************************************************
+ * @format.tab-size 4		(Plain Text/Source Code File Header)			*
+ * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
+ *																			*
+ * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html		*
+ *																			*
+ * 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; either version 2			*
+ * of the License, or (at your option) any later version.					*
+ * See the GNU General Public License for more details: gpl.txt or			*
+ * http://www.fsf.org/copyleft/gpl.html										*
+ *																			*
+ * Anonymous FTP access to the most recent released source is available at	*
+ * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*
+ *																			*
+ * Anonymous CVS access to the development source and modification history	*
+ * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*
+ * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*
+ *     (just hit return, no password is necessary)							*
+ * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*
+ *																			*
+ * For Synchronet coding style and modification guidelines, see				*
+ * http://www.synchro.net/source.html										*
+ *																			*
+ * You are encouraged to submit any modifications (preferably in Unix diff	*
+ * format) via e-mail to mods@synchro.net									*
+ *																			*
+ * Note: If this box doesn't appear square, then you need to fix your tabs.	*
+ ****************************************************************************/
+
+#ifndef _THREADWRAP_H
+#define _THREADWRAP_H
+
+#include "gen_defs.h"	/* HANDLE */
+
+#ifdef DLLEXPORT
+#undef DLLEXPORT
+#endif
+#ifdef DLLCALL
+#undef DLLCALL
+#endif
+
+#ifdef _WIN32
+	#ifdef WRAPPER_DLL
+		#define DLLEXPORT	__declspec(dllexport)
+	#else
+		#define DLLEXPORT	__declspec(dllimport)
+	#endif
+	#ifdef __BORLANDC__
+		#define DLLCALL __stdcall
+	#else
+		#define DLLCALL
+	#endif
+#else	/* !_WIN32 */
+	#define DLLEXPORT
+	#define DLLCALL
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __unix__
+
+	#include <pthread.h>	/* POSIX threads and mutexes */
+	#include <semaphore.h>	/* POSIX semaphores */
+	ulong _beginthread(void( *start_address )( void * )
+		,unsigned stack_size, void *arglist);
+
+#elif defined(_WIN32)	
+
+	/* POSIX semaphores */
+	typedef HANDLE sem_t;
+	#define sem_init(psem,ps,v)			ResetEvent(*(psem))
+	#define sem_wait(psem)				WaitForSingleObject(*(psem),INFINITE)
+	#define sem_post(psem)				SetEvent(*(psem))
+	#define sem_destroy(psem)			CloseHandle(*(psem))
+	DLLEXPORT int DLLCALL sem_getvalue(sem_t*, int* val);
+
+	/* POSIX mutexes */
+	typedef HANDLE pthread_mutex_t;
+	#define PTHREAD_MUTEX_INITIALIZER	CreateMutex(NULL,FALSE,NULL)
+	#define pthread_mutex_init(pmtx,v)	*(pmtx)=CreateMutex(NULL,FALSE,NULL)
+	#define pthread_mutex_lock(pmtx)	WaitForSingleObject(*(pmtx),INFINITE)
+	#define pthread_mutex_unlock(pmtx)	ReleaseMutex(*(pmtx))
+	#define	pthread_mutex_destroy(pmtx)	CloseHandle(*(pmtx))
+
+#else
+
+	#warning "Need semaphore wrappers."
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* Don't add anything after this line */