FAQ

[svn:PHP-Sandwich] r1446 - in PHP-Sandwich/trunk: . lib/PHP t

Gschlossnagle
Aug 1, 2005 at 11:00 pm
Author: gschlossnagle
Date: Mon Aug 1 16:00:34 2005
New Revision: 1446

Modified:
PHP-Sandwich/trunk/PHP.xs
PHP-Sandwich/trunk/lib/PHP/Interpreter.pm
PHP-Sandwich/trunk/phpinterp.c
PHP-Sandwich/trunk/phpinterp.h
PHP-Sandwich/trunk/t/7.t
Log:
make this stuff work with php-5.0

Modified: PHP-Sandwich/trunk/PHP.xs
==============================================================================
--- PHP-Sandwich/trunk/PHP.xs (original)
+++ PHP-Sandwich/trunk/PHP.xs Mon Aug 1 16:00:34 2005
@@ -200,7 +200,7 @@ SV *newSVzval(zval *zptr, PHP_Interprete
{
SV *retval;
void *old_ctx;
- old_ctx = tsrm_set_interpreter_context(interp->ctx);
+ INTERP_CTX_ENTER(interp->ctx);
{
TSRMLS_FETCH();
switch( zptr->type) {
@@ -337,7 +337,7 @@ SV *newSVzval(zval *zptr, PHP_Interprete
break;
}
}
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
return retval;
}

@@ -455,7 +455,7 @@ SV* SAND_new(classname, ...)
SV *trackvars;
char *trackvars_key;
I32 trackvars_keylen;
- void *old_ctx = tsrm_set_interpreter_context(interp->ctx);
+ INTERP_CTX_ENTER(interp->ctx);
TSRMLS_FETCH();
hv_iterinit(args);
while((trackvars = hv_iternextsv(args, &trackvars_key, &trackvars_keylen)) != NULL) {
@@ -518,7 +518,7 @@ SV* SAND_new(classname, ...)
}
}
my_auto_globals_create_request(NULL TSRMLS_CC);
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
}
RETVAL = newSV(0);
sv_setref_pv(RETVAL, classname, (void *)interp);
@@ -542,7 +542,23 @@ SV *SAND_include(interp, file)
char *file;
CODE:
{
- if(sandwich_include(interp, file) == 0) {
+ if(sandwich_include(interp, file, 0) == 0) {
+ RETVAL = newSVsv(ST(0));
+ }
+ else {
+ croak("Error including %s\n", file);
+ RETVAL = &PL_sv_no;
+ }
+ }
+ OUTPUT:
+ RETVAL
+
+SV *SAND_include_once(interp, file)
+ PHP_Interpreter interp;
+ char *file;
+ CODE:
+ {
+ if(sandwich_include(interp, file, 1) == 0) {
RETVAL = newSVsv(ST(0));
}
else {
@@ -563,9 +579,8 @@ SV *SAND_call(interp, method_name, ...)
int i;
int param_count = 0;
zval *retval;
- void *old_ctx;
char *croakstr = NULL;
- old_ctx = tsrm_set_interpreter_context(interp->ctx);
+ INTERP_CTX_ENTER(interp->ctx);
{
TSRMLS_FETCH();
INIT_ZVAL(method);
@@ -580,18 +595,31 @@ SV *SAND_call(interp, method_name, ...)
retval = sandwich_call_function(interp, &method, params, param_count);
zval_dtor(&method);
if(retval == NULL) {
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
croakstr = "A PHP error occured\n";
} else {
RETVAL = newSVzval(retval, interp);
}
}
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
if(croakstr) croak(croakstr);
}
OUTPUT:
RETVAL

+SV *SAND_is_multithreaded(interp)
+ PHP_Interpreter interp;
+ CODE:
+ {
+#ifdef ZTS
+ RETVAL = &PL_sv_yes;
+#else
+ RETVAL = &PL_sv_no;
+#endif
+ }
+ OUTPUT:
+ RETVAL
+
SV *SAND_set_output_handler(interp, sv)
PHP_Interpreter interp;
SV *sv;
@@ -643,11 +671,9 @@ SV* SAND_instantiate(interp, class, ...)
char *class;
CODE:
{
- void *old_ctx;
char *croakstr = NULL;
zval *obj = NULL;
-
- old_ctx = tsrm_set_interpreter_context(interp->ctx);
+ INTERP_CTX_ENTER(interp->ctx);
{
zend_fcall_info fci;
zval method;
@@ -697,7 +723,7 @@ SV* SAND_instantiate(interp, class, ...)
}
}
if(obj) RETVAL = newSVzval(obj, interp);
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
if(croakstr) croak(croakstr);
}
OUTPUT:
@@ -715,9 +741,7 @@ SV* PHP_V_C_FETCH(pclass, key)
{
zend_class_entry *ce;
zval *retval;
- void *old_ctx;
-
- old_ctx = tsrm_set_interpreter_context(pclass->interp->ctx);
+ INTERP_CTX_ENTER(pclass->interp->ctx);
{
TSRMLS_FETCH();

@@ -725,7 +749,7 @@ SV* PHP_V_C_FETCH(pclass, key)
retval = zend_read_property(ce, pclass->val, key, strlen(key), 0 TSRMLS_CC);
RETVAL = newSVzval(retval, pclass->interp);
}
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
}
OUTPUT:
RETVAL
@@ -738,9 +762,8 @@ SV* PHP_V_C_STORE(pclass, key, value)
{
zend_class_entry *ce;
zval *retval;
- void *old_ctx;

- old_ctx = tsrm_set_interpreter_context(pclass->interp->ctx);
+ INTERP_CTX_ENTER(pclass->interp->ctx);
{
zval *tostore;
TSRMLS_FETCH();
@@ -751,7 +774,7 @@ SV* PHP_V_C_STORE(pclass, key, value)
else croak("problem converting perl type to SV");
RETVAL = newSVsv(value);
}
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
}
OUTPUT:
RETVAL
@@ -764,9 +787,8 @@ SV* PHP_V_C_FIRSTKEY(pclass)
ulong index;
char buf[32];
HashTable *properties;
- void *old_ctx;

- old_ctx = tsrm_set_interpreter_context(pclass->interp->ctx);
+ INTERP_CTX_ENTER(pclass->interp->ctx);
{
TSRMLS_FETCH();
properties = Z_OBJPROP_P(pclass->val);
@@ -785,7 +807,7 @@ SV* PHP_V_C_FIRSTKEY(pclass)
break;
}
}
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
}
OUTPUT:
RETVAL
@@ -801,7 +823,7 @@ SV* PHP_V_C_NEXTKEY(pclass, lastkey)
HashTable *properties;
void *old_ctx;

- old_ctx = tsrm_set_interpreter_context(pclass->interp->ctx);
+ INTERP_CTX_ENTER(pclass->interp->ctx);
{
TSRMLS_FETCH();
properties = Z_OBJPROP_P(pclass->val);
@@ -820,7 +842,7 @@ SV* PHP_V_C_NEXTKEY(pclass, lastkey)
break;
}
}
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
}
OUTPUT:
RETVAL
@@ -835,7 +857,7 @@ SV* PHP_V_C_EXISTS(pclass, skey)
HashTable *properties;
void *old_ctx;

- old_ctx = tsrm_set_interpreter_context(pclass->interp->ctx);
+ INTERP_CTX_ENTER(pclass->interp->ctx);
{
TSRMLS_FETCH();
properties = Z_OBJPROP_P(pclass->val);
@@ -846,7 +868,7 @@ SV* PHP_V_C_EXISTS(pclass, skey)
RETVAL = &PL_sv_no;
}
}
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
}
OUTPUT:
RETVAL
@@ -862,7 +884,7 @@ SV *PHP_V_C_DELETE(pclass, skey)
zval zkey;
void *old_ctx;

- old_ctx = tsrm_set_interpreter_context(pclass->interp->ctx);
+ INTERP_CTX_ENTER(pclass->interp->ctx);
{
TSRMLS_FETCH();
properties = Z_OBJPROP_P(pclass->val);
@@ -880,7 +902,7 @@ SV *PHP_V_C_DELETE(pclass, skey)
RETVAL = &PL_sv_yes;
zval_dtor(&zkey);
}
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
}
OUTPUT:
RETVAL
@@ -891,7 +913,6 @@ SV *PHP_V_C__AUTOLOAD(self, method_name,
CODE:
{
PHP_Interpreter_Class pclass;
- void *old_ctx;
MAGIC *mg;
zval method;
zval ***params = NULL;
@@ -907,7 +928,7 @@ SV *PHP_V_C__AUTOLOAD(self, method_name,

interp = pclass->interp;

- old_ctx = tsrm_set_interpreter_context(interp->ctx);
+ INTERP_CTX_ENTER(interp->ctx);
{
zend_fcall_info fci;
TSRMLS_FETCH();
@@ -1043,7 +1064,7 @@ SV *PHP_V_C__AUTOLOAD(self, method_name,
efree(fci.params);
}
zval_dtor(&method);
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
}
if(croakstr) croak(croakstr);
}
@@ -1062,12 +1083,12 @@ void PHP_V_C_DESTROY(in)
if(!mg || !mg->mg_obj || !SvROK(mg->mg_obj) || !SvIOK(SvRV(mg->mg_obj))) return;
pclass = (PHP_Interpreter_Class) SvIV(SvRV(mg->mg_obj));
if(!pclass) return;
- old_ctx = tsrm_set_interpreter_context(pclass->interp->ctx);
+ INTERP_CTX_ENTER(pclass->interp->ctx);
{
TSRMLS_FETCH();
zval_ptr_dtor(&pclass->val);
}
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
/* potentially shutdown ZE */
sandwich_interp_dec_ref(pclass->interp);
free(pclass);
@@ -1088,7 +1109,7 @@ SV* PHP_V_C_create(in, class, ...)
if(!mg) return;
pclass = (PHP_Interpreter_Class) SvIV(SvRV(mg->mg_obj));
if(!pclass) return;
- old_ctx = tsrm_set_interpreter_context(pclass->interp->ctx);
+ INTERP_CTX_ENTER(pclass->interp->ctx);
{
zend_fcall_info fci;
zval method;
@@ -1116,7 +1137,7 @@ SV* PHP_V_C_create(in, class, ...)
RETVAL = newSVzval(obj, pclass->interp);
}
}
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
if(croakstr) croak(croakstr);
}
OUTPUT:
@@ -1132,13 +1153,13 @@ PHP_Interpreter_Resource PHP_V_R_FETCH(z
PHP_Interpreter_Resource rv;
CODE:
{
- void *old_ctx = tsrm_set_interpreter_context(zptr->interp->ctx);
+ INTERP_CTX_ENTER(zptr->interp->ctx);
RETVAL = malloc(sizeof(*RETVAL));
MAKE_STD_ZVAL(RETVAL->val);
ZVAL_ZVAL(RETVAL->val, zptr->val, 1, 0);
RETVAL->interp = zptr->interp;
sandwich_interp_inc_ref(zptr->interp);
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
}
OUTPUT:
RETVAL
@@ -1155,12 +1176,12 @@ void PHP_V_R_DESTROY(prsrc)
CODE:
{
if(!prsrc || !prsrc->interp) return;
- void *old_ctx = tsrm_set_interpreter_context(prsrc->interp->ctx);
+ INTERP_CTX_ENTER(prsrc->interp->ctx);
{
TSRMLS_FETCH();
zval_ptr_dtor(&prsrc->val);
}
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
/* potentially shutdown ZE */
sandwich_interp_dec_ref(prsrc->interp);
free(prsrc);

Modified: PHP-Sandwich/trunk/lib/PHP/Interpreter.pm
==============================================================================
--- PHP-Sandwich/trunk/lib/PHP/Interpreter.pm (original)
+++ PHP-Sandwich/trunk/lib/PHP/Interpreter.pm Mon Aug 1 16:00:34 2005
@@ -129,8 +129,25 @@ script, or true. Throw an exception on f
$php->include("somePhpFile.php");

Calls the PHP construct include on the specified file (similar to Perl's
+C<use> keyword). Does not suppress duplicate usages. Throws an exception on failure.
+
+=head3 include_once()
+
+ $php->include_once("somePhpFile.php");
+
+Calls the PHP construct include_once on the specified file (similar to Perl's
C<use> keyword). Throws an exception on failure.

+=head3 is_multithreaded()
+
+ if($php->is_multithread) {
+ # I can instantiate a second independent interpreter
+ }
+
+A runtime check to determine if PHP is thread-safe - i.e. if more than one interpreter
+can be simultaneously instantiated. If not, further calls to PHP::Interpreter->new()
+will return the original PHP interpreter instance.
+
=head3 call()

$rv = $php->call(stroupper => $perlVar);

Modified: PHP-Sandwich/trunk/phpinterp.c
==============================================================================
--- PHP-Sandwich/trunk/phpinterp.c (original)
+++ PHP-Sandwich/trunk/phpinterp.c Mon Aug 1 16:00:34 2005
@@ -13,6 +13,11 @@
#include "phpinterp.h"
#include "phpfuncs.h"

+/* a true global in non-threaded servers */
+#ifndef ZTS
+static sandwich_per_interp *one_true_interp = NULL;
+#endif
+
static pthread_key_t sandwich_per_thread_info_key;

/* {{{ sandwich SAPI Details */
@@ -116,6 +121,7 @@ int sandwich_php_interpreter_create()
if(ze_started) {
return 0;
}
+#ifdef ZTS
pthread_key_create(&sandwich_per_thread_info_key, NULL);

if (!tsrm_startup(128, 32, TSRM_ERROR_LEVEL_CORE, "/tmp/TSRM.log")) {
@@ -128,6 +134,7 @@ int sandwich_php_interpreter_create()
core_globals = ts_resource(core_globals_id);
sapi_globals = ts_resource(sapi_globals_id);
tsrm_ls = ts_resource(0);
+#endif

sandwich_sapi.php_ini_path_override = "/opt/ecelerity/3rdParty/lib/php.ini";
sapi_startup(&sandwich_sapi);
@@ -144,49 +151,63 @@ sandwich_per_interp *sandwich_per_interp
{
/* if (!conf->eval_ok) return NULL; */
sandwich_per_interp *info;
- void *old_ctx = NULL;
+
+#ifndef ZTS
+ if(one_true_interp) return one_true_interp;
+#endif

info = calloc(sizeof(*info), 1);
+ info->ref = 1;

- if (!info->ctx) {
- info->ctx = tsrm_new_interpreter_context();
- info->ref = 1;
- old_ctx = tsrm_set_interpreter_context(info->ctx);
- {
- TSRMLS_FETCH();
-
- zend_alter_ini_entry("register_argc_argv", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
- zend_alter_ini_entry("html_errors", 12, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
- zend_alter_ini_entry("implicit_flush", 15, "1", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
- zend_alter_ini_entry("max_execution_time", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
-
- SG(headers_sent) = 1;
- SG(request_info).no_headers = 1;
- SG(server_context) = info;
- SG(options) = SAPI_OPTION_NO_CHDIR;
- php_request_startup(TSRMLS_C);
- PG(during_request_startup) = 0;
- SandwichG(php) = info;
- tsrm_set_interpreter_context(old_ctx);
- }
+#ifdef ZTS
+ info->ctx = tsrm_new_interpreter_context();
+#else
+ one_true_interp = info;
+#endif
+
+ info->ref = 1;
+ INTERP_CTX_ENTER(info->ctx);
+ {
+ TSRMLS_FETCH();
+
+ zend_alter_ini_entry("register_argc_argv", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
+ zend_alter_ini_entry("html_errors", 12, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
+ zend_alter_ini_entry("implicit_flush", 15, "1", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
+ zend_alter_ini_entry("max_execution_time", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
+
+ SG(headers_sent) = 1;
+ SG(request_info).no_headers = 1;
+ SG(server_context) = info;
+ SG(options) = SAPI_OPTION_NO_CHDIR;
+ php_request_startup(TSRMLS_C);
+ PG(during_request_startup) = 0;
+ SandwichG(php) = info;
+ INTERP_CTX_LEAVE();
}
+
return info;
}


void sandwich_per_interp_shutdown(sandwich_per_interp *interp)
{
- void *old_ctx = NULL;
- old_ctx = tsrm_set_interpreter_context(interp->ctx);
+#ifndef ZTS
+ if(one_true_interp == NULL) return;
+ else one_true_interp = NULL;
+#endif
+
+ INTERP_CTX_ENTER(interp->ctx);
{
TSRMLS_FETCH();
php_request_shutdown(NULL);
- tsrm_set_interpreter_context(NULL);
+ INTERP_CTX_LEAVE();
+#ifdef ZTS
tsrm_free_interpreter_context(interp->ctx);
+#endif
interp->ctx = NULL;
free(interp);
}
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
}

int my_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
@@ -251,9 +272,8 @@ int my_eval_string(char *str, zval *retv
SV *sandwich_eval(sandwich_per_interp *interp, char *code)
{
int rv = 0;
- void *old_ctx = NULL;
zval retval;
- old_ctx = tsrm_set_interpreter_context(interp->ctx);
+ INTERP_CTX_ENTER(interp->ctx);
{
TSRMLS_FETCH();
zend_try {
@@ -268,7 +288,7 @@ SV *sandwich_eval(sandwich_per_interp *i
}
}
cleanup:
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
if(rv == -1) {
croak("PHP Error in eval");
} else {
@@ -279,21 +299,27 @@ cleanup:
}
}

-int sandwich_include(sandwich_per_interp *interp, char *file)
+int sandwich_include(sandwich_per_interp *interp, char *file, int once)
{
int rv = 0;
void *old_ctx = NULL;
- old_ctx = tsrm_set_interpreter_context(interp->ctx);
+ INTERP_CTX_ENTER(interp->ctx);
{
zend_file_handle file_handle;
TSRMLS_FETCH();
zend_try {
+ int dummy = 1;
SG(request_info).path_translated = file;
file_handle.type = ZEND_HANDLE_FILENAME;
file_handle.handle.fd = 0;
file_handle.filename = SG(request_info).path_translated;
file_handle.opened_path = NULL;
file_handle.free_filename = 0;
+ if(zend_hash_add(&EG(included_files), file, strlen(file)+1, (void *)&dummy, sizeof(int), NULL) != SUCCESS&& once) {
+ /* implicit success! */
+ rv = 0;
+ goto cleanup;
+ }
rv = (php_execute_script(&file_handle TSRMLS_CC) == 1)?0:-1;
} zend_catch {
rv = -1;
@@ -302,7 +328,7 @@ int sandwich_include(sandwich_per_interp
}
}
cleanup:
- tsrm_set_interpreter_context(old_ctx);
+ INTERP_CTX_LEAVE();
return rv;
}


Modified: PHP-Sandwich/trunk/phpinterp.h
==============================================================================
--- PHP-Sandwich/trunk/phpinterp.h (original)
+++ PHP-Sandwich/trunk/phpinterp.h Mon Aug 1 16:00:34 2005
@@ -31,7 +31,7 @@ sandwich_per_interp *sandwich_per_interp
void sandwhich_per_interp_shutdown(sandwich_per_interp *interp);

SV *sandwich_eval(sandwich_per_interp *interp, char *code);
-int sandwich_include(sandwich_per_interp *interp, char *file);
+int sandwich_include(sandwich_per_interp *interp, char *file, int once);

/* NOTE: caller must tsrm_set_interpreter_context and reset the old one */
zval *sandwich_call_function(sandwich_per_interp *interp, zval *method, zval **params, zend_uint param_count);
@@ -42,4 +42,12 @@ zval *sandwich_call_function(sandwich_pe
zval *SvZval(SV *sv TSRMLS_DC);
SV *newSVzval(zval *param, sandwich_per_interp *interp);

+#ifdef ZTS
+#define INTERP_CTX_ENTER(ctx) void *old_ctx = tsrm_set_interpreter_context(ctx)
+#define INTERP_CTX_LEAVE() tsrm_set_interpreter_context(old_ctx)
+#else
+#define INTERP_CTX_ENTER(ctx)
+#define INTERP_CTX_LEAVE()
+#endif
+
#endif

Modified: PHP-Sandwich/trunk/t/7.t
==============================================================================
--- PHP-Sandwich/trunk/t/7.t (original)
+++ PHP-Sandwich/trunk/t/7.t Mon Aug 1 16:00:34 2005
@@ -14,10 +14,20 @@ ok my $a1 = $p->include($inc)->call('ide
"Including a PHP file and executing a function off iti via call";

ok my $p2 = new PHP::Interpreter(), "Create new PHP interpreter";
-ok $a1 = $p2->include($inc)->ident(1),
- "Including a PHP file and executing a function off iti via AUTOLOAD";
+if($p2->is_multithreaded) {
+ ok $a1 = $p2->include($inc)->ident(1),
+ "Including a PHP file and executing a function off iti via AUTOLOAD";
+}
+else {
+ ok $a1 = $p2->include_once($inc)->ident(1),
+ "Including a PHP file and executing a function off iti via AUTOLOAD";
+}

ok my $p3 = new PHP::Interpreter(), "Create new PHP interpreter";
-ok $p3->include($inc), "Including a file";
+if($p3->is_multithreaded) {
+ ok $p3->include($inc), "Including a file";
+} else {
+ ok $p3->include_once($inc), "Including a file";
+}
ok $p3->ident(1),
"... and executing a function off it via AUTOLOAD (2)";
reply

Search Discussions

Related Discussions

Discussion Navigation
viewthread | post

1 user in discussion

Gschlossnagle: 1 post