From: Mark L. Woodward Date: Tue, 4 Jun 2002 13:59:46 +0000 (+0000) Subject: Added persistent connections, and automattic reconnect on X-Git-Tag: RELEASE_0_90~37 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=63ded04ef5da1f82b2519be09f7d05bb6c87fae0;p=php Added persistent connections, and automattic reconnect on lost connections. Requires Phoenix 1.0 --- diff --git a/ext/msession/msession.c b/ext/msession/msession.c index fd7043fa0b..e06018034a 100644 --- a/ext/msession/msession.c +++ b/ext/msession/msession.c @@ -16,6 +16,10 @@ | Portions copyright the PHP group. | +----------------------------------------------------------------------+ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "php.h" #include "php_ini.h" #include "php_msession.h" @@ -23,6 +27,7 @@ #include "ext/standard/info.h" #include "ext/session/php_session.h" + /* Macros and such */ #ifndef TRUE #define TRUE 1 @@ -37,6 +42,13 @@ /* Uncomment to get debugging messages */ /* #define ERR_DEBUG */ +/* Uncomment for conections which are persistent for a process + * This will be faster but allocates a thread in the msession + * daemon. + * Pros: No reconnect overhead. + * cons: Msession maintains a thread per connection. + */ +/* #define PERSISTENT_CONN */ #ifdef ERR_DEBUG #define ELOG( str ) php_log_err( str ) @@ -50,6 +62,10 @@ #define IFCONNECT_ENDVAL(V) } else { php_error(E_WARNING, s_szNoInit); return V; } #define IFCONNECT_END } else { php_error(E_WARNING, s_szNoInit); RETURN_FALSE; } +#ifndef HAVE_PHP_SESSION +#error HAVE_PHP_SESSION not defined +#endif + /* Test if session module contains custom sesson ID patch */ #ifdef PHP_SESSION_API #if (PHP_SESSION_API >= 20020330) @@ -60,7 +76,6 @@ /* This sets the PHP API version used in the file. */ /* If this module does not compile on the version of PHP you are using, look for */ /* this value in Zend/zend_modules.h, and set appropriately */ - #if (ZEND_MODULE_API_NO <= 20001222) #define PHP_4_0 #define TSRMLS_CC @@ -183,6 +198,7 @@ PHP_RINIT_FUNCTION(msession) PHP_RSHUTDOWN_FUNCTION(msession) { +#ifndef PERSISTENT_CONN if(s_conn) { CloseReqConn(s_conn); @@ -194,6 +210,7 @@ PHP_RSHUTDOWN_FUNCTION(msession) FreeRequestBuffer(s_reqb); s_reqb=NULL; } +#endif return SUCCESS; } @@ -204,32 +221,87 @@ PHP_MINFO_FUNCTION(msession) php_info_print_table_end(); } +/* The PHP Version of DoRequest */ +/* Manages connections that have been disconnected */ +int PHPDoRequest(void **pconn, REQB **ppreq) +{ + void *conn = *pconn; + int stat = (*ppreq)->req.stat; + int param = (*ppreq)->req.param; + + int result = DoRequest(conn, ppreq); + + // Server closed the connection! + if((*ppreq)->req.stat == REQ_ERR && (result == REQE_BADCONN || result == REQE_NOSEND)) + { + // In the case of a bad socket, this should be + // all that changs! + (*ppreq)->req.stat = stat; + (*ppreq)->req.param = param; + ELOG("Connection was closed by server"); + if(ReopenReqConn(conn)) + result = DoRequest(*pconn, ppreq); + } +#ifdef ERR_DEBUG + if((*ppreq)->req.stat == REQ_ERR && (result == REQE_BADCONN || result == REQE_NOSEND)) + ELOG("Socket reports closed"); +#endif + return result; +} + int PHPMsessionConnect(const char *szhost, int nport) { + int fNewHost=FALSE; TSRMLS_FETCH(); + if(!s_reqb) s_reqb = AllocateRequestBuffer(2048); if(!s_reqb) // no buffer, it won't work! return 0; - - if(s_conn) - { - CloseReqConn(s_conn); - php_log_err("Call to connect with non-null s_conn" TSRMLS_CC); - } + if(strcmp(s_szhost, szhost)) { if(s_szhost != s_szdefhost) free(s_szhost); s_szhost = strdup(szhost); + fNewHost = TRUE; } - if(nport) + if(nport && nport != s_port) + { + fNewHost = TRUE; s_port = nport; + } + +#ifndef PERSISTENT_CONN + ELOG("PHPMsessionConnect:old"); + if(s_conn) + { + CloseReqConn(s_conn); + php_log_err("Call to connect with non-null s_conn" TSRMLS_CC); + } s_conn = OpenReqConn(s_szhost, s_port); +#else + ELOG("PHPMsessionConnect:new"); + if(s_conn && fNewHost) + { + ELOG("Closing old connection, opening new"); + CloseReqConn(s_conn); + s_conn = NULL; + } + if(!s_conn) + s_conn = OpenReqConn(s_szhost, s_port); +#ifdef ERR_DEBUG + else + { + ELOG("Reusing old connection"); + } +#endif +#endif + #ifdef ERR_DEBUG { @@ -244,6 +316,7 @@ int PHPMsessionConnect(const char *szhost, int nport) void PHPMsessionDisconnect() { +#ifndef PERSISTENT_CONN if(s_conn) { CloseReqConn(s_conn); @@ -254,6 +327,7 @@ void PHPMsessionDisconnect() FreeRequestBuffer(s_reqb); s_reqb = NULL; } +#endif } char *PHPMsessionGetData(const char *session) @@ -263,7 +337,7 @@ char *PHPMsessionGetData(const char *session) IFCONNECT_BEGIN FormatRequest(&s_reqb, REQ_DATAGET, session,"","",0); - DoRequest(s_conn, &s_reqb); + PHPDoRequest(&s_conn, &s_reqb); if(s_reqb->req.stat==REQ_OK) ret = safe_estrdup(s_reqb->req.datum); @@ -273,12 +347,11 @@ char *PHPMsessionGetData(const char *session) } int PHPMsessionSetData(const char *session, const char *data) { - IFCONNECT_BEGIN int ret=0; FormatRequest(&s_reqb, REQ_DATASET, session,"",data,0); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); ret = (s_reqb->req.stat==REQ_OK); if(s_reqb->req.stat!=REQ_OK) php_error(E_WARNING, s_szErrFmt, ReqbErr(s_reqb)); @@ -287,14 +360,13 @@ int PHPMsessionSetData(const char *session, const char *data) IFCONNECT_ENDVAL(0) } - int PHPMsessionDestroy(const char *session) { IFCONNECT_BEGIN int ret=0; FormatRequest(&s_reqb, REQ_DROP, session, "","",0); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); ret = (s_reqb->req.stat==REQ_OK); if(s_reqb->req.stat!=REQ_OK) php_error(E_WARNING, s_szErrFmt, ReqbErr(s_reqb)); @@ -353,7 +425,7 @@ PHP_FUNCTION(msession_count) int count; FormatRequest(&s_reqb, REQ_COUNT, "", "","",0); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); count = (s_reqb->req.stat == REQ_OK) ? s_reqb->req.param : 0; @@ -379,7 +451,7 @@ PHP_FUNCTION(msession_create) convert_to_string_ex(session); szsession = Z_STRVAL_PP(session); FormatRequest(&s_reqb, REQ_CREATE, szsession, "","",0); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat==REQ_OK) { RETURN_TRUE; @@ -426,7 +498,7 @@ PHP_FUNCTION(msession_lock) convert_to_string_ex(session); szsession = Z_STRVAL_PP(session); FormatRequest(&s_reqb, REQ_SLOCK, szsession, "","",0); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat==REQ_OK) { @@ -496,7 +568,7 @@ PHP_FUNCTION(msession_ctl) } } FormatRequest(&s_reqb, REQ_CTL, szsession, "","",fn); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat==REQ_OK) { @@ -534,7 +606,7 @@ PHP_FUNCTION(msession_unlock) convert_to_long_ex(key); lkey = Z_LVAL_PP(key); FormatRequest(&s_reqb, REQ_SUNLOCK, szsession, "","",lkey); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat==REQ_OK) { @@ -575,7 +647,7 @@ PHP_FUNCTION(msession_set) szvalue = Z_STRVAL_PP(value); FormatRequest(&s_reqb, REQ_SETVAL, szsession, szname, szvalue, 0); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat==REQ_OK) { @@ -614,7 +686,7 @@ PHP_FUNCTION(msession_get) szvalue = Z_STRVAL_PP(value); FormatRequest(&s_reqb, REQ_GETVAL, szsession, szname, szvalue,0); - DoRequest(s_conn, &s_reqb); + PHPDoRequest(&s_conn, &s_reqb); if(s_reqb->req.stat==REQ_OK) { @@ -647,7 +719,7 @@ PHP_FUNCTION(msession_uniq) val = Z_LVAL_PP(param); FormatRequest(&s_reqb, REQ_UNIQ,"", "", "",val); - DoRequest(s_conn, &s_reqb); + PHPDoRequest(&s_conn, &s_reqb); if(s_reqb->req.stat==REQ_OK) { @@ -680,7 +752,7 @@ PHP_FUNCTION(msession_randstr) val = Z_LVAL_PP(param); FormatRequest(&s_reqb, REQ_RANDSTR,"", "", "",val); - DoRequest(s_conn, &s_reqb); + PHPDoRequest(&s_conn, &s_reqb); if(s_reqb->req.stat==REQ_OK) { @@ -717,7 +789,7 @@ PHP_FUNCTION(msession_find) szvalue = Z_STRVAL_PP(value); FormatRequest(&s_reqb, REQ_FIND, "", szname, szvalue,0); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat==REQ_OK && s_reqb->req.param) { @@ -748,7 +820,7 @@ PHP_FUNCTION(msession_list) { IFCONNECT_BEGIN FormatRequest(&s_reqb, REQ_LIST, "", "", "",0); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat==REQ_OK && s_reqb->req.param) { @@ -789,7 +861,7 @@ PHP_FUNCTION(msession_get_array) convert_to_string_ex(session); szsession = Z_STRVAL_PP(session); FormatRequest(&s_reqb, REQ_GETALL, szsession, "", "",0); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); array_init(return_value); @@ -902,7 +974,7 @@ PHP_FUNCTION(msession_set_array) ELOG("FormatMulti"); FormatRequestMulti(&s_reqb, REQ_SETVAL, Z_STRVAL_PP(session), countpair, pairs,0); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat != REQ_OK) php_error(E_WARNING, s_szErrFmt, ReqbErr(s_reqb)); @@ -923,7 +995,7 @@ PHP_FUNCTION(msession_listvar) } convert_to_string_ex(name); FormatRequest(&s_reqb, REQ_LISTVAR, "", Z_STRVAL_PP(name), "",0); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); array_init(return_value); @@ -985,7 +1057,7 @@ PHP_FUNCTION(msession_timeout) } convert_to_string_ex(session); FormatRequest(&s_reqb, REQ_TIMEOUT, Z_STRVAL_PP(session), "","",timeout); - DoRequest(s_conn,&s_reqb); + PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat == REQ_OK) { @@ -1017,7 +1089,7 @@ PHP_FUNCTION(msession_inc) convert_to_string_ex(name); FormatRequest(&s_reqb, REQ_INC, Z_STRVAL_PP(session), Z_STRVAL_PP(name),0,0); - DoRequest(s_conn, &s_reqb); + PHPDoRequest(&s_conn, &s_reqb); if(s_reqb->req.stat==REQ_OK) { @@ -1122,7 +1194,7 @@ PHP_FUNCTION(msession_plugin) ret = atoi(Z_STRVAL_PP(val)); FormatRequest(&s_reqb, REQ_PLUGIN, Z_STRVAL_PP(session), Z_STRVAL_PP(val), param ? Z_STRVAL_PP(param) : "",ret); - DoRequest(s_conn, &s_reqb); + PHPDoRequest(&s_conn, &s_reqb); if(s_reqb->req.stat==REQ_OK && s_reqb->req.len) { @@ -1172,7 +1244,7 @@ PHP_FUNCTION(msession_call) } FormatRequestStrings(&s_reqb, REQ_CALL, NULL , n, strings); - DoRequest(s_conn, &s_reqb); + PHPDoRequest(&s_conn, &s_reqb); if(s_reqb->req.stat==REQ_OK && s_reqb->req.len) { @@ -1192,9 +1264,28 @@ PHP_FUNCTION(msession_call) PS_OPEN_FUNC(msession) { + int port; + int len = strlen(save_path)+1; + char * path = alloca(len); + char * szport; + + strcpy(path, save_path); + + szport = strchr(path, ':'); + + if(szport) + { + *szport++=0; + port = atoi(szport); + } + else + { + port = s_port; + } + ELOG( "ps_open_msession"); PS_SET_MOD_DATA((void *)1); // session.c needs a non-zero here! - return PHPMsessionConnect(save_path, 8086) ? SUCCESS : FAILURE; + return PHPMsessionConnect(path, port) ? SUCCESS : FAILURE; } PS_CLOSE_FUNC(msession) @@ -1246,7 +1337,7 @@ PS_CREATE_SID_FUNC(msession) { ELOG("Should create a new session"); FormatRequest(&s_reqb, REQ_UNIQ,"", "", "",SID_LEN); - DoRequest(s_conn, &s_reqb); + PHPDoRequest(&s_conn, &s_reqb); if(s_reqb->req.stat==REQ_OK) { diff --git a/ext/msession/reqclient.h b/ext/msession/reqclient.h index f8b2695d1e..3384b3d6c7 100644 --- a/ext/msession/reqclient.h +++ b/ext/msession/reqclient.h @@ -58,9 +58,6 @@ enum REQ_TYPES REQ_SERIALIZE, REQ_LAST, REQ_INTERNAL_BEGIN=1023, - REQ_POPEN, - REQ_PCLOSE, - REQ_LOADDLL, REQ_INTERNALLAST, }; enum REQ_ERRORS @@ -83,6 +80,10 @@ enum REQ_ERRORS REQE_UNKNOWN }; +#define REQ_POPEN 1024 +#define REQ_PCLOSE 1025 +#define REQ_PING 1026 + typedef struct _requestPacket { int version; @@ -136,6 +137,8 @@ int FormatRequestStrings(REQB **ppreq, int stat, char *session, int n, char **st int DoSingleRequest(char *hostname, int port, REQB **preq); void *OpenReqConn(char *hostname, int port); void CloseReqConn(void *conn); +void DeleteReqConn(void *conn); +unsigned char ReopenReqConn(void *conn); int DoRequest(void *conn, REQB **preq); char *ReqbErr(REQB *reqb);