FAQ
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

Search Discussions

  • Antony Dovgal at Jun 2, 2008 at 10:40 am

    On 02.06.2008 13:35, Adam Klobukowski wrote:
    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
  • Adam Klobukowski at Jun 2, 2008 at 4:49 pm

    Antony Dovgal pisze:
    On 02.06.2008 13:35, Adam Klobukowski wrote:
    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(&params, 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(&params, 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
  • Antony Dovgal at Jun 3, 2008 at 7:32 am

    On 02.06.2008 20:49, Adam Klobukowski wrote:
    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
  • Adam Klobukowski at Jun 3, 2008 at 12:01 pm

    Antony Dovgal pisze:
    On 02.06.2008 20:49, Adam Klobukowski wrote:
    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

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupphp-internals @
categoriesphp
postedJun 2, '08 at 10:30a
activeJun 3, '08 at 12:01p
posts5
users2
websitephp.net

2 users in discussion

Adam Klobukowski: 3 posts Antony Dovgal: 2 posts

People

Translate

site design / logo © 2022 Grokbase