Saxon/C - PHP C++ extension threading issues
| From: | O'Neil Delpratt | Date: | Mon, 18 Nov 2019 14:55:26 +0000 |
| Subject: | Saxon/C - PHP C++ extension threading issues | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-107821@lists.php.net to get a copy of this message | ||
Hi,
Consultancy help:
I have written an PHP 7.X extension to my Saxon/C C++ API. My C++ program has an Excelsior JET JNI
environment which is created as a static variable at the start of the program and released at the
end.
The threads are created by the JET Runtime, e.g. GC thread, weak reference handler thread,
finalizers thread, etc. Initially I thought best to create the Jet runtime for each request, but
this did not work. So I tried to keep the Jet runtime alive for the lifetime of the extension, which
could be reused between requests.
I create the JET runtime (which has several threads) in the PHP_MINIT_FUNCTION(saxonc)
To make sure the clean up of the JET threads happens I have added a release method in the
MSHUTDOWN_FUNCTION of the PHP extension.
The problem is when I run the PHP extension in the browser it just hangs. If I remove the code to
manage the JET threads the PHP scripts run, but does not kill the JET threads. The only way to kill
the threads.
How can I manage these resources between requests? Is there a way to keep a global variable to the
JET resources that maintains the static variable from the C++ code between requests?
Somehow I think the management via globals as discussed in your blog: http://blog.jpauli.tech/2017-01-12-threads-and-php-html/
is relevant and I have tried to follow through with this in some test code to get things working,
but still not resolved the issue.
Here is snippet of the my C++ code for the PHP extension:
void php_saxonc_initialize(void){
if(SaxonProcessor::jvmCreatedCPP == 0){
SaxonProcessor::jvmCreatedCPP=1;
SaxonProcessor::sxn_environ= (sxnc_environment *)malloc(sizeof(sxnc_environment));
/*
* First of all, load required component.
* By the time of JET initialization, all components should be loaded.
*/
SaxonProcessor::sxn_environ->myDllHandle = loadDefaultDll ();
/*
* Initialize JET run-time.
* The handle of loaded component is used to retrieve Invocation API.
*/
initDefaultJavaRT
(SaxonProcessor::sxn_environ);
}
}
PHP_MINIT_FUNCTION
(saxon)
{
php_saxonc_initialize
();
zend_class_entry ce
;
INIT_CLASS_ENTRY
(ce, "SaxonProcessor", SaxonProcessor_methods);
....
In a different approach I tried calling the php_saxonc_initialize() method in the 'static
PHP_GINIT_FUNCTION(saxon)’ but still did not get it to work.
This is linked to this bug issue: https://saxonica.plan.io/issues/2055
Full source code for the PHP extension Saxon/C: https://dev.saxonica.com/repos/archive/opensource/latest9.9/hec/Saxon.C.API/php7_saxon.cpp
https://dev.saxonica.com/repos/archive/opensource/latest9.9/hec/Saxon.C.API/php_saxon.h
I am wondering if someone could assist me and collaborate to resolve it. We are willing to pay for
the consultancy work.
kind regards,
O'Neil