This patch is an experimental patch for adding locks around non reentrant
libc functions. 5.8 perl will be used in ithreaded modes. Currently it seems
that only certain libc (digital unix + win32) are reentrant safe without
using the _r functions.
As it seems like a major work to convert to _r functions, I did a
threads::safe module that used CORE::GLOBAL to lock() around certain
functions. This approach works on linux for the gm/localtime functions (the
ones I have test on). However the slowdown is extreme.
Our alternatives are.
a) override using CORE::GLOBAL::
b) lock in the pp_ function
c) use _r
This patch is a test for case b, it is much faster than case a, it seems to
be easier to implment than c, (I got the impression that c is very much
work).
Right now I do a static mutex for the function, I am not sure this is
portable (I assume not, but we don't need to support win32 threads since the
libc is reentrant). If we want to do it att boot time where would I put the
init_mutex functions? Can we do some better define magic to handle all the
locks needed? Or do we need to define evry lock?
This patch works, it will make localtime and gmtime be safe on linux (if
compiled with ithreads or threads) but I don't think it should be applied.
Artur
--- pp_sys.c.old Sat Jun 9 19:33:35 2001
+++ pp_sys.c Wed Jun 13 09:53:16 2001
@@ -4298,6 +4298,8 @@
return pp_gmtime();
}
+INIT_PP_GMTIME_MUTEX;
+
PP(pp_gmtime)
{
dSP;
@@ -4307,6 +4309,7 @@
static char *monname[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
if (MAXARG < 1)
(void)time(&when);
else
@@ -4316,6 +4319,8 @@
when = (Time_t)SvIVx(POPs);
#endif
+ LOCK_PP_GMTIME_MUTEX;
+
if (PL_op->op_type == OP_LOCALTIME)
tmbuf = localtime(&when);
else
@@ -4325,8 +4330,11 @@
EXTEND_MORTAL(9);
if (GIMME != G_ARRAY) {
SV *tsv;
- if (!tmbuf)
- RETPUSHUNDEF;
+ if (!tmbuf) {
+ UNLOCK_PP_GMTIME_MUTEX;
+ RETPUSHUNDEF;
+ }
+
tsv = Perl_newSVpvf(aTHX_ "%s %s %2d %02d:%02d:%02d %d",
dayname[tmbuf->tm_wday],
monname[tmbuf->tm_mon],
@@ -4348,6 +4356,7 @@
PUSHs(sv_2mortal(newSViv(tmbuf->tm_yday)));
PUSHs(sv_2mortal(newSViv(tmbuf->tm_isdst)));
}
+ UNLOCK_PP_GMTIME_MUTEX;
RETURN;
}
--- thread.h.old Sat Jun 9 19:33:35 2001
+++ thread.h Wed Jun 13 10:20:55 2001
@@ -358,7 +360,24 @@
#define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
#endif /* USE_THREADS */
+
+#if defined(__linux)
+#define UNSAFE_PP_GMTIME
+#endif
+
+
#endif /* USE_THREADS || USE_ITHREADS */
+
+
+#ifdef UNSAFE_PP_GMTIME
+#define INIT_PP_GMTIME_MUTEX static pthread_mutex_t
pp_gmtime_mutex = PTHREAD_MUTEX_INITIALIZER
+#define LOCK_PP_GMTIME_MUTEX pthread_mutex_lock(&pp_gmtime_mutex)
+#define UNLOCK_PP_GMTIME_MUTEX
pthread_mutex_unlock(&pp_gmtime_mutex)
+#else
+#define INIT_PP_GMTIME_MUTEX
+#define LOCK_PP_GMTIME_MUTEX
+#define UNLOCK_PP_GMTIME_MUTEX
+#endif
#ifndef MUTEX_LOCK
# define MUTEX_LOCK(m)