Saxon/C - PHP C++ extension threading issues

  107821
November 18, 2019 14:55 oneil@saxonica.com (O'Neil Delpratt)
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