#define taint_env Perl_taint_env
#define taint_proper Perl_taint_proper
#define thisexpr Perl_thisexpr
+#define thr_key Perl_thr_key
#define timesbuf Perl_timesbuf
#define tokenbuf Perl_tokenbuf
#define too_few_arguments Perl_too_few_arguments
#include "perl.h"
#include "XSUB.h"
+#ifdef WIN32
+#define ssize_t int
+#include <fcntl.h>
+#define THR_RET_TYPE DWORD
+#define THR_FUNC_TYPE THR_RET_TYPE WINAPI
+#else
+#define THR_RET_TYPE void *
+#define THR_FUNC_TYPE THR_RET_TYPE
+#endif
+
/* Magic signature for Thread's mg_private is "Th" */
#define Thread_MAGIC_SIGNATURE 0x5468
static U32 threadnum = 0;
static int sig_pipe[2];
+static void remove_thread _((Thread t));
+static THR_FUNC_TYPE threadstart _((void *));
+
static void
remove_thread(t)
Thread t;
MUTEX_UNLOCK(&threads_mutex);
}
-static void *
+
+static THR_FUNC_TYPE
threadstart(arg)
void *arg;
{
* from our pthread_t structure to our struct thread, since we're
* the only thread who can get at it anyway.
*/
+#ifdef WIN32
+ if (TlsSetValue(thr_key, (void *) thr) == 0)
+#else
if (pthread_setspecific(thr_key, (void *) thr))
+#endif
croak("panic: pthread_setspecific");
/* Only now can we use SvPEEK (which calls sv_newmortal which does dTHR) */
croak("panic: illegal state %u at end of threadstart", ThrSTATE(thr));
/* NOTREACHED */
}
- return (void *) returnav; /* Available for anyone to join with us */
+ return (THR_RET_TYPE) returnav;/* Available for anyone to join with us */
/* unless we are detached in which case */
/* noone will see the value anyway. */
#endif
Thread savethread;
int i;
SV *sv;
+#ifndef WIN32
sigset_t fullmask, oldmask;
+#else
+ DWORD junk;
+#endif
savethread = thr;
sv = newSVpv("", 0);
/* Get set...
* Increment the global thread count.
*/
+#ifndef WIN32
sigfillset(&fullmask);
if (sigprocmask(SIG_SETMASK, &fullmask, &oldmask) == -1)
croak("panic: sigprocmask");
if (pthread_create(&self, NULL, threadstart, (void*) thr))
+#else
+ if ((self = CreateThread(NULL,0,threadstart,(void*)thr,0,&junk)) == 0)
+#endif
return NULL; /* XXX should clean up first */
/* Go */
MUTEX_UNLOCK(&thr->mutex);
+#ifndef WIN32
if (sigprocmask(SIG_SETMASK, &oldmask, 0))
croak("panic: sigprocmask");
#endif
+#endif
sv = newSViv(thr->tid);
sv_magic(sv, oursv, '~', 0, 0);
SvMAGIC(sv)->mg_private = Thread_MAGIC_SIGNATURE;
croak("can't join with thread");
/* NOTREACHED */
}
+#ifdef WIN32
+ if ((WaitForSingleObject(t->Tself,INFINITE) == WAIT_FAILED)
+ || (GetExitCodeThread(t->Tself,(LPDWORD)&av) == 0))
+#else
if (pthread_join(t->Tself, (void **) &av))
+#endif
croak("pthread_join failed");
/* Could easily speed up the following if necessary */
pthread_yield();
#else
#ifndef NO_SCHED_YIELD
+#ifdef WIN32
+ Sleep(0); /* same semantics as POSIX sched_yield() */
+#else
sched_yield();
+#endif /* WIN32 */
#endif /* NO_SCHED_YIELD */
#endif /* OLD_PTHREADS_API */
multiline
mystrk
nrs
+nthreads
+nthreads_cond
ofmt
ofs
ofslen
tainted
tainting
thrsv
+threads_mutex
tmps_floor
tmps_ix
tmps_max
"perl_destruct: waiting for %d threads...\n",
nthreads - 1));
for (t = thr->next; t != thr; t = t->next) {
- MUTEX_LOCK(&threads_mutex);
MUTEX_LOCK(&t->mutex);
switch (ThrSTATE(t)) {
AV *av;
.\include\sys\socket.h \
.\win32.h
-EXTENSIONS=DynaLoader Socket IO Fcntl Opcode SDBM_File attrs
+EXTENSIONS=DynaLoader Socket IO Fcntl Opcode SDBM_File attrs Thread
DYNALOADER=$(EXTDIR)\DynaLoader\DynaLoader
SOCKET=$(EXTDIR)\Socket\Socket
SDBM_FILE=$(EXTDIR)\SDBM_File\SDBM_File
IO=$(EXTDIR)\IO\IO
ATTRS=$(EXTDIR)\attrs\attrs
+THREAD=$(EXTDIR)\Thread\Thread
SOCKET_DLL=..\lib\auto\Socket\Socket.dll
FCNTL_DLL=..\lib\auto\Fcntl\Fcntl.dll
SDBM_FILE_DLL=..\lib\auto\SDBM_File\SDBM_File.dll
IO_DLL=..\lib\auto\IO\IO.dll
ATTRS_DLL=..\lib\auto\attrs\attrs.dll
+THREAD_DLL=..\lib\auto\Thread\Thread.dll
STATICLINKMODULES=DynaLoader
DYNALOADMODULES= \
$(OPCODE_DLL) \
$(SDBM_FILE_DLL)\
$(IO_DLL) \
- $(ATTRS_DLL)
+ $(ATTRS_DLL) \
+ $(THREAD_DLL)
POD2HTML=$(PODDIR)\pod2html
POD2MAN=$(PODDIR)\pod2man
$(EXTDIR)\DynaLoader\dl_win32.xs: dl_win32.xs
copy dl_win32.xs $(EXTDIR)\DynaLoader\dl_win32.xs
+$(THREAD_DLL): $(PERLEXE) $(THREAD).xs
+ cd $(EXTDIR)\$(*B)
+ ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+ $(MAKE)
+ cd ..\..\win32
+
$(ATTRS_DLL): $(PERLEXE) $(ATTRS).xs
cd $(EXTDIR)\$(*B)
..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
$(PERLIMPLIB) ..\miniperl.lib $(MINIMOD)
-del /f *.def *.map
-del /f $(SOCKET_DLL) $(IO_DLL) $(SDBM_FILE_DLL) $(FCNTL_DLL) \
- $(OPCODE_DLL) $(ATTRS_DLL)
+ $(OPCODE_DLL) $(ATTRS_DLL) $(THREAD_DLL)
-del /f $(SOCKET).c $(IO).c $(SDBM_FILE).c $(FCNTL).c $(OPCODE).c \
- $(DYNALOADER).c $(ATTRS).c
+ $(DYNALOADER).c $(ATTRS).c $(THREAD).c
-del /f $(PODDIR)\*.html
-del /f $(PODDIR)\*.bat
-del /f ..\config.sh ..\splittree.pl perlmain.c dlutils.c \
.\win32.h
-EXTENSIONS=DynaLoader Socket IO Fcntl Opcode SDBM_File attrs
+EXTENSIONS=DynaLoader Socket IO Fcntl Opcode SDBM_File attrs Thread
DYNALOADER=$(EXTDIR)\DynaLoader\DynaLoader
SOCKET=$(EXTDIR)\Socket\Socket
SDBM_FILE=$(EXTDIR)\SDBM_File\SDBM_File
IO=$(EXTDIR)\IO\IO
ATTRS=$(EXTDIR)\attrs\attrs
+THREAD=$(EXTDIR)\Thread\Thread
SOCKET_DLL=..\lib\auto\Socket\Socket.dll
FCNTL_DLL=..\lib\auto\Fcntl\Fcntl.dll
SDBM_FILE_DLL=..\lib\auto\SDBM_File\SDBM_File.dll
IO_DLL=..\lib\auto\IO\IO.dll
ATTRS_DLL=..\lib\auto\attrs\attrs.dll
+THREAD_DLL=..\lib\auto\Thread\Thread.dll
STATICLINKMODULES=DynaLoader
DYNALOADMODULES= \
$(OPCODE_DLL) \
$(SDBM_FILE_DLL)\
$(IO_DLL) \
- $(ATTRS_DLL)
+ $(ATTRS_DLL) \
+ $(THREAD_DLL)
POD2HTML=$(PODDIR)\pod2html
POD2MAN=$(PODDIR)\pod2man
$(EXTDIR)\DynaLoader\dl_win32.xs: dl_win32.xs
copy dl_win32.xs $(EXTDIR)\DynaLoader\dl_win32.xs
+$(THREAD_DLL): $(PERLEXE) $(THREAD).xs
+ cd $(EXTDIR)\$(*B) && \
+ ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+ cd $(EXTDIR)\$(*B) && $(MAKE)
+
$(ATTRS_DLL): $(PERLEXE) $(ATTRS).xs
cd $(EXTDIR)\$(*B) && \
..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
$(PERLIMPLIB) ..\miniperl.lib $(MINIMOD)
-del /f *.def *.map
-del /f $(SOCKET_DLL) $(IO_DLL) $(SDBM_FILE_DLL) $(FCNTL_DLL) \
- $(OPCODE_DLL) $(ATTRS_DLL)
+ $(OPCODE_DLL) $(ATTRS_DLL) $(THREAD_DLL)
-del /f $(SOCKET).c $(IO).c $(SDBM_FILE).c $(FCNTL).c $(OPCODE).c \
- $(DYNALOADER).c $(ATTRS).c
+ $(DYNALOADER).c $(ATTRS).c $(THREAD).c
-del /f $(PODDIR)\*.html
-del /f $(PODDIR)\*.bat
-del /f ..\config.sh ..\splittree.pl perlmain.c dlutils.c config.h.new