A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/Perl/perl5/commit/24f3e849b5ce9f3bf6b6be5d3e730562e927aa79 below:

Add thread safety to some environment accesses · Perl/perl5@24f3e84 · GitHub

File tree Expand file treeCollapse file tree 8 files changed

+86

-37

lines changed

Filter options

Expand file treeCollapse file tree 8 files changed

+86

-37

lines changed Original file line number Diff line number Diff line change

@@ -453,6 +453,8 @@

453 453

:

454 454

: Individual flags may be separated by non-tab whitespace.

455 455 456 +

CipRTX |char * |mortal_getenv |NN const char * str

457 + 456 458

#if defined(PERL_IMPLICIT_SYS)

457 459

ATo |PerlInterpreter*|perl_alloc_using \

458 460

|NN struct IPerlMem *ipM \

Original file line number Diff line number Diff line change

@@ -313,6 +313,7 @@

313 313

#define mg_size(a) Perl_mg_size(aTHX_ a)

314 314

#define mini_mktime Perl_mini_mktime

315 315

#define moreswitches(a) Perl_moreswitches(aTHX_ a)

316 +

#define mortal_getenv Perl_mortal_getenv

316 317

#define mro_get_linear_isa(a) Perl_mro_get_linear_isa(aTHX_ a)

317 318

#define mro_method_changed_in(a) Perl_mro_method_changed_in(aTHX_ a)

318 319

#define my_atof(a) Perl_my_atof(aTHX_ a)

Original file line number Diff line number Diff line change

@@ -2586,6 +2586,59 @@ S_my_memrchr(const char * s, const char c, const STRLEN len)

2586 2586 2587 2587

#endif

2588 2588 2589 +

PERL_STATIC_INLINE char *

2590 +

Perl_mortal_getenv(const char * str)

2591 +

{

2592 +

/* This implements a (mostly) thread-safe, sequential-call-safe getenv().

2593 +

*

2594 +

* It's (mostly) thread-safe because it uses a mutex to prevent

2595 +

* simultaneous access from other threads that use the same mutex, and

2596 +

* makes a copy of the result before releasing that mutex. All of the Perl

2597 +

* core uses that mutex, but, like all mutexes, everything has to cooperate

2598 +

* for it to completely work. It is possible for code from, say XS, to not

2599 +

* use this mutex, defeating the safety.

2600 +

*

2601 +

* On some platforms, getenv() is not sequential-call-safe, because

2602 +

* subsequent calls destroy the static storage inside the C library

2603 +

* returned by an earlier call. The result must be copied or completely

2604 +

* acted upon before a subsequent getenv call. Those calls could come from

2605 +

* another thread. Again, making a copy while controlling the mutex

2606 +

* prevents these problems..

2607 +

*

2608 +

* To prevent leaks, the copy is made by creating a new SV containing it,

2609 +

* mortalizing the SV, and returning the SV's string (the copy). Thus this

2610 +

* is a drop-in replacement for getenv().

2611 +

*

2612 +

* A complication is that this can be called during phases where the

2613 +

* mortalization process isn't available. These are in interpreter

2614 +

* destruction or early in construction. khw believes that at these times

2615 +

* there shouldn't be anything else going on, so plain getenv is safe AS

2616 +

* LONG AS the caller acts on the return before calling it again. */

2617 + 2618 +

char * ret;

2619 +

dTHX;

2620 + 2621 +

PERL_ARGS_ASSERT_MORTAL_GETENV;

2622 + 2623 +

/* Can't mortalize without stacks. khw believes that no other threads

2624 +

* should be running, so no need to lock things, and this may be during a

2625 +

* phase when locking isn't even available */

2626 +

if (UNLIKELY(PL_scopestack_ix == 0)) {

2627 +

return getenv(str);

2628 +

}

2629 + 2630 +

ENV_LOCK;

2631 + 2632 +

ret = getenv(str);

2633 + 2634 +

if (ret != NULL) {

2635 +

ret = SvPVX(sv_2mortal(newSVpv(ret, 0)));

2636 +

}

2637 + 2638 +

ENV_UNLOCK;

2639 +

return ret;

2640 +

}

