Hello
I'm writing a PHP extension where I'm using a custom library. This
library uses a structure that needs to be initialized once per server
instance. First I initialized it in each of my functions and
deinitialize it ant the end. It works ok, but unfortunetly it turns to
be to slow. So, I'm trying to do it globally. Everything in that library
is internally synchronized, so I don not have to worry about thread
safety. I declare my structure globally (in fact a pointer to a
structure), initialize it in PHP_MINIT (it works), then deinitialize in
PHP_MSHUTDOWN (works too). Unfortunetly, when I'm trying to use this
structure in my PHP_FUNCTIONs, it does not work.
What i don't know, if PHP magic does something that prevents using such
globals. Should I use global resources for that instead?
Btw. I'm looking for a good reference of internal PHP APIs. I found
excelent Sara's Golemon articles, but thats all, is there anything better?
--
Semper Fidelis
Adam Klobukowski
adam@klobukowski.pl
Hello
I'm writing a PHP extension where I'm using a custom library. This
library uses a structure that needs to be initialized once per server
instance. First I initialized it in each of my functions and
deinitialize it ant the end. It works ok, but unfortunetly it turns to
be to slow. So, I'm trying to do it globally. Everything in that library
is internally synchronized, so I don not have to worry about thread
safety. I declare my structure globally (in fact a pointer to a
structure), initialize it in PHP_MINIT (it works), then deinitialize in
PHP_MSHUTDOWN (works too).
That's exactly what lots of extensions do.
Unfortunetly, when I'm trying to use this
structure in my PHP_FUNCTIONs, it does not work.
You've managed to describe everything except for the problem itself =)
What does this "does not work" mean?
How exactly do you initialize and address these variables?
Btw. I'm looking for a good reference of internal PHP APIs. I found
excelent Sara's Golemon articles, but thats all, is there anything better?
The sources are better.
--
Wbr,
Antony Dovgal
Antony Dovgal pisze:
Hello
I'm writing a PHP extension where I'm using a custom library. This
library uses a structure that needs to be initialized once per server
instance. First I initialized it in each of my functions and
deinitialize it ant the end. It works ok, but unfortunetly it turns to
be to slow. So, I'm trying to do it globally. Everything in that
library is internally synchronized, so I don not have to worry about
thread safety. I declare my structure globally (in fact a pointer to a
structure), initialize it in PHP_MINIT (it works), then deinitialize
in PHP_MSHUTDOWN (works too).That's exactly what lots of extensions do.
Unfortunetly, when I'm trying to use this structure in my
PHP_FUNCTIONs, it does not work.You've managed to describe everything except for the problem itself =)
What does this "does not work" mean?
How exactly do you initialize and address these variables?
My code uses Yami message passing library
(http://www.msobczak.com/prog/yami/)
Ok, here is the code, first the "working" (one standalone function) version:
PHP_FUNCTION(myFunc)
{
HPARAMSET params, returnparamset;
HMESSAGE hm;
enum msgStatus status;
char *id = NULL;
int id_len;
int i, count, size;
char *element = NULL;
char *server_port = NULL;
char *server_ip = NULL;
char *name = NULL;
char *value = NULL;
double d;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id,
&id_len) == FAILURE) return;
yamiNetInitialize();
yamiCreateAgent(&agent, 0, NULL);
yamiAgentDomainRegister(agent, SERVER_NAME, SERVER_ADDRES,
SERVER_PORT, 2);
yamiCreateParamSet(¶ms, 1);
yamiSetString(params, 0, id);
yamiAgentMsgSend(agent, SERVER_NAME, id, "get_info", params, &hm);
yamiAgentMsgWait(hm);
yamiAgentMsgGetStatus(hm, &status);
if (status == eReplied)
{
yamiAgentMsgGetResponse(hm, &returnparamset);
if (!returnparamset)
{
return;
}
yamiGetParamCount(returnparamset, &count);
array_init(return_value);
for (i = 0; i < count; i++)
{
yamiGetStringLength(returnparamset, i, &size);
name = emalloc (sizeof (char) * (size +1));
yamiGetStringValue(returnparamset, i, name);
i++;
yamiGetStringLength(returnparamset, i, &size);
value = emalloc (sizeof (char) * (size +1));
yamiGetStringValue(returnparamset, i, value);
add_assoc_string(return_value, name , value, 0);
}
yamiDestroyParamSet(returnparamset);
yamiDestroyParamSet(params);
yamiDestroyAgent(agent);
yamiNetCleanup();
}
else
{
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong answer from
server.");
}
}
And the non working (with PHP_MINIT and PHP_SHUTDOWN) version:
HYAMIAGENT agent;
PHP_MINIT_FUNCTION(gra)
{
yamiNetInitialize();
yamiCreateAgent(&agent, 0, NULL);
yamiAgentDomainRegister(agent, SERVER_NAME, SERVER_ADDRES,
SERVER_PORT, 2);
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION(gra)
{
yamiDestroyAgent(agent);
yamiNetCleanup();
return SUCCESS;
}
PHP_FUNCTION(myFunc)
{
HPARAMSET params, returnparamset;
HMESSAGE hm;
enum msgStatus status;
char *id = NULL;
int id_len;
int i, count, size;
char *element = NULL;
char *server_port = NULL;
char *server_ip = NULL;
char *name = NULL;
char *value = NULL;
double d;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id,
&id_len) == FAILURE) return;
yamiCreateParamSet(¶ms, 1);
yamiSetString(params, 0, id);
yamiAgentMsgSend(agent, SERVER_NAME, id, "get_info", params, &hm);
yamiAgentMsgWait(hm);
yamiAgentMsgGetStatus(hm, &status);
if (status == eReplied)
{
yamiAgentMsgGetResponse(hm, &returnparamset);
if (!returnparamset)
{
return;
}
yamiGetParamCount(returnparamset, &count);
array_init(return_value);
for (i = 0; i < count; i++)
{
yamiGetStringLength(returnparamset, i, &size);
name = emalloc (sizeof (char) * (size +1));
yamiGetStringValue(returnparamset, i, name);
i++;
yamiGetStringLength(returnparamset, i, &size);
value = emalloc (sizeof (char) * (size +1));
yamiGetStringValue(returnparamset, i, value);
add_assoc_string(return_value, name , value, 0);
}
yamiDestroyParamSet(returnparamset);
yamiDestroyParamSet(params);
}
else
{
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong answer from
server.");
}
}
And by "non working" I mean that it hangs in yamiAgentMsgWait forever :(
Adam Klobukowski
HYAMIAGENT agent;
PHP_MINIT_FUNCTION(gra)
{
yamiNetInitialize();yamiCreateAgent(&agent, 0, NULL); yamiAgentDomainRegister(agent, SERVER_NAME, SERVER_ADDRES,
SERVER_PORT, 2);
return SUCCESS;
}
/* }}} */
Well, this is clearly wrong as the agent object has to be created by your
functions each time - in the same way as MySQL are created each time you
connect to a MySQL server.
But I guess the NetInitialize() function might be called once per process.
Also you didn't mention whether you're developing on Windows or not -
there seem to be quite a noticeable difference in the way that library works.
--
Wbr,
Antony Dovgal
Antony Dovgal pisze:
HYAMIAGENT agent;
PHP_MINIT_FUNCTION(gra)
{
yamiNetInitialize();yamiCreateAgent(&agent, 0, NULL); yamiAgentDomainRegister(agent, SERVER_NAME, SERVER_ADDRES,
SERVER_PORT, 2);
return SUCCESS;
}
/* }}} */Well, this is clearly wrong as the agent object has to be created by
your functions each time - in the same way as MySQL are created each
time you
connect to a MySQL server.
Thats is not true. Agent is multi threaded internally and required once
per instance. For example, in server, one agent is responsible for all
communication for multiple objects (services).
But I guess the NetInitialize() function might be called once per process.
That's true.
Also you didn't mention whether you're developing on Windows or not -
there seem to be quite a noticeable difference in the way that library
works.
I'm developing for Linux.
Adam Klobukowski