summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/msession/msession.c157
-rw-r--r--ext/msession/reqclient.h9
2 files changed, 130 insertions, 36 deletions
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);