2641 + 2589 2642

/*

2590 2643

* ex: set ts=8 sts=4 sw=4 et:

2591 2644

*/

Original file line number Diff line number Diff line change

@@ -562,10 +562,18 @@ struct IPerlEnvInfo

562 562

(*PL_Env->pGetChildIO)(PL_Env, ptr)

563 563

#endif

564 564 565 -

#else /* PERL_IMPLICIT_SYS */

566 - 567 -

#define PerlEnv_putenv(str) putenv((str))

568 -

#define PerlEnv_getenv(str) getenv((str))

565 +

#else /* below is ! PERL_IMPLICIT_SYS */

566 +

# ifdef USE_ITHREADS

567 + 568 +

/* Use the comma operator to return 0/non-zero, while avoiding putting

569 +

* this in an inline function */

570 +

# define PerlEnv_putenv(str) (ENV_LOCK, (putenv(str) \

571 +

? (ENV_UNLOCK, 1) \

572 +

: (ENV_UNLOCK, 0)))

573 +

# else

574 +

# define PerlEnv_putenv(str) putenv(str)

575 +

# endif

576 +

#define PerlEnv_getenv(str) mortal_getenv(str)

569 577

#define PerlEnv_getenv_len(str,l) getenv_len((str), (l))

570 578

#ifdef HAS_ENVGETENV

571 579

# define PerlEnv_ENVgetenv(str) ENVgetenv((str))

@@ -588,7 +596,9 @@ struct IPerlEnvInfo

588 596

#define PerlEnv_get_childdir() win32_get_childdir()

589 597

#define PerlEnv_free_childdir(d) win32_free_childdir((d))

590 598

#else

591 -

#define PerlEnv_clearenv() clearenv()

599 +

#define PerlEnv_clearenv(str) (ENV_LOCK, (clearenv(str) \

600 +

? (ENV_UNLOCK, 1) \

601 +

: (ENV_UNLOCK, 0)))

592 602

#define PerlEnv_get_childenv() get_childenv()

593 603

#define PerlEnv_free_childenv(e) free_childenv((e))

594 604

#define PerlEnv_get_childdir() get_childdir()

Original file line number Diff line number Diff line change

@@ -791,16 +791,6 @@ S_emulate_setlocale(const int category,

791 791

if (! default_name || strEQ(default_name, "")) {

792 792

default_name = "C";

793 793

}

794 -

else if (PL_scopestack_ix != 0) {

795 -

/* To minimize other threads messing with the environment,

796 -

* we copy the variable, making it a temporary. But this

797 -

* doesn't work upon program initialization before any

798 -

* scopes are created, and at this time, there's nothing

799 -

* else going on that would interfere. So skip the copy

800 -

* in that case */

801 -

default_name = savepv(default_name);

802 -

SAVEFREEPV(default_name);

803 -

}

804 794 805 795

if (category != LC_ALL) {

806 796

const char * const name = PerlEnv_getenv(category_names[index]);

@@ -835,22 +825,19 @@ S_emulate_setlocale(const int category,

835 825 836 826

for (i = 0; i < LC_ALL_INDEX; i++) {

837 827

const char * const env_override

838 -

= savepv(PerlEnv_getenv(category_names[i]));

828 +

= PerlEnv_getenv(category_names[i]);

839 829

const char * this_locale = ( env_override

840 830

&& strNE(env_override, ""))

841 831

? env_override

842 832

: default_name;

843 833

if (! emulate_setlocale(categories[i], this_locale, i, TRUE))

844 834

{

845 -

Safefree(env_override);

846 835

return NULL;

847 836

}

848 837 849 838

if (strNE(this_locale, default_name)) {

850 839

did_override = TRUE;

851 840

}

852 - 853 -

Safefree(env_override);

854 841

}

855 842 856 843

/* If all the categories are the same, we can set LC_ALL to

@@ -3310,7 +3297,7 @@ Perl_init_i18nl10n(pTHX_ int printwarn)

3310 3297

#else /* USE_LOCALE */

3311 3298

# ifdef __GLIBC__

3312 3299 3313 -

const char * const language = savepv(PerlEnv_getenv("LANGUAGE"));

3300 +

const char * const language = PerlEnv_getenv("LANGUAGE");

3314 3301 3315 3302

# endif

3316 3303

@@ -3320,8 +3307,8 @@ Perl_init_i18nl10n(pTHX_ int printwarn)

3320 3307

: "";

3321 3308

const char* trial_locales[5]; /* 5 = 1 each for "", LC_ALL, LANG, "", C */

3322 3309

unsigned int trial_locales_count;

3323 -

const char * const lc_all = savepv(PerlEnv_getenv("LC_ALL"));

3324 -

const char * const lang = savepv(PerlEnv_getenv("LANG"));

3310 +

const char * const lc_all = PerlEnv_getenv("LC_ALL");

3311 +

const char * const lang = PerlEnv_getenv("LANG");

3325 3312

bool setlocale_failure = FALSE;

3326 3313

unsigned int i;

3327 3314

@@ -3909,15 +3896,6 @@ Perl_init_i18nl10n(pTHX_ int printwarn)

3909 3896

}

3910 3897 3911 3898

# endif

3912 -

# ifdef __GLIBC__

3913 - 3914 -

Safefree(language);

3915 - 3916 -

# endif

3917 - 3918 -

Safefree(lc_all);

3919 -

Safefree(lang);

3920 - 3921 3899

#endif /* USE_LOCALE */

3922 3900

#ifdef DEBUGGING

3923 3901 Original file line number Diff line number Diff line change

@@ -2283,10 +2283,6 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)

2283 2283

#endif

2284 2284

(s = PerlEnv_getenv("PERL5OPT")))

