summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/Makefile32
-rw-r--r--win32/config.bc8
-rw-r--r--win32/config.vc6
-rw-r--r--win32/config_H.bc2
-rw-r--r--win32/config_H.vc2
-rw-r--r--win32/makedef.pl60
-rw-r--r--win32/makefile.mk32
-rw-r--r--win32/win32.c84
-rw-r--r--win32/win32.h30
-rw-r--r--win32/win32io.c24
-rw-r--r--win32/win32io.h10
-rw-r--r--win32/win32iop.h24
-rw-r--r--win32/win32sck.c7
-rw-r--r--win32/win32thread.c31
-rw-r--r--win32/win32thread.h94
15 files changed, 331 insertions, 115 deletions
diff --git a/win32/Makefile b/win32/Makefile
index 19dce90ab9..3e26dfc38f 100644
--- a/win32/Makefile
+++ b/win32/Makefile
@@ -11,6 +11,8 @@
# newly built perl.
INST_DRV=c:
INST_TOP=$(INST_DRV)\perl
+BUILDOPT=-DUSE_THREADS -TP
+CORECCOPT=
#
# uncomment next line if you are using Visual C++ 2.x
@@ -49,8 +51,8 @@ RUNTIME = -MD
!ENDIF
INCLUDES = -I.\include -I. -I..
#PCHFLAGS = -Fp"$(INTDIR)/modules.pch" -YX
-DEFINES = -DWIN32 -D_CONSOLE -DUSE_THREADS -D_WIN32_WINNT=0x400
-LOCDEFS = -DPERLDLL
+DEFINES = -DWIN32 -D_CONSOLE $(BUILDOPT)
+LOCDEFS = -DPERLDLL $(CORECCOPT)
SUBSYS = console
!IF "$(RUNTIME)" == "-MD"
@@ -84,7 +86,7 @@ LIBFILES = oldnames.lib kernel32.lib user32.lib gdi32.lib \
version.lib odbc32.lib odbccp32.lib
CFLAGS = -nologo -W3 $(INCLUDES) $(DEFINES) $(LOCDEFS) $(PCHFLAGS) $(OPTIMIZE)
-LINK_FLAGS = -nologo $(LIBFILES) $(LINK_DBG) -machine:I386
+LINK_FLAGS = -nologo $(LIBFILES) $(LINK_DBG) -machine:$(PROCESSOR_ARCHITECTURE)
OBJOUT_FLAG = -Fo
#################### do not edit below this line #######################
@@ -196,11 +198,13 @@ CORE_OBJ= ..\av.obj \
WIN32_C = perllib.c \
win32.c \
win32io.c \
- win32sck.c
+ win32sck.c \
+ win32thread.c
WIN32_OBJ = win32.obj \
win32io.obj \
- win32sck.obj
+ win32sck.obj \
+ win32thread.obj
PERL95_OBJ = perl95.obj \
win32mt.obj \
@@ -269,7 +273,7 @@ DYNALOADMODULES= \
$(OPCODE_DLL) \
$(SDBM_FILE_DLL)\
$(IO_DLL) \
- $(ATTRS_DLL) \
+ $(ATTRS_DLL) \
$(THREAD_DLL)
POD2HTML=$(PODDIR)\pod2html
@@ -300,9 +304,10 @@ perlglob.obj : perlglob.c
config.w32 : $(CFGSH_TMPL)
copy $(CFGSH_TMPL) config.w32
-.\config.h : $(CFGSH_TMPL)
+.\config.h : $(CFGH_TMPL)
-del /f config.h
copy $(CFGH_TMPL) config.h
+
..\config.sh : config.w32 $(MINIPERL) config_sh.PL
$(MINIPERL) -I..\lib config_sh.PL "INST_DRV=$(INST_DRV)" \
@@ -330,7 +335,7 @@ $(CORE_OBJ) : $(CORE_H)
$(DLL_OBJ) : $(CORE_H)
perldll.def : $(MINIPERL) $(CONFIGPM)
- $(MINIPERL) -w makedef.pl $(CCTYPE) > perldll.def
+ $(MINIPERL) -w makedef.pl $(DEFINES) $(CCTYPE) > perldll.def
$(PERLDLL): perldll.def $(CORE_OBJ) $(WIN32_OBJ) $(DLL_OBJ)
$(LINK32) -dll -def:perldll.def -out:$@ @<<
@@ -357,8 +362,8 @@ $(PERLEXE): $(PERLDLL) $(CONFIGPM) perlmain.obj
del perl.exe
copy splittree.pl ..
$(MINIPERL) -I..\lib ..\splittree.pl "../LIB" "../LIB/auto"
- attrib -r ..\t\*.*
- copy test ..\t
+# attrib -r ..\t\*.*
+# copy test ..\t
perl95.c : runperl.c
copy runperl.c perl95.c
@@ -391,19 +396,20 @@ $(DYNALOADER).c: $(MINIPERL) $(EXTDIR)\DynaLoader\dl_win32.xs $(CONFIGPM)
$(EXTDIR)\DynaLoader\dl_win32.xs: dl_win32.xs
copy dl_win32.xs $(EXTDIR)\DynaLoader\dl_win32.xs
-$(THREAD_DLL): $(PERLEXE) $(THREAD).xs
+$(ATTRS_DLL): $(PERLEXE) $(ATTRS).xs
cd $(EXTDIR)\$(*B)
..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
$(MAKE)
cd ..\..\win32
-$(ATTRS_DLL): $(PERLEXE) $(ATTRS).xs
+$(THREAD_DLL): $(PERLEXE) $(THREAD).xs
cd $(EXTDIR)\$(*B)
..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
$(MAKE)
cd ..\..\win32
-$(IO_DLL): $(PERLEXE) $(IO).xs
+
+$(IO_DLL): $(PERLEXE) $(CONFIGPM) $(IO).xs
cd $(EXTDIR)\$(*B)
..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
$(MAKE)
diff --git a/win32/config.bc b/win32/config.bc
index ad76309e5d..3933c2789c 100644
--- a/win32/config.bc
+++ b/win32/config.bc
@@ -59,7 +59,7 @@ byteorder='1234'
c=''
castflags='0'
cat='type'
-cccdlflags=''
+cccdlflags=' '
ccdlflags=' '
cf_by='garyng'
cf_email='71564.1743@compuserve.com'
@@ -83,7 +83,7 @@ cryptlib=''
csh='undef'
d_Gconvert='gcvt((x),(n),(b))'
d_access='define'
-d_alarm='undef'
+d_alarm='define'
d_archlib='define'
d_attribut='undef'
d_bcmp='undef'
@@ -362,7 +362,7 @@ ksh=''
large=''
ld='tlink32'
lddlflags='-Tpd'
-ldflags=''
+ldflags='~LINK_FLAGS~'
less='less'
lib_ext='.lib'
libc='cw32mti.lib'
@@ -430,7 +430,7 @@ prefixexp='~INST_DRV~'
privlib='~INST_TOP~\lib'
prototype='define'
randbits='15'
-ranlib=''
+ranlib='rem'
rd_nodata='-1'
rm='del'
rmail=''
diff --git a/win32/config.vc b/win32/config.vc
index 7cc91dabd3..2bce3b230e 100644
--- a/win32/config.vc
+++ b/win32/config.vc
@@ -59,7 +59,7 @@ byteorder='1234'
c=''
castflags='0'
cat='type'
-cccdlflags=''
+cccdlflags=' '
ccdlflags=' '
cf_by='garyng'
cf_email='71564.1743@compuserve.com'
@@ -430,7 +430,7 @@ prefixexp='~INST_DRV~'
privlib='~INST_TOP~\lib'
prototype='define'
randbits='15'
-ranlib=''
+ranlib='rem'
rd_nodata='-1'
rm='del'
rmail=''
@@ -463,7 +463,7 @@ spitshell=''
split=''
ssizetype='int'
startperl='#perl'
-stdchar='unsigned char'
+stdchar='char'
stdio_base='((fp)->_base)'
stdio_bufsiz='((fp)->_cnt + (fp)->_ptr - (fp)->_base)'
stdio_cnt='((fp)->_cnt)'
diff --git a/win32/config_H.bc b/win32/config_H.bc
index 61fb5a3241..460b58577c 100644
--- a/win32/config_H.bc
+++ b/win32/config_H.bc
@@ -113,7 +113,7 @@
* This symbol, if defined, indicates that the alarm routine is
* available.
*/
-/*#define HAS_ALARM /**/
+#define HAS_ALARM /**/
/* HASATTRIBUTE:
* This symbol indicates the C compiler can check for function attributes,
diff --git a/win32/config_H.vc b/win32/config_H.vc
index 76f19f1d87..4634072a4e 100644
--- a/win32/config_H.vc
+++ b/win32/config_H.vc
@@ -1400,7 +1400,7 @@
* This symbol is defined to be the type of char used in stdio.h.
* It has the values "unsigned char" or "char".
*/
-#define STDCHAR unsigned char /**/
+#define STDCHAR char /**/
/* Uid_t:
* This symbol holds the type used to declare user ids in the kernel.
diff --git a/win32/makedef.pl b/win32/makedef.pl
index 2ef1bb5dd0..8bc7a8a46a 100644
--- a/win32/makedef.pl
+++ b/win32/makedef.pl
@@ -14,15 +14,18 @@
# that does not present in the WIN32 port but there is no easy
# way to find them so I just put a exception list here
+while (@ARGV && $ARGV[0] =~ /^-/)
+ {
+ my $flag = shift;
+ $define{$1} = 1 if ($flag =~ /^-D(\w+)$/);
+ }
+
+warn join(' ',keys %define)."\n";
+
my $CCTYPE = shift || "MSVC";
$skip_sym=<<'!END!OF!SKIP!';
-Perl_SvIV
-Perl_SvNV
-Perl_SvTRUE
-Perl_SvUV
Perl_block_type
-Perl_sv_pvn
Perl_additem
Perl_cast_ulong
Perl_check_uni
@@ -63,6 +66,7 @@ Perl_force_next
Perl_force_word
Perl_hv_stashpv
Perl_intuit_more
+Perl_init_thread_intern
Perl_know_next
Perl_modkids
Perl_mstats
@@ -83,6 +87,7 @@ Perl_pp_interp
Perl_pp_map
Perl_pp_nswitch
Perl_q
+Perl_rcsid
Perl_reall_srchlen
Perl_regdump
Perl_regfold
@@ -138,6 +143,48 @@ Perl_cshname
Perl_opsave
!END!OF!SKIP!
+unless ($define{'USE_THREADS'})
+ {
+ $skip_sym .= <<'!END!OF!SKIP!';
+Perl_condpair_magic
+Perl_thr_key
+Perl_sv_mutex
+Perl_malloc_mutex
+Perl_eval_mutex
+Perl_eval_cond
+Perl_eval_owner
+Perl_threads_mutex
+Perl_nthreads_cond
+Perl_unlock_condpair
+Perl_vtbl_mutex
+Perl_magic_mutexfree
+Perl_sv_iv
+Perl_sv_nv
+Perl_sv_true
+Perl_sv_uv
+Perl_sv_pvn
+Perl_newRV_noinc
+!END!OF!SKIP!
+ }
+
+if ($define{'USE_THISPTR'} || $define{'USE_THREADS'})
+ {
+ open(THREAD,"<../thread.sym") || die "Cannot open thread.sym:$!";
+ while (<THREAD>)
+ {
+ next if (!/^[A-Za-z]/);
+ next if (/_amg[ \t]*$/);
+ $skip_sym .= "Perl_".$_;
+ }
+ close(THREAD);
+ $skip_sym .= "Perl_op\n";
+ }
+
+unless ($define{'USE_THREADS'})
+ {
+ $skip_sym .= "Perl_thread_create\n";
+ }
+
# All symbols have a Perl_ prefix because that's what embed.h
# sticks in front of them.
@@ -183,6 +230,8 @@ while (<DATA>) {
next if (/^#/);
$symbol = $_;
next if ($skip_sym =~ m/^$symbol/m);
+ $symbol = "Perl_".$symbol if ($define{'USE_THISPTR'}
+ && $symbol =~ /^perl/);
emit_symbol($symbol);
}
@@ -228,6 +277,7 @@ perl_require_pv
perl_eval_pv
perl_eval_sv
boot_DynaLoader
+Perl_thread_create
win32_errno
win32_environ
win32_stdin
diff --git a/win32/makefile.mk b/win32/makefile.mk
index 6a482ba320..655efb7395 100644
--- a/win32/makefile.mk
+++ b/win32/makefile.mk
@@ -10,7 +10,10 @@
# Set these to wherever you want "nmake install" to put your
# newly built perl.
INST_DRV=c:
-INST_TOP=$(INST_DRV)\perl
+INST_TOP=$(INST_DRV)\perl\perl5004.5X
+BUILDOPT=-DUSE_THREADS
+
+# -DUSE_PERLIO -D__STDC__=1 -DUSE_SFIO -DI_SFIO -I\sfio97\include
#
# uncomment one if you are using Visual C++ 2.x or Borland
@@ -25,14 +28,14 @@ CCTYPE=BORLAND
#
# set the install locations of the compiler include/libraries
#CCHOME = f:\msdev\vc
-CCHOME = D:\bc5
+CCHOME = C:\bc5
CCINCDIR = $(CCHOME)\include
CCLIBDIR = $(CCHOME)\lib
#
# set this to point to cmd.exe (only needed if you use some
# alternate shell that doesn't grok cmd.exe style commands)
-SHELL = g:\winnt\system32\cmd.exe
+#SHELL = g:\winnt\system32\cmd.exe
#
# set this to your email address (perl will guess a value from
@@ -60,7 +63,7 @@ IMPLIB = implib
RUNTIME = -D_RTLDLL
INCLUDES = -I.\include -I. -I.. -I$(CCINCDIR)
#PCHFLAGS = -H -H$(INTDIR)\bcmoduls.pch
-DEFINES = -DWIN32 -DUSE_THREADS -D_WIN32_WINNT=0x400
+DEFINES = -DWIN32 $(BUILDOPT)
LOCDEFS = -DPERLDLL
SUBSYS = console
LIBC = cw32mti.lib
@@ -72,7 +75,7 @@ WINIOMAYBE =
OPTIMIZE = -v $(RUNTIME)
LINK_DBG = -v
.ELSE
-OPTIMIZE = -O $(RUNTIME)
+OPTIMIZE = -5 -O2 $(RUNTIME)
LINK_DBG =
.ENDIF
@@ -93,7 +96,7 @@ RUNTIME = -MD
.ENDIF
INCLUDES = -I.\include -I. -I..
#PCHFLAGS = -Fp$(INTDIR)\vcmoduls.pch -YX
-DEFINES = -DWIN32 -D_CONSOLE -DUSE_THREADS -D_WIN32_WINNT=0x400
+DEFINES = -DWIN32 $(BUILDOPT) -D_CONSOLE -D_WIN32_WINNT=0x400
LOCDEFS = -DPERLDLL
SUBSYS = console
@@ -263,11 +266,13 @@ CORE_OBJ= ..\av.obj \
WIN32_C = perllib.c \
win32.c \
win32io.c \
- win32sck.c
+ win32sck.c \
+ win32thread.c
WIN32_OBJ = win32.obj \
win32io.obj \
- win32sck.obj
+ win32sck.obj \
+ win32thread.obj
PERL95_OBJ = perl95.obj \
win32mt.obj \
@@ -374,7 +379,7 @@ perlglob.obj : perlglob.c
config.w32 : $(CFGSH_TMPL)
copy $(CFGSH_TMPL) config.w32
-.\config.h : $(CFGSH_TMPL)
+.\config.h : $(CFGH_TMPL)
-del /f config.h
copy $(CFGH_TMPL) config.h
@@ -383,6 +388,7 @@ config.w32 : $(CFGSH_TMPL)
"INST_TOP=$(INST_TOP)" "cc=$(CC)" "ccflags=$(OPTIMIZE) $(DEFINES)" \
"cf_email=$(EMAIL)" "libs=$(LIBFILES:f)" "incpath=$(CCINCDIR)" \
"libpth=$(strip $(CCLIBDIR) $(LIBFILES:d))" "libc=$(LIBC)" \
+ "LINK_FLAGS=$(LINK_FLAGS)" \
config.w32 > ..\config.sh
$(CONFIGPM) : $(MINIPERL) ..\config.sh config_h.PL ..\minimod.pl
@@ -409,8 +415,8 @@ $(WIN32_OBJ) : $(CORE_H)
$(CORE_OBJ) : $(CORE_H)
$(DLL_OBJ) : $(CORE_H)
-perldll.def : $(MINIPERL) $(CONFIGPM)
- $(MINIPERL) -w makedef.pl $(CCTYPE) > perldll.def
+perldll.def : $(MINIPERL) $(CONFIGPM) ..\global.sym makedef.pl
+ $(MINIPERL) -w makedef.pl $(DEFINES) $(CCTYPE) > perldll.def
$(PERLDLL): perldll.def $(CORE_OBJ) $(WIN32_OBJ) $(DLL_OBJ)
.IF "$(CCTYPE)" == "BORLAND"
@@ -455,8 +461,8 @@ $(PERLEXE): $(PERLDLL) $(CONFIGPM) perlmain.obj
.ENDIF
copy splittree.pl ..
$(MINIPERL) -I..\lib ..\splittree.pl "../LIB" "../LIB/auto"
- attrib -r ..\t\*.*
- copy test ..\t
+# attrib -r ..\t\*.*
+# copy test ..\t
.IF "$(CCTYPE)" != "BORLAND"
diff --git a/win32/win32.c b/win32/win32.c
index 7cbfae8a83..e10bf2b463 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -361,7 +361,7 @@ GetShell(void)
}
int
-do_aspawn(void* really, void** mark, void** arglast)
+do_aspawn(void* really, void ** mark, void ** arglast)
{
char **argv;
char *strPtr;
@@ -524,7 +524,7 @@ opendir(char *filename)
/* char *dummy;*/
/* check to see if filename is a directory */
- if (win32_stat(filename, &sbuf) < 0 || sbuf.st_mode & S_IFDIR == 0) {
+ if (win32_stat(filename, &sbuf) < 0 || (sbuf.st_mode & S_IFDIR) == 0) {
return NULL;
}
@@ -833,26 +833,78 @@ win32_getenv(const char *name)
#endif
+static long
+FileTimeToClock(PFILETIME ft)
+{
+ __int64 qw = ft->dwHighDateTime;
+ qw <<= 32;
+ qw |= ft->dwLowDateTime;
+ qw /= 10000; /* File time ticks at 0.1uS, clock at 1mS */
+ return (long) qw;
+}
+
#undef times
int
mytimes(struct tms *timebuf)
{
- clock_t t = clock();
- timebuf->tms_utime = t;
- timebuf->tms_stime = 0;
- timebuf->tms_cutime = 0;
- timebuf->tms_cstime = 0;
-
+ FILETIME user;
+ FILETIME kernel;
+ FILETIME dummy;
+ if (GetProcessTimes(GetCurrentProcess(), &dummy, &dummy,
+ &kernel,&user)) {
+ timebuf->tms_utime = FileTimeToClock(&user);
+ timebuf->tms_stime = FileTimeToClock(&kernel);
+ timebuf->tms_cutime = 0;
+ timebuf->tms_cstime = 0;
+
+ } else {
+ /* That failed - e.g. Win95 fallback to clock() */
+ clock_t t = clock();
+ timebuf->tms_utime = t;
+ timebuf->tms_stime = 0;
+ timebuf->tms_cutime = 0;
+ timebuf->tms_cstime = 0;
+ }
return 0;
}
+static UINT timerid = 0;
+
+
+static VOID CALLBACK TimerProc(HWND win, UINT msg, UINT id, DWORD time)
+{
+ KillTimer(NULL,timerid);
+ timerid=0;
+ sighandler(14);
+}
+
#undef alarm
unsigned int
myalarm(unsigned int sec)
{
- /* we warn the usuage of alarm function */
- if (sec != 0)
- WARN("dummy function alarm called, program might not function as expected\n");
+ /*
+ * the 'obvious' implentation is SetTimer() with a callback
+ * which does whatever receiving SIGALRM would do
+ * we cannot use SIGALRM even via raise() as it is not
+ * one of the supported codes in <signal.h>
+ *
+ * Snag is unless something is looking at the message queue
+ * nothing happens :-(
+ */
+ if (sec)
+ {
+ timerid = SetTimer(NULL,timerid,sec*1000,(TIMERPROC)TimerProc);
+ if (!timerid)
+ croak("Cannot set timer");
+ }
+ else
+ {
+ if (timerid)
+ {
+ KillTimer(NULL,timerid);
+ timerid=0;
+ }
+ }
return 0;
}
@@ -987,7 +1039,7 @@ win32_fopen(const char *filename, const char *mode)
DllExport FILE *
win32_fdopen( int handle, const char *mode)
{
- return pIOSubSystem->pfnfdopen(handle, mode);
+ return pIOSubSystem->pfnfdopen(handle, (char *) mode);
}
DllExport FILE *
@@ -1205,13 +1257,13 @@ win32_chdir(const char *dir)
DllExport int
win32_spawnvp(int mode, const char *cmdname, const char *const *argv)
{
- return pIOSubSystem->pfnspawnvp(mode, cmdname, argv);
+ return pIOSubSystem->pfnspawnvp(mode, cmdname, (char * const *) argv);
}
DllExport int
win32_execvp(const char *cmdname, const char *const *argv)
{
- return pIOSubSystem->pfnexecvp(cmdname, argv);
+ return pIOSubSystem->pfnexecvp(cmdname, (char *const *)argv);
}
DllExport void
@@ -1637,3 +1689,7 @@ Perl_win32_init(int *argcp, char ***argvp)
_control87(MCW_EM, MCW_EM);
#endif
}
+
+
+
+
diff --git a/win32/win32.h b/win32/win32.h
index dc069ba366..525ef0f6cc 100644
--- a/win32/win32.h
+++ b/win32/win32.h
@@ -52,6 +52,10 @@ typedef long gid_t;
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern uid_t getuid(void);
extern gid_t getgid(void);
extern uid_t geteuid(void);
@@ -61,6 +65,11 @@ extern int setgid(gid_t gid);
extern int kill(int pid, int sig);
+#ifdef __cplusplus
+}
+#endif
+
+
extern char *staticlinkmodules[];
/* if USE_WIN32_RTL_ENV is not defined, Perl uses direct Win32 calls
@@ -79,10 +88,16 @@ extern char *staticlinkmodules[];
EXT char *win32_getenv(const char *name);
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
EXT void Perl_win32_init(int *argcp, char ***argvp);
#define USE_SOCKETS_AS_HANDLES
#ifndef USE_SOCKETS_AS_HANDLES
+
extern FILE *myfdopen(int, char *);
#undef fdopen
@@ -119,11 +134,15 @@ char *win32PerlLibPath(void);
char *win32SiteLibPath(void);
int mytimes(struct tms *timebuf);
unsigned int myalarm(unsigned int sec);
-int do_aspawn(void* really, void** mark, void** arglast);
+int do_aspawn(void* really, void ** mark, void ** arglast);
int do_spawn(char *cmd);
char do_exec(char *cmd);
void init_os_extras(void);
+#ifdef __cplusplus
+}
+#endif
+
typedef char * caddr_t; /* In malloc.c (core address). */
/*
@@ -144,9 +163,18 @@ typedef char * caddr_t; /* In malloc.c (core address). */
#pragma warning(disable: 4018 4035 4101 4102 4244 4245 4761)
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int IsWin95(void);
int IsWinNT(void);
+#ifdef __cplusplus
+}
+#endif
+
+
#ifndef VER_PLATFORM_WIN32_WINDOWS /* VC-2.0 headers dont have this */
#define VER_PLATFORM_WIN32_WINDOWS 1
#endif
diff --git a/win32/win32io.c b/win32/win32io.c
index eeb684620b..0e2e649059 100644
--- a/win32/win32io.c
+++ b/win32/win32io.c
@@ -1,13 +1,11 @@
-#ifdef __cplusplus
-extern "C" {
-#endif
#define WIN32_LEAN_AND_MEAN
+#include <stdio.h>
+extern int my_fclose(FILE *pf);
+#include "EXTERN.h"
#define WIN32IO_IS_STDIO
-#define EXT
#include <windows.h>
-#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <sys/stat.h>
@@ -17,6 +15,16 @@ extern "C" {
#include <errno.h>
#include <process.h>
#include <direct.h>
+
+
+#ifdef __cplusplus
+#define START_EXTERN_C extern "C" {
+#define END_EXTERN_C }
+#else
+#define START_EXTERN_C
+#define END_EXTERN_C
+#endif
+
#include "win32iop.h"
/*
@@ -238,7 +246,6 @@ my_flock(int fd, int oper)
#undef LK_ERR
#undef LK_LEN
-EXT int my_fclose(FILE *pf);
#ifdef PERLDLL
__declspec(dllexport)
@@ -321,7 +328,6 @@ WIN32_IOSUBSYSTEM win32stdio = {
};
-#ifdef __cplusplus
-}
-#endif
+
+
diff --git a/win32/win32io.h b/win32/win32io.h
index ba4080c152..0e849cf783 100644
--- a/win32/win32io.h
+++ b/win32/win32io.h
@@ -3,6 +3,9 @@
#ifdef __BORLANDC__
#include <stdarg.h>
+#define MSconst
+#else
+#define MSconst const
#endif
typedef struct {
@@ -20,7 +23,7 @@ int (*pfnvprintf)(const char *format, va_list arg);
size_t (*pfnfread)(void *buf, size_t size, size_t count, FILE *pf);
size_t (*pfnfwrite)(const void *buf, size_t size, size_t count, FILE *pf);
FILE* (*pfnfopen)(const char *path, const char *mode);
-FILE* (*pfnfdopen)(int fh, const char *mode);
+FILE* (*pfnfdopen)(int fh, MSconst char *mode);
FILE* (*pfnfreopen)(const char *path, const char *mode, FILE *pf);
int (*pfnfclose)(FILE *pf);
int (*pfnfputs)(const char *s,FILE *pf);
@@ -55,12 +58,12 @@ int (*pfnwrite)(int fd, const void *buf, unsigned int cnt);
int (*pfnopenmode)(int mode);
int (*pfn_open_osfhandle)(long handle, int flags);
long (*pfn_get_osfhandle)(int fd);
-int (*pfnspawnvp)(int mode, const char *cmdname, const char *const *argv);
+int (*pfnspawnvp)(int mode, const char *cmdname, MSconst char * const *argv);
int (*pfnmkdir)(const char *path);
int (*pfnrmdir)(const char *path);
int (*pfnchdir)(const char *path);
int (*pfnflock)(int fd, int oper);
-int (*pfnexecvp)(const char *cmdname, const char *const *argv);
+int (*pfnexecvp)(const char *cmdname, MSconst char *const *argv);
void (*pfnperror)(const char *str);
void (*pfnsetbuf)(FILE *pf, char *buf);
int (*pfnsetvbuf)(FILE *pf, char *buf, int type, size_t size);
@@ -85,3 +88,4 @@ int signature_end;
typedef WIN32_IOSUBSYSTEM *PWIN32_IOSUBSYSTEM;
#endif /* WIN32IO_H */
+
diff --git a/win32/win32iop.h b/win32/win32iop.h
index 4606563d0e..52acce1a9b 100644
--- a/win32/win32iop.h
+++ b/win32/win32iop.h
@@ -1,6 +1,15 @@
#ifndef WIN32IOP_H
#define WIN32IOP_H
+/*
+ * defines for flock emulation
+ */
+#define LOCK_SH 1
+#define LOCK_EX 2
+#define LOCK_NB 4
+#define LOCK_UN 8
+
+#include <win32io.h> /* pull in the io sub system structure */
/*
* Make this as close to original stdio as possible.
@@ -9,6 +18,8 @@
/*
* function prototypes for our own win32io layer
*/
+START_EXTERN_C
+
EXT int * win32_errno(void);
EXT char *** win32_environ(void);
EXT FILE* win32_stdin(void);
@@ -81,25 +92,20 @@ EXT void* win32_calloc(size_t numitems, size_t size);
EXT void* win32_realloc(void *block, size_t size);
EXT void win32_free(void *block);
+
+
/*
* these two are win32 specific but still io related
*/
int stolen_open_osfhandle(long handle, int flags);
long stolen_get_osfhandle(int fd);
-/*
- * defines for flock emulation
- */
-#define LOCK_SH 1
-#define LOCK_EX 2
-#define LOCK_NB 4
-#define LOCK_UN 8
-
-#include <win32io.h> /* pull in the io sub system structure */
EXT PWIN32_IOSUBSYSTEM SetIOSubSystem(void *piosubsystem);
EXT PWIN32_IOSUBSYSTEM GetIOSubSystem(void);
+END_EXTERN_C
+
/*
* the following six(6) is #define in stdio.h
*/
diff --git a/win32/win32sck.c b/win32/win32sck.c
index 3653fc8b88..b4ad4f4cfb 100644
--- a/win32/win32sck.c
+++ b/win32/win32sck.c
@@ -702,7 +702,14 @@ win32_setservent(int stayopen)
#define WIN32IO_IS_STDIO
#include <io.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
#include "win32iop.h"
+#ifdef __cplusplus
+}
+#endif
static struct servent*
win32_savecopyservent(struct servent*d, struct servent*s, const char *proto)
diff --git a/win32/win32thread.c b/win32/win32thread.c
index 9f63d178f4..dfa9a0c733 100644
--- a/win32/win32thread.c
+++ b/win32/win32thread.c
@@ -1,10 +1,26 @@
#include "EXTERN.h"
#include "perl.h"
-#include "win32/win32thread.h"
+
+void
+Perl_alloc_thread_key(void)
+{
+#ifdef USE_THREADS
+ static int key_allocated = 0;
+ if (!key_allocated) {
+ if ((thr_key = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+ croak("panic: TlsAlloc");
+ key_allocated = 1;
+ }
+#endif
+}
void
init_thread_intern(struct thread *thr)
{
+#ifdef USE_THREADS
+ /* GetCurrentThread() retrurns a pseudo handle, need
+ this to convert it into a handle another thread can use
+ */
DuplicateHandle(GetCurrentProcess(),
GetCurrentThread(),
GetCurrentProcess(),
@@ -12,19 +28,22 @@ init_thread_intern(struct thread *thr)
0,
FALSE,
DUPLICATE_SAME_ACCESS);
- if ((thr_key = TlsAlloc()) == TLS_OUT_OF_INDEXES)
- croak("panic: TlsAlloc");
- if (TlsSetValue(thr_key, (LPVOID) thr) != TRUE)
- croak("panic: TlsSetValue");
+#endif
}
+#ifdef USE_THREADS
int
-thread_create(struct thread *thr, THREAD_RET_TYPE (*fn)(void *))
+Perl_thread_create(struct thread *thr, thread_func_t *fn)
{
DWORD junk;
MUTEX_LOCK(&thr->mutex);
+ DEBUG_L(PerlIO_printf(PerlIO_stderr(),
+ "%p: create OS thread\n", thr));
thr->self = CreateThread(NULL, 0, fn, (void*)thr, 0, &junk);
+ DEBUG_L(PerlIO_printf(PerlIO_stderr(),
+ "%p: OS thread = %p, id=%ld\n", thr, thr->self, junk));
MUTEX_UNLOCK(&thr->mutex);
return thr->self ? 0 : -1;
}
+#endif
diff --git a/win32/win32thread.h b/win32/win32thread.h
index ab0dbc598f..75aa25b632 100644
--- a/win32/win32thread.h
+++ b/win32/win32thread.h
@@ -1,6 +1,6 @@
-/*typedef CRITICAL_SECTION perl_mutex;*/
-typedef HANDLE perl_mutex;
-typedef HANDLE perl_cond;
+#ifndef _WIN32THREAD_H
+#define _WIN32THREAD_H
+typedef struct win32_cond { LONG waiters; HANDLE sem; } perl_cond;
typedef DWORD perl_key;
typedef HANDLE perl_thread;
@@ -8,12 +8,15 @@ typedef HANDLE perl_thread;
* but can't be communicated to child processes, and can't get
* HANDLE to it for use elsewhere
*/
-/*
+
+#ifndef DONT_USE_CRITICAL_SECTION
+typedef CRITICAL_SECTION perl_mutex;
#define MUTEX_INIT(m) InitializeCriticalSection(m)
#define MUTEX_LOCK(m) EnterCriticalSection(m)
#define MUTEX_UNLOCK(m) LeaveCriticalSection(m)
#define MUTEX_DESTROY(m) DeleteCriticalSection(m)
-*/
+#else
+typedef HANDLE perl_mutex;
#define MUTEX_INIT(m) \
STMT_START { \
@@ -36,38 +39,51 @@ typedef HANDLE perl_thread;
croak("panic: MUTEX_DESTROY"); \
} STMT_END
+#endif
+
+/* These macros assume that the mutex associated with the condition
+ * will always be held before COND_{SIGNAL,BROADCAST,WAIT,DESTROY},
+ * so there's no separate mutex protecting access to (c)->waiters
+ */
#define COND_INIT(c) \
- STMT_START { \
- if ((*(c) = CreateEvent(NULL,TRUE,FALSE,NULL)) == NULL) \
- croak("panic: COND_INIT"); \
+ STMT_START { \
+ (c)->waiters = 0; \
+ (c)->sem = CreateSemaphore(NULL,0,LONG_MAX,NULL); \
+ if ((c)->sem == NULL) \
+ croak("panic: COND_INIT (%ld)",GetLastError()); \
} STMT_END
+
#define COND_SIGNAL(c) \
- STMT_START { \
- if (PulseEvent(*(c)) == 0) \
- croak("panic: COND_SIGNAL (%ld)",GetLastError()); \
+ STMT_START { \
+ if (ReleaseSemaphore((c)->sem,1,NULL) == 0) \
+ croak("panic: COND_SIGNAL (%ld)",GetLastError()); \
} STMT_END
+
#define COND_BROADCAST(c) \
- STMT_START { \
- if (PulseEvent(*(c)) == 0) \
- croak("panic: COND_BROADCAST"); \
+ STMT_START { \
+ if ((c)->waiters > 0 && \
+ ReleaseSemaphore((c)->sem,(c)->waiters,NULL) == 0) \
+ croak("panic: COND_BROADCAST (%ld)",GetLastError());\
} STMT_END
-/* #define COND_WAIT(c, m) \
- STMT_START { \
- if (WaitForSingleObject(*(c),INFINITE) == WAIT_FAILED) \
- croak("panic: COND_WAIT"); \
- } STMT_END
-*/
+
#define COND_WAIT(c, m) \
- STMT_START { \
- if (SignalObjectAndWait(*(m),*(c),INFINITE,FALSE) == WAIT_FAILED)\
- croak("panic: COND_WAIT"); \
- else \
- MUTEX_LOCK(m); \
+ STMT_START { \
+ (c)->waiters++; \
+ MUTEX_UNLOCK(m); \
+ /* Note that there's no race here, since a \
+ * COND_BROADCAST() on another thread will have seen the\
+ * right number of waiters (i.e. including this one) */ \
+ if (WaitForSingleObject((c)->sem,INFINITE)==WAIT_FAILED)\
+ croak("panic: COND_WAIT (%ld)",GetLastError()); \
+ MUTEX_LOCK(m); \
+ (c)->waiters--; \
} STMT_END
+
#define COND_DESTROY(c) \
- STMT_START { \
- if (CloseHandle(*(c)) == 0) \
- croak("panic: COND_DESTROY"); \
+ STMT_START { \
+ (c)->waiters = 0; \
+ if (CloseHandle((c)->sem) == 0) \
+ croak("panic: COND_DESTROY (%ld)",GetLastError()); \
} STMT_END
#define DETACH(t) \
@@ -79,8 +95,22 @@ typedef HANDLE perl_thread;
} STMT_END
#define THR ((struct thread *) TlsGetValue(thr_key))
+#define THREAD_CREATE(t, f) Perl_thread_create(t, f)
+#define THREAD_POST_CREATE(t) NOOP
+#define THREAD_RET_TYPE DWORD WINAPI
+#define THREAD_RET_CAST(p) ((DWORD)(p))
-#define HAVE_THREAD_INTERN
+typedef THREAD_RET_TYPE thread_func_t(void *);
+
+START_EXTERN_C
+void Perl_alloc_thread_key _((void));
+int Perl_thread_create _((struct thread *thr, thread_func_t *fn));
+void Perl_init_thread_intern _((struct thread *thr));
+END_EXTERN_C
+
+#define INIT_THREADS NOOP
+#define ALLOC_THREAD_KEY Perl_alloc_thread_key()
+#define INIT_THREAD_INTERN(thr) Perl_init_thread_intern(thr)
#define JOIN(t, avp) \
STMT_START { \
@@ -95,8 +125,6 @@ typedef HANDLE perl_thread;
croak("panic: TlsSetValue"); \
} STMT_END
-#define THREAD_CREATE(t, f) thread_create(t, f)
-#define THREAD_POST_CREATE(t) NOOP
-#define THREAD_RET_TYPE DWORD WINAPI
-#define THREAD_RET_CAST(p) ((DWORD)(p))
#define YIELD Sleep(0)
+
+#endif /* _WIN32THREAD_H */