]> granicus.if.org Git - php/commitdiff
Make basic/string functions thread-safe
authorSascha Schumann <sas@php.net>
Sun, 28 Nov 1999 00:31:02 +0000 (00:31 +0000)
committerSascha Schumann <sas@php.net>
Sun, 28 Nov 1999 00:31:02 +0000 (00:31 +0000)
ext/standard/basic_functions.c
ext/standard/basic_functions.h
ext/standard/php3_string.h
ext/standard/string.c

index e5a7677e33a47ff6207fc4b91a245355f32134d3..2b51c2025bf0f86f2a8d09d7aa8d06400ec3c92f 100644 (file)
        #define md5 ap_md5
        which "kills" out md5 function.
 */
-#ifdef md5
 #undef md5
 #endif
+
+#ifdef ZTS
+int basic_globals_id;
+#else
+php_basic_globals basic_globals;
 #endif
 
 static unsigned char second_and_third_args_force_ref[] = { 3, BYREF_NONE, BYREF_FORCE, BYREF_FORCE };
 /* uncomment this if/when we actually need it - tired of seeing the warning
 static unsigned char third_and_fourth_args_force_ref[] = { 4, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYREF_FORCE };
 */
-static HashTable *user_shutdown_function_names;
+;
 
 typedef struct _php_shutdown_function_entry {
        zval **arguments;
        int arg_count;
 } php_shutdown_function_entry;
 
-#ifdef ZTS
-#undef HAVE_PUTENV
-#endif
-
 /* some prototypes for local functions */
