Browse Source

Added persistent connections, and automattic reconnect on

lost connections. Requires Phoenix 1.0
experimental/new_apache_hooks
Mark L. Woodward 24 years ago
parent
commit
63ded04ef5
  1. 157
      ext/msession/msession.c
  2. 9
      ext/msession/reqclient.h

157
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)
{

9
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);

Loading…
Cancel
Save