Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Each child process has its own copy of extension's global variables #329

Open
yogistraAnderson opened this issue Apr 22, 2017 · 1 comment

Comments

@yogistraAnderson
Copy link

This is my setup:
OS: Ubuntu 12.04 LTS

Web Server: Apache/2.4.12 (Ubuntu) OpenSSL/1.0.1f
Server MPM: prefork
Server Built: Feb 4 2015 14:21:55

PHP Version 7.0.14-2+deb.sury.org~precise+1

PHP-CPP: 2.0

I am developing an extension that requires an initialization function to set up some global variables. The functions I am exposing to PHP will be utilizing those globals.

This only needs to be done once the web server is started up, upon the first call of the exposed function.

The init only should be done once, set the is_init flag and never to be called again during the lifetime of the webserver process. However I am seeing the init function called multiple times. I though it was a synchronization problem and even added a mutex lock.

After adding some logging code, and making several requests to the web server, it looks like requests that are spawning new worker processes are calling the init function again(because they have their own copy of the flag which is not set). Requests the reuse the workers are working correctly and the init is not being called.

my code looks like this:

` bool b_is_initialized=false;
mutex init_lock;

void initialize(){
	if(b_is_initialized){
		return;
	}else{			
		Php::call("error_log","initializing, pid:");
		Php::call("error_log",getpid());
	}
	
	b_is_initialized=true;
}

Php::Value secure_require_once(Php::Parameters &params){
	Php::Value secure_file_nm = params[0];
	
	if(!b_is_initialized){			
		 init_lock.lock();
		 initialize();			
		 init_lock.unlock();
	}
	
	return 0;
}

extern "C" {
	PHPCPP_EXPORT void *get_module() {
		static Php::Extension extension("AS_Loader", "1.0");
		
		extension.onStartup([](){			
			//initialize();
		});
		
		
		// install a callback that is called at the beginning of each request(the execution of script)
		extension.onRequest([]() {
			Php::call("error_log","request processed");
			Php::call("error_log",getpid());            
		});
		
		
		extension.add<secure_require_once>("secure_require_once");
		
		
		return extension;
	}
}`

The calling page is this:

<?php 
	echo secure_require_once("cls_file_import_np.php");
?>

This is the output of the logging:

[22-Apr-2017 07:58:22 America/New_York] request processed
[22-Apr-2017 07:58:22 America/New_York] 2024
[22-Apr-2017 07:58:22 America/New_York] initializing, pid:
[22-Apr-2017 07:58:22 America/New_York] 2024
[22-Apr-2017 07:58:29 America/New_York] request processed
[22-Apr-2017 07:58:29 America/New_York] 2023
[22-Apr-2017 07:58:29 America/New_York] initializing, pid:
[22-Apr-2017 07:58:29 America/New_York] 2023
[22-Apr-2017 07:58:35 America/New_York] request processed
[22-Apr-2017 07:58:35 America/New_York] 2022
[22-Apr-2017 07:58:35 America/New_York] initializing, pid:
[22-Apr-2017 07:58:35 America/New_York] 2022
[22-Apr-2017 07:58:40 America/New_York] request processed
[22-Apr-2017 07:58:40 America/New_York] 2022
[22-Apr-2017 07:58:44 America/New_York] request processed
[22-Apr-2017 07:58:44 America/New_York] 2022

Note: I tried to do the initialization on the extension's onStartup callback but the webserver would not start. (The real init function uses curl to download, I dont know if thats an issue with the startup). That may be a different issue.

So I am left to do it on the first call of the exposed function(secure_require_once), but I am getting this strange behaviour.

@redagito
Copy link

This is default behavior for Apache, the extension is loaded and kept loaded for a limited amount of requests (lets say 10) and unloaded/reloaded afterwards. Each worker thread also has its own php environment and thus also extension(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants