Integrate:
Jarkko Hietaniemi [Tue, 1 Apr 2003 16:36:52 +0000 (16:36 +0000)]
[ 19119]
Address "5.8.1@19053: crypt_r() takes 128K per thread".
p4raw-link: @19119 on //depot/maint-5.8/perl: 5338c2bbd71426ba96ace22615fafeda3d05e36d
p4raw-link: @19053 on //depot/maint-5.8/perl: dab75801826d3b09804fff099d3631e91578dcd1

p4raw-id: //depot/perl@19122
p4raw-integrated: from //depot/maint-5.8/perl@19121 'copy in' reentr.c
reentr.h reentr.pl (@19106..) 'merge in' pp.c (@19045..)

pp.c
reentr.c
reentr.h
reentr.pl

diff --git a/pp.c b/pp.c
index 37277e4..524ed24 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -3418,6 +3418,24 @@ PP(pp_crypt)
         sv_utf8_downgrade(tsv, FALSE);
         tmps = SvPVX(tsv);
     }
+#   ifdef USE_ITHREADS
+#     ifdef HAS_CRYPT_R
+    if (!PL_reentrant_buffer->_crypt_struct_buffer) {
+      /* This should be threadsafe because in ithreads there is only
+       * one thread per interpreter.  If this would not be true,
+       * we would need a mutex to protect this malloc. */
+        PL_reentrant_buffer->_crypt_struct_buffer =
+         (struct crypt_data *)safemalloc(sizeof(struct crypt_data));
+#if defined(__GLIBC__) || defined(__EMX__)
+       if (PL_reentrant_buffer->_crypt_struct_buffer) {
+           PL_reentrant_buffer->_crypt_struct_buffer->initialized = 0;
+           /* work around glibc-2.2.5 bug */
+           PL_reentrant_buffer->_crypt_struct_buffer->current_saltbits = 0;
+       }
+    }
+#endif
+#     endif /* HAS_CRYPT_R */
+#   endif /* USE_ITHREADS */
 #   ifdef FCRYPT
     sv_setpv(TARG, fcrypt(tmps, SvPV(right, n_a)));
 #   else
index a2f1a19..3b2a39a 100644 (file)
--- a/reentr.c
+++ b/reentr.c
@@ -146,10 +146,8 @@ Perl_reentrant_init(pTHX) {
        New(31338, PL_reentrant_buffer->_asctime_buffer, PL_reentrant_buffer->_asctime_size, char);
 #endif /* HAS_ASCTIME_R */
 #ifdef HAS_CRYPT_R
-#if defined(__GLIBC__) || defined(__EMX__)
-       PL_reentrant_buffer->_crypt_struct.initialized = 0;
-       /* work around glibc-2.2.5 bug */
-       PL_reentrant_buffer->_crypt_struct.current_saltbits = 0;
+#if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
+       PL_reentrant_buffer->_crypt_struct_buffer = 0;
 #endif
 #endif /* HAS_CRYPT_R */
 #ifdef HAS_CTIME_R
@@ -230,6 +228,9 @@ Perl_reentrant_free(pTHX) {
        Safefree(PL_reentrant_buffer->_asctime_buffer);
 #endif /* HAS_ASCTIME_R */
 #ifdef HAS_CRYPT_R
+#if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
+       Safefree(PL_reentrant_buffer->_crypt_struct_buffer);
+#endif
 #endif /* HAS_CRYPT_R */
 #ifdef HAS_CTIME_R
        Safefree(PL_reentrant_buffer->_ctime_buffer);
index f5337c4..f4f9f25 100644 (file)
--- a/reentr.h
+++ b/reentr.h
@@ -604,7 +604,7 @@ typedef struct {
 #if CRYPT_R_PROTO == REENTRANT_PROTO_B_CCD
        CRYPTD* _crypt_data;
 #else
-       struct crypt_data _crypt_struct;
+       struct crypt_data *_crypt_struct_buffer;
 #endif
 #endif /* HAS_CRYPT_R */
 #ifdef HAS_CTIME_R
@@ -781,7 +781,7 @@ typedef struct {
 #ifdef HAS_CRYPT_R
 #   undef crypt
 #   if !defined(crypt) && CRYPT_R_PROTO == REENTRANT_PROTO_B_CCS
-#       define crypt(a, b) crypt_r(a, b, &PL_reentrant_buffer->_crypt_struct)
+#       define crypt(a, b) crypt_r(a, b, PL_reentrant_buffer->_crypt_struct_buffer)
 #   endif
 #   if !defined(crypt) && CRYPT_R_PROTO == REENTRANT_PROTO_B_CCD
 #       define crypt(a, b) crypt_r(a, b, &PL_reentrant_buffer->_crypt_data)
index d96cb3a..4429bc4 100644 (file)
--- a/reentr.pl
+++ b/reentr.pl
@@ -453,14 +453,17 @@ EOF
 #if CRYPT_R_PROTO == REENTRANT_PROTO_B_CCD
        $seend{$func} _${func}_data;
 #else
-       $seent{$func} _${func}_struct;
+       $seent{$func} *_${func}_struct_buffer;
 #endif
 EOF
            push @init, <<EOF;
-#if defined(__GLIBC__) || defined(__EMX__)
-       PL_reentrant_buffer->_${func}_struct.initialized = 0;
-       /* work around glibc-2.2.5 bug */
-       PL_reentrant_buffer->_${func}_struct.current_saltbits = 0;
+#if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
+       PL_reentrant_buffer->_${func}_struct_buffer = 0;
+#endif
+EOF
+           push @free, <<EOF;
+#if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
+       Safefree(PL_reentrant_buffer->_${func}_struct_buffer);
 #endif
 EOF
            pushssif $endif;
@@ -661,9 +664,11 @@ EOF
                             $_ eq 'D' ?
                                 "&PL_reentrant_buffer->_${genfunc}_data" :
                             $_ eq 'S' ?
-                                ($func =~ /^readdir/ ?
+                                ($func =~ /^readdir\d*$/ ?
                                  "PL_reentrant_buffer->_${genfunc}_struct" :
-                                 "&PL_reentrant_buffer->_${genfunc}_struct" ) :
+                                 $func =~ /^crypt$/ ?
+                                 "PL_reentrant_buffer->_${genfunc}_struct_buffer" :
+                                 "&PL_reentrant_buffer->_${genfunc}_struct") :
                             $_ eq 'T' && $func eq 'drand48' ?
                                 "&PL_reentrant_buffer->_${genfunc}_double" :
                             $_ =~ /^[ilt]$/ && $func eq 'random' ?