Browse Source

Move V8JSG extensions and v8_flags to process globals

Stefan Siegl 9 years ago
parent
commit
74440ed9f7
4 changed files with 81 additions and 32 deletions
  1. 7 2
      php_v8js_macros.h
  2. 35 17
      v8js.cc
  3. 36 11
      v8js_class.cc
  4. 3 2
      v8js_v8.cc

+ 7 - 2
php_v8js_macros.h

@@ -113,10 +113,8 @@ void v8js_register_accessors(std::vector<v8js_accessor_ctx*> *accessor_list, v8:
 ZEND_BEGIN_MODULE_GLOBALS(v8js)
   // Thread-local cache whether V8 has been initialized so far
   int v8_initialized;
-  HashTable *extensions;
 
   /* Ini globals */
-  char *v8_flags; /* V8 command line flags */
   bool use_date; /* Generate JS Date objects instead of PHP DateTime */
   bool use_array_access; /* Convert ArrayAccess, Countable objects to array-like objects */
   bool compat_php_exceptions; /* Don't stop JS execution on PHP exception */
@@ -149,6 +147,8 @@ ZEND_EXTERN_MODULE_GLOBALS(v8js)
  *
  *  - whether V8 has been initialized at all
  *  - the V8 backend platform
+ *  - loaded extensions
+ *  - V8 "command line" flags
  *
  * In a ZTS-enabled environment access to all of these variables must happen
  * while holding a mutex lock.
@@ -159,6 +159,11 @@ struct _v8js_process_globals {
 	std::mutex lock;
 #endif
 
+	HashTable *extensions;
+
+	/* V8 command line flags */
+	char *v8_flags;
+
 #if !defined(_WIN32) && PHP_V8_API_VERSION >= 3029036
 	v8::Platform *v8_platform;
 #endif

+ 35 - 17
v8js.cc

@@ -35,15 +35,35 @@ struct _v8js_process_globals v8js_process_globals;
 
 static ZEND_INI_MH(v8js_OnUpdateV8Flags) /* {{{ */
 {
+	bool immutable = false;
+
+#ifdef ZTS
+	v8js_process_globals.lock.lock();
+
+	if(v8js_process_globals.v8_initialized) {
+		v8js_process_globals.lock.unlock();
+		immutable = true;
+	}
+
+	v8js_process_globals.lock.unlock();
+#else
+	immutable = V8JSG(v8_initialized);
+#endif
+
+	if(immutable) {
+		/* V8 already has been initialized -> cannot be changed anymore */
+		return FAILURE;
+	}
+
 	if (new_value) {
-		if (V8JSG(v8_flags)) {
-			free(V8JSG(v8_flags));
-			V8JSG(v8_flags) = NULL;
+		if (v8js_process_globals.v8_flags) {
+			free(v8js_process_globals.v8_flags);
+			v8js_process_globals.v8_flags = NULL;
 		}
 		if (!new_value[0]) {
 			return FAILURE;
 		}
-		V8JSG(v8_flags) = zend_strndup(new_value, new_value_length);
+		v8js_process_globals.v8_flags = zend_strndup(new_value, new_value_length);
 	}
 
 	return SUCCESS;
@@ -129,6 +149,17 @@ static PHP_MSHUTDOWN_FUNCTION(v8js)
 #endif
 	}
 
+	if (v8js_process_globals.v8_flags) {
+		free(v8js_process_globals.v8_flags);
+		v8js_process_globals.v8_flags = NULL;
+	}
+
+	if (v8js_process_globals.extensions) {
+		zend_hash_destroy(v8js_process_globals.extensions);
+		free(v8js_process_globals.extensions);
+		v8js_process_globals.extensions = NULL;
+	}
+
 	return SUCCESS;
 }
 /* }}} */
@@ -180,9 +211,7 @@ static PHP_GINIT_FUNCTION(v8js)
 	  run the destructors manually.
 	*/
 #ifdef ZTS
-	v8js_globals->extensions = NULL;
 	v8js_globals->v8_initialized = 0;
-	v8js_globals->v8_flags = NULL;
 
 	v8js_globals->timer_thread = NULL;
 	v8js_globals->timer_stop = false;
@@ -198,17 +227,6 @@ static PHP_GINIT_FUNCTION(v8js)
  */
 static PHP_GSHUTDOWN_FUNCTION(v8js)
 {
-	if (v8js_globals->extensions) {
-		zend_hash_destroy(v8js_globals->extensions);
-		free(v8js_globals->extensions);
-		v8js_globals->extensions = NULL;
-	}
-
-	if (v8js_globals->v8_flags) {
-		free(v8js_globals->v8_flags);
-		v8js_globals->v8_flags = NULL;
-	}
-
 #ifdef ZTS
 	v8js_globals->timer_stack.~deque();
 	v8js_globals->timer_mutex.~mutex();

+ 36 - 11
v8js_class.cc

@@ -827,10 +827,17 @@ static int v8js_register_extension(char *name, uint name_len, char *source, uint
 {
 	v8js_jsext *jsext = NULL;
 
-	if (!V8JSG(extensions)) {
-		V8JSG(extensions) = (HashTable *) malloc(sizeof(HashTable));
-		zend_hash_init(V8JSG(extensions), 1, NULL, (dtor_func_t) v8js_jsext_dtor, 1);
-	} else if (zend_hash_exists(V8JSG(extensions), name, name_len + 1)) {
+#ifdef ZTS
+	v8js_process_globals.lock.lock();
+#endif
+
+	if (!v8js_process_globals.extensions) {
+		v8js_process_globals.extensions = (HashTable *) malloc(sizeof(HashTable));
+		zend_hash_init(v8js_process_globals.extensions, 1, NULL, (dtor_func_t) v8js_jsext_dtor, 1);
+	} else if (zend_hash_exists(v8js_process_globals.extensions, name, name_len + 1)) {
+#ifdef ZTS
+		v8js_process_globals.lock.unlock();
+#endif
 		return FAILURE;
 	}
 
@@ -843,6 +850,9 @@ static int v8js_register_extension(char *name, uint name_len, char *source, uint
 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid dependency array passed");
 			v8js_jsext_dtor(jsext);
 			free(jsext);
+#ifdef ZTS
+			v8js_process_globals.lock.unlock();
+#endif
 			return FAILURE;
 		}
 	}
@@ -859,17 +869,23 @@ static int v8js_register_extension(char *name, uint name_len, char *source, uint
 
 	jsext->extension = new v8::Extension(jsext->name, jsext->source, jsext->deps_count, jsext->deps);
 
-	if (zend_hash_add(V8JSG(extensions), name, name_len + 1, jsext, sizeof(v8js_jsext), NULL) == FAILURE) {
+	if (zend_hash_add(v8js_process_globals.extensions, name, name_len + 1, jsext, sizeof(v8js_jsext), NULL) == FAILURE) {
 		v8js_jsext_dtor(jsext);
 		free(jsext);
+#ifdef ZTS
+		v8js_process_globals.lock.unlock();
+#endif
 		return FAILURE;
 	}
 
+#ifdef ZTS
+	v8js_process_globals.lock.unlock();
+#endif
+
 	jsext->extension->set_auto_enable(auto_enable ? true : false);
 	v8::RegisterExtension(jsext->extension);
 
 	free(jsext);
-
 	return SUCCESS;
 }
 /* }}} */
@@ -916,10 +932,15 @@ static PHP_METHOD(V8Js, getExtensions)
 	}
 
 	array_init(return_value);
-	if (V8JSG(extensions)) {
-		zend_hash_internal_pointer_reset_ex(V8JSG(extensions), &pos);
-		while (zend_hash_get_current_data_ex(V8JSG(extensions), (void **) &jsext, &pos) == SUCCESS) {
-			if (zend_hash_get_current_key_ex(V8JSG(extensions), &key, &key_len, &index, 0, &pos) == HASH_KEY_IS_STRING) {
+
+#ifdef ZTS
+	v8js_process_globals.lock.lock();
+#endif
+
+	if (v8js_process_globals.extensions) {
+		zend_hash_internal_pointer_reset_ex(v8js_process_globals.extensions, &pos);
+		while (zend_hash_get_current_data_ex(v8js_process_globals.extensions, (void **) &jsext, &pos) == SUCCESS) {
+			if (zend_hash_get_current_key_ex(v8js_process_globals.extensions, &key, &key_len, &index, 0, &pos) == HASH_KEY_IS_STRING) {
 				MAKE_STD_ZVAL(ext)
 				array_init(ext);
 				add_assoc_bool_ex(ext, ZEND_STRS("auto_enable"), jsext->auto_enable);
@@ -931,9 +952,13 @@ static PHP_METHOD(V8Js, getExtensions)
 				}
 				add_assoc_zval_ex(return_value, key, key_len, ext);
 			}
-			zend_hash_move_forward_ex(V8JSG(extensions), &pos);
+			zend_hash_move_forward_ex(v8js_process_globals.extensions, &pos);
 		}
 	}
+
+#ifdef ZTS
+	v8js_process_globals.lock.unlock();
+#endif
 }
 /* }}} */
 

+ 3 - 2
v8js_v8.cc

@@ -61,8 +61,9 @@ void v8js_v8_init(TSRMLS_D) /* {{{ */
 #endif
 
 	/* Set V8 command line flags (must be done before V8::Initialize()!) */
-	if (V8JSG(v8_flags)) {
-		v8::V8::SetFlagsFromString(V8JSG(v8_flags), strlen(V8JSG(v8_flags)));
+	if (v8js_process_globals.v8_flags) {
+		v8::V8::SetFlagsFromString(v8js_process_globals.v8_flags,
+								   strlen(v8js_process_globals.v8_flags));
 	}
 
 	/* Initialize V8 */