-int user_shutdown_function_dtor(php_shutdown_function_entry *shutdown_function_entry);
-void php3_call_shutdown_functions(void);
+static int user_shutdown_function_dtor(php_shutdown_function_entry *shutdown_function_entry);
 
 function_entry basic_functions[] = {
        PHP_FE(intval,                                                                  NULL)
@@ -329,7 +328,6 @@ php3_module_entry basic_functions_module = {
 };
 
 #if defined(HAVE_PUTENV)
-static HashTable putenv_ht;
 
 static int _php3_putenv_destructor(putenv_entry *pe)
 {
@@ -364,7 +362,10 @@ void test_class_startup();
 PHP_MINIT_FUNCTION(basic)
 {
        ELS_FETCH();
-
+#ifdef ZTS
+       basic_globals_id = ts_allocate_id(sizeof(php_basic_globals), NULL, NULL);
+#endif
+       
        REGISTER_DOUBLE_CONSTANT("M_PI", M_PI, CONST_CS | CONST_PERSISTENT);
        
        test_class_startup();
@@ -378,6 +379,10 @@ PHP_MINIT_FUNCTION(basic)
 
 PHP_MSHUTDOWN_FUNCTION(basic)
 {
+#ifdef ZTS
+       ts_free_id(basic_globals_id);
+#endif
+       
        UNREGISTER_INI_ENTRIES();
        return SUCCESS; 
 }
@@ -385,30 +390,34 @@ PHP_MSHUTDOWN_FUNCTION(basic)
 
 PHP_RINIT_FUNCTION(basic)
 {
-       strtok_string = NULL;
-       locale_string = NULL;
+       BLS_FETCH();
+
+       BG(strtok_string) = NULL;
+       BG(locale_string) = NULL;
 #ifdef HAVE_PUTENV
-       if (zend_hash_init(&putenv_ht, 1, NULL, (int (*)(void *)) _php3_putenv_destructor, 0) == FAILURE) {
+       if (zend_hash_init(&BG(putenv_ht), 1, NULL, (int (*)(void *)) _php3_putenv_destructor, 0) == FAILURE) {
                return FAILURE;
        }
 #endif
-       user_shutdown_function_names=NULL;
+       BG(user_shutdown_function_names)=NULL;
        return SUCCESS;
 }
 
 
 PHP_RSHUTDOWN_FUNCTION(basic)
 {
-       STR_FREE(strtok_string);
+       BLS_FETCH();
+
+       STR_FREE(BG(strtok_string));
 #ifdef HAVE_PUTENV
-       zend_hash_destroy(&putenv_ht);
+       zend_hash_destroy(&BG(putenv_ht));
 #endif
        /* Check if locale was changed and change it back
           to the value in startup environment */
-       if (locale_string != NULL) {
+       if (BG(locale_string) != NULL) {
                setlocale(LC_ALL, "");
        }
-       STR_FREE(locale_string);
+       STR_FREE(BG(locale_string));
 
        return SUCCESS;
 }
@@ -475,6 +484,7 @@ PHP_FUNCTION(getenv)
 PHP_FUNCTION(putenv)
 {
        pval **str;
+       BLS_FETCH();
 
        if (ARG_COUNT(ht) != 1 || getParametersEx(1, &str) == FAILURE) {
                WRONG_PARAM_COUNT;
@@ -494,7 +504,7 @@ PHP_FUNCTION(putenv)
                pe.key_len = strlen(pe.key);
                pe.key = estrndup(pe.key,pe.key_len);
                
-               zend_hash_del(&putenv_ht,pe.key,pe.key_len+1);
+               zend_hash_del(&BG(putenv_ht),pe.key,pe.key_len+1);
                
                /* find previous value */
                pe.previous_value = NULL;
@@ -506,7 +516,7 @@ PHP_FUNCTION(putenv)
                }
 
                if ((ret=putenv(pe.putenv_string))==0) { /* success */
-                       zend_hash_add(&putenv_ht,pe.key,pe.key_len+1,(void **) &pe,sizeof(putenv_entry),NULL);
+                       zend_hash_add(&BG(putenv_ht),pe.key,pe.key_len+1,(void **) &pe,sizeof(putenv_entry),NULL);
                        RETURN_TRUE;
                } else {
                        efree(pe.putenv_string);
@@ -1024,9 +1034,11 @@ int user_shutdown_function_dtor(php_shutdown_function_entry *shutdown_function_e
 
 void php3_call_shutdown_functions(void)
 {
-       if (user_shutdown_function_names) {
-               zend_hash_destroy(user_shutdown_function_names);
-               efree(user_shutdown_function_names);
+       BLS_FETCH();
+       
+       if (BG(user_shutdown_function_names)) {
+               zend_hash_destroy(BG(user_shutdown_function_names));
+               efree(BG(user_shutdown_function_names));
        }
 }
 
@@ -1036,6 +1048,7 @@ PHP_FUNCTION(register_shutdown_function)
 {
        php_shutdown_function_entry shutdown_function_entry;
        int i;
+       BLS_FETCH();
 
        shutdown_function_entry.arg_count = ARG_COUNT(ht);
 
@@ -1048,15 +1061,15 @@ PHP_FUNCTION(register_shutdown_function)
                RETURN_FALSE;
        }       
        convert_to_string(shutdown_function_entry.arguments[0]);
-       if (!user_shutdown_function_names) {
-               user_shutdown_function_names = (HashTable *) emalloc(sizeof(HashTable));
-               zend_hash_init(user_shutdown_function_names, 0, NULL, (int (*)(void *))user_shutdown_function_dtor, 0);
+       if (!BG(user_shutdown_function_names)) {
+               BG(user_shutdown_function_names) = (HashTable *) emalloc(sizeof(HashTable));
+               zend_hash_init(BG(user_shutdown_function_names), 0, NULL, (int (*)(void *))user_shutdown_function_dtor, 0);
        }
 
        for (i=0; i<shutdown_function_entry.arg_count; i++) {
                shutdown_function_entry.arguments[i]->refcount++;
        }
-       zend_hash_next_index_insert(user_shutdown_function_names, &shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL);
+       zend_hash_next_index_insert(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL);
 }
 /* }}} */
 
index 6d1e778db628b9682df81d353510b9a5565f7a10..2fe14c8bfb1025d77ff5a567722ac925baad8704 100644 (file)
@@ -103,6 +103,32 @@ PHP_FUNCTION(getservbyport);
 PHP_FUNCTION(getprotobyname);
 PHP_FUNCTION(getprotobynumber);
 
+typedef struct {
+       HashTable *user_shutdown_function_names;
+       HashTable putenv_ht;
+       char *strtok_string;
+       char *locale_string;
+       char *strtok_pos1;
+       char *strtok_pos2;
+       char str_ebuf[40];
+} php_basic_globals;
+
+#ifdef ZTS
+#define BLS_D php_basic_globals *basic_globals
+#define BLS_DC , BLS_D
+#define BLS_C basic_globals
+#define BLS_CC , BLS_C
+#define BG(v) (basic_globals->v)
+#define BLS_FETCH() php_basic_globals *basic_globals = ts_resource(basic_globals_id)
+#else
+#define BLS_D
+#define BLS_DC
+#define BLS_C
+#define BLS_CC
+#define BG(v) (basic_globals.v)
+#define BLS_FETCH()
+#endif
+
 #if HAVE_PUTENV
 typedef struct {
        char *putenv_string;
index d23dbb46f83d45c09ece121c0d766f51bdc8ada9..93e4ab18c1036b136f8836724e57b3b84f64c276 100644 (file)
 #ifndef _PHPSTRING_H
 #define _PHPSTRING_H
 
-#ifndef THREAD_SAFE
-extern char *strtok_string;
-extern char *locale_string;
-#endif
+#include "basic_functions.h"
 
 PHP_FUNCTION(strspn);
 PHP_FUNCTION(strcspn);
index d751b60ff64d5f7d816848bce6e7334e35093666..86e2f496840a0102a21a05c76958389d38dbcd45 100644 (file)
 #include "zend_execute.h"
 #include "php_globals.h"
 
+#ifdef ZTS
+extern int basic_globals_id;
+#else
+extern php_basic_globals basic_globals;
+#endif
+
+/* this is read-only, so it's ok */
 static char hexconvtab[] = "0123456789abcdef";
 
 static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t *newlen)
@@ -321,22 +328,15 @@ PHP_FUNCTION(implode)
 /* }}} */
 
 
-#ifndef THREAD_SAFE
-char *strtok_string;
-#endif
-
 /* {{{ proto string strtok([string str,] string token)
    Tokenize a string */
 PHP_FUNCTION(strtok)
 {
        pval **str, **tok;
-#ifndef THREAD_SAFE
-       static char *strtok_pos1 = NULL;
-       static char *strtok_pos2 = NULL;
-#endif
        char *token = NULL, *tokp=NULL;
        char *first = NULL;
        int argc;
+       BLS_FETCH();
        
        argc = ARG_COUNT(ht);
 
@@ -351,35 +351,35 @@ PHP_FUNCTION(strtok)
        if (argc == 2) {
                convert_to_string_ex(str);
 
-               STR_FREE(strtok_string);
-               strtok_string = estrndup((*str)->value.str.val,(*str)->value.str.len);
-               strtok_pos1 = strtok_string;
-               strtok_pos2 = NULL;
+               STR_FREE(BG(strtok_string));
+               BG(strtok_string) = estrndup((*str)->value.str.val,(*str)->value.str.len);
+               BG(strtok_pos1) = BG(strtok_string);
+               BG(strtok_pos2) = NULL;
        }
-       if (strtok_pos1 && *strtok_pos1) {
+       if (BG(strtok_pos1) && *BG(strtok_pos1)) {
                for ( /* NOP */ ; token && *token; token++) {
-                       strtok_pos2 = strchr(strtok_pos1, (int) *token);
-                       if (!first || (strtok_pos2 && strtok_pos2 < first)) {
-                               first = strtok_pos2;
+                       BG(strtok_pos2) = strchr(BG(strtok_pos1), (int) *token);
+                       if (!first || (BG(strtok_pos2) && BG(strtok_pos2) < first)) {
+                               first = BG(strtok_pos2);
                        }
                }                                               /* NB: token is unusable now */
 
-               strtok_pos2 = first;
-               if (strtok_pos2) {
-                       *strtok_pos2 = '\0';
+               BG(strtok_pos2) = first;
+               if (BG(strtok_pos2)) {
+                       *BG(strtok_pos2) = '\0';
                }
-               RETVAL_STRING(strtok_pos1,1);
+               RETVAL_STRING(BG(strtok_pos1),1);
 #if 0
                /* skip 'token' white space for next call to strtok */
-               while (strtok_pos2 && 
-                       strchr(tokp, *(strtok_pos2+1))) {
-                       strtok_pos2++;
+               while (BG(strtok_pos2) && 
+                       strchr(tokp, *(BG(strtok_pos2)+1))) {
+                       BG(strtok_pos2)++;
                }
 #endif
-               if (strtok_pos2)
-                       strtok_pos1 = strtok_pos2 + 1;
+               if (BG(strtok_pos2))
+                       BG(strtok_pos1) = BG(strtok_pos2) + 1;
                else
-                       strtok_pos1 = NULL;
+                       BG(strtok_pos1) = NULL;
        } else {
                RETVAL_FALSE;
        }
@@ -1436,13 +1436,11 @@ char *strerror(int errnum)
 {
        extern int sys_nerr;
        extern char *sys_errlist[];
-#ifndef THREAD_SAFE
-       static char str_ebuf[40];
-#endif
+       BLS_FETCH();
 
        if ((unsigned int)errnum < sys_nerr) return(sys_errlist[errnum]);
-       (void)sprintf(str_ebuf, "Unknown error: %d", errnum);
-       return(str_ebuf);
+       (void)sprintf(BG(str_ebuf), "Unknown error: %d", errnum);
+       return(BG(str_ebuf));
 }
 #endif
 #endif
@@ -1987,10 +1985,6 @@ PHP_FUNCTION(strip_tags)
 }
 /* }}} */
 
-#ifndef THREAD_SAFE
-char *locale_string;
-#endif
-
 /* {{{ proto string setlocale(string category, string locale)
    Set locale information */
 PHP_FUNCTION(setlocale)
@@ -1999,6 +1993,7 @@ PHP_FUNCTION(setlocale)
        pval *category, *locale;
        int cat;
        char *loc, *retval;
+       BLS_FETCH();
 
        if (ARG_COUNT(ht)!=2 || getParametersEx(2, &pcategory, &plocale)==FAILURE)
                WRONG_PARAM_COUNT;
@@ -2031,8 +2026,8 @@ PHP_FUNCTION(setlocale)
        if (retval) {
                /* Remember if locale was changed */
                if (loc) {
-                       STR_FREE(locale_string);
-                       strtok_string = estrdup(retval);
+                       STR_FREE(BG(locale_string));
+                       BG(strtok_string) = estrdup(retval);
                }
 
                RETVAL_STRING(retval,1);