2285 2285

{

2286 -

/* s points to static memory in getenv(), which may be overwritten at

2287 -

* any time; use a mortal copy instead */

2288 -

s = SvPVX(sv_2mortal(newSVpv(s, 0)));

2289 - 2290 2286

while (isSPACE(*s))

2291 2287

s++;

2292 2288

if (*s == '-' && *(s+1) == 'T') {

Original file line number Diff line number Diff line change

@@ -2045,6 +2045,13 @@ PERL_CALLCONV void * Perl_more_bodies(pTHX_ const svtype sv_type, const size_t b

2045 2045

PERL_CALLCONV const char* Perl_moreswitches(pTHX_ const char* s);

2046 2046

#define PERL_ARGS_ASSERT_MORESWITCHES \

2047 2047

assert(s)

2048 +

#ifndef PERL_NO_INLINE_FUNCTIONS

2049 +

PERL_STATIC_INLINE char * Perl_mortal_getenv(const char * str)

2050 +

__attribute__warn_unused_result__;

2051 +

#define PERL_ARGS_ASSERT_MORTAL_GETENV \

2052 +

assert(str)

2053 +

#endif

2054 + 2048 2055

PERL_CALLCONV const struct mro_alg * Perl_mro_get_from_name(pTHX_ SV *name);

2049 2056

#define PERL_ARGS_ASSERT_MRO_GET_FROM_NAME \

2050 2057

assert(name)

Original file line number Diff line number Diff line change

@@ -2139,7 +2139,8 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)

2139 2139

# endif

2140 2140 2141 2141

# ifdef USE_ITHREADS

2142 -

/* only parent thread can modify process environment */

2142 +

/* only parent thread can modify process environment, so no need to use a

2143 +

* mutex */

2143 2144

if (PL_curinterp == aTHX)

2144 2145

# endif

2145 2146

{

@@ -5169,7 +5170,8 @@ Perl_my_clearenv(pTHX)

5169 5170

# else /* ! (PERL_IMPLICIT_SYS || WIN32) */

5170 5171

# if defined(USE_ENVIRON_ARRAY)

5171 5172

# if defined(USE_ITHREADS)

5172 -

/* only the parent thread can clobber the process environment */

5173 +

/* only the parent thread can clobber the process environment, so no need

5174 +

* to use a mutex */

5173 5175

if (PL_curinterp == aTHX)

5174 5176

# endif /* USE_ITHREADS */

5175 5177

{

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4