summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Williamson <khw@cpan.org>2020-12-01 07:44:18 -0700
committerKarl Williamson <khw@cpan.org>2020-12-19 22:00:30 -0700
commit35bcf7ffa2bfeab79ab7b4eb0d35f462775b54d2 (patch)
treefeffc93e76297c539b0bc9985c2a88d626caf7e5
parent9d228af78ad17dabb51f9059d215cc88c059a22a (diff)
downloadperl-35bcf7ffa2bfeab79ab7b4eb0d35f462775b54d2.tar.gz
Add GETENV_LOCK
get_env() needs to lock other threads from writing to the environment while it is executing. It may need to have an exclusive lock if those threads can clobber its buffer before it gets a chance to save them. The previous commit has added a Configure probe which tells us if that is the case. This commit uses it to select which type of mutex to use.
-rw-r--r--inline.h5
-rw-r--r--perl.h17
2 files changed, 20 insertions, 2 deletions
diff --git a/inline.h b/inline.h
index c18637208f..dbfb89a6b0 100644
--- a/inline.h
+++ b/inline.h
@@ -2654,7 +2654,7 @@ Perl_mortal_getenv(const char * str)
return getenv(str);
}
- ENV_LOCK;
+ GETENV_LOCK;
ret = getenv(str);
@@ -2662,7 +2662,8 @@ Perl_mortal_getenv(const char * str)
ret = SvPVX(sv_2mortal(newSVpv(ret, 0)));
}
- ENV_UNLOCK;
+ GETENV_UNLOCK;
+
return ret;
}
diff --git a/perl.h b/perl.h
index 9243ca82cb..cbb6905fe0 100644
--- a/perl.h
+++ b/perl.h
@@ -7009,6 +7009,21 @@ cannot have changed since the precalculation.
# define ENV_READ_UNLOCK PERL_READ_UNLOCK(&PL_env_mutex)
# define ENV_INIT PERL_RW_MUTEX_INIT(&PL_env_mutex)
# define ENV_TERM PERL_RW_MUTEX_DESTROY(&PL_env_mutex)
+
+ /* On platforms where the static buffer contained in getenv() is per-thread
+ * rather than process-wide, another thread executing a getenv() at the same
+ * time won't destroy ours before we have copied the result safely away and
+ * unlocked the mutex. On such platforms (which is most), we can have many
+ * readers of the environment at the same time. */
+# ifdef GETENV_PRESERVES_OTHER_THREAD
+# define GETENV_LOCK ENV_READ_LOCK
+# define GETENV_UNLOCK ENV_READ_UNLOCK
+# else
+ /* If, on the other hand, another thread could zap our getenv() return, we
+ * need to keep them from executing until we are done */
+# define GETENV_LOCK ENV_LOCK
+# define GETENV_UNLOCK ENV_UNLOCK
+# endif
#else
# define ENV_LOCK NOOP
# define ENV_UNLOCK NOOP
@@ -7016,6 +7031,8 @@ cannot have changed since the precalculation.
# define ENV_READ_UNLOCK NOOP
# define ENV_INIT NOOP
# define ENV_TERM NOOP
+# define GETENV_LOCK NOOP
+# define GETENV_UNLOCK NOOP
#endif
#ifndef PERL_NO_INLINE_FUNCTIONS