mirror of
https://github.com/phpredis/phpredis.git
synced 2026-06-19 07:35:31 +00:00
Merge branch 'master' of https://github.com/imvu/phpredis into imvu-master
This commit is contained in:
@@ -150,6 +150,7 @@ typedef struct {
|
||||
int failed;
|
||||
int status;
|
||||
int persistent;
|
||||
int watching;
|
||||
char *persistent_id;
|
||||
|
||||
int serializer;
|
||||
|
||||
@@ -31,24 +31,25 @@ PHPAPI void redis_stream_close(RedisSock *redis_sock TSRMLS_DC) {
|
||||
|
||||
PHPAPI int redis_check_eof(RedisSock *redis_sock TSRMLS_DC)
|
||||
{
|
||||
|
||||
int eof = redis_sock->stream == NULL ? 1 : php_stream_eof(redis_sock->stream);
|
||||
int eof = php_stream_eof(redis_sock->stream);
|
||||
int count = 0;
|
||||
while(eof) {
|
||||
if(count++ == 10) { /* too many failures */
|
||||
if((MULTI == redis_sock->mode) || redis_sock->watching || count++ == 10) { /* too many failures */
|
||||
if(redis_sock->stream) { /* close stream if still here */
|
||||
redis_stream_close(redis_sock TSRMLS_CC);
|
||||
php_stream_close(redis_sock->stream);
|
||||
redis_sock->stream = NULL;
|
||||
redis_sock->mode = ATOMIC;
|
||||
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
|
||||
redis_sock->watching = 0;
|
||||
}
|
||||
zend_throw_exception(redis_exception_ce, "Connection lost", 0 TSRMLS_CC);
|
||||
return -1;
|
||||
}
|
||||
if(redis_sock->stream) { /* close existing stream before reconnecting */
|
||||
redis_stream_close(redis_sock TSRMLS_CC);
|
||||
php_stream_close(redis_sock->stream);
|
||||
redis_sock->stream = NULL;
|
||||
redis_sock->mode = ATOMIC;
|
||||
redis_sock->watching = 0;
|
||||
}
|
||||
redis_sock_connect(redis_sock TSRMLS_CC); /* reconnect */
|
||||
if(redis_sock->stream) { /* check for EOF again. */
|
||||
@@ -72,6 +73,7 @@ PHPAPI zval *redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS,
|
||||
redis_sock->stream = NULL;
|
||||
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
|
||||
redis_sock->mode = ATOMIC;
|
||||
redis_sock->watching = 0;
|
||||
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
|
||||
return NULL;
|
||||
}
|
||||
@@ -146,6 +148,7 @@ PHPAPI char *redis_sock_read(RedisSock *redis_sock, int *buf_len TSRMLS_DC)
|
||||
redis_sock->stream = NULL;
|
||||
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
|
||||
redis_sock->mode = ATOMIC;
|
||||
redis_sock->watching = 0;
|
||||
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
|
||||
return NULL;
|
||||
}
|
||||
@@ -478,7 +481,7 @@ PHPAPI void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_s
|
||||
}
|
||||
}
|
||||
|
||||
PHPAPI void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
|
||||
PHPAPI void redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx, SuccessCallback success_callback) {
|
||||
|
||||
char *response;
|
||||
int response_len;
|
||||
@@ -496,12 +499,18 @@ PHPAPI void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redi
|
||||
|
||||
IF_MULTI_OR_PIPELINE() {
|
||||
if (ret == '+') {
|
||||
if (success_callback != NULL) {
|
||||
success_callback(redis_sock);
|
||||
}
|
||||
add_next_index_bool(z_tab, 1);
|
||||
} else {
|
||||
add_next_index_bool(z_tab, 0);
|
||||
}
|
||||
} else {
|
||||
if (ret == '+') {
|
||||
if (success_callback != NULL) {
|
||||
success_callback(redis_sock);
|
||||
}
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
@@ -509,6 +518,10 @@ PHPAPI void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redi
|
||||
}
|
||||
}
|
||||
|
||||
PHPAPI void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
|
||||
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, ctx, NULL);
|
||||
}
|
||||
|
||||
PHPAPI void redis_long_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval * z_tab, void *ctx) {
|
||||
|
||||
char *response;
|
||||
@@ -570,6 +583,7 @@ PHPAPI int redis_sock_read_multibulk_reply_zipped_with_flag(INTERNAL_FUNCTION_PA
|
||||
redis_sock->stream = NULL;
|
||||
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
|
||||
redis_sock->mode = ATOMIC;
|
||||
redis_sock->watching = 0;
|
||||
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
|
||||
return -1;
|
||||
}
|
||||
@@ -701,6 +715,7 @@ PHPAPI RedisSock* redis_sock_create(char *host, int host_len, unsigned short por
|
||||
redis_sock->host = estrndup(host, host_len);
|
||||
redis_sock->stream = NULL;
|
||||
redis_sock->status = REDIS_SOCK_STATUS_DISCONNECTED;
|
||||
redis_sock->watching = 0;
|
||||
|
||||
redis_sock->persistent = persistent;
|
||||
|
||||
@@ -841,6 +856,7 @@ PHPAPI int redis_sock_disconnect(RedisSock *redis_sock TSRMLS_DC)
|
||||
}
|
||||
|
||||
redis_sock->status = REDIS_SOCK_STATUS_DISCONNECTED;
|
||||
redis_sock->watching = 0;
|
||||
if(redis_sock->stream && !redis_sock->persistent) { /* still valid after the write? */
|
||||
php_stream_close(redis_sock->stream);
|
||||
}
|
||||
@@ -893,6 +909,7 @@ PHPAPI int redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSo
|
||||
redis_sock->stream = NULL;
|
||||
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
|
||||
redis_sock->mode = ATOMIC;
|
||||
redis_sock->watching = 0;
|
||||
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
|
||||
return -1;
|
||||
}
|
||||
@@ -934,6 +951,7 @@ PHPAPI int redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, Red
|
||||
redis_sock->stream = NULL;
|
||||
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
|
||||
redis_sock->mode = ATOMIC;
|
||||
redis_sock->watching = 0;
|
||||
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
|
||||
return -1;
|
||||
}
|
||||
@@ -1007,6 +1025,7 @@ PHPAPI int redis_sock_read_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, R
|
||||
redis_sock->stream = NULL;
|
||||
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
|
||||
redis_sock->mode = ATOMIC;
|
||||
redis_sock->watching = 0;
|
||||
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ PHPAPI char * redis_sock_read(RedisSock *redis_sock, int *buf_len TSRMLS_DC);
|
||||
|
||||
PHPAPI void redis_1_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
|
||||
PHPAPI void redis_long_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval* z_tab, void *ctx);
|
||||
typedef void (*SuccessCallback)(RedisSock *redis_sock);
|
||||
PHPAPI void redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx, SuccessCallback success_callback);
|
||||
PHPAPI void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
|
||||
PHPAPI void redis_bulk_double_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
|
||||
PHPAPI void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
|
||||
|
||||
@@ -176,6 +176,8 @@ PHPAPI void redis_atomic_increment(INTERNAL_FUNCTION_PARAMETERS, char *keyword,
|
||||
PHPAPI int generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int keyword_len,
|
||||
int min_argc, RedisSock **redis_sock, int has_timeout, int all_keys, int can_serialize);
|
||||
PHPAPI void generic_sort_cmd(INTERNAL_FUNCTION_PARAMETERS, char *sort, int use_alpha);
|
||||
typedef void (*ResultCallback)(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
|
||||
PHPAPI void generic_empty_cmd_impl(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ResultCallback result_callback);
|
||||
PHPAPI void generic_empty_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...);
|
||||
PHPAPI void generic_empty_long_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...);
|
||||
|
||||
|
||||
@@ -1122,6 +1122,16 @@ PHP_METHOD(Redis, delete)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHPAPI void redis_set_watch(RedisSock *redis_sock)
|
||||
{
|
||||
redis_sock->watching = 1;
|
||||
}
|
||||
|
||||
PHPAPI void redis_watch_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
|
||||
{
|
||||
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, ctx, redis_set_watch);
|
||||
}
|
||||
|
||||
/* {{{ proto boolean Redis::watch(string key1, string key2...)
|
||||
*/
|
||||
PHP_METHOD(Redis, watch)
|
||||
@@ -1131,20 +1141,31 @@ PHP_METHOD(Redis, watch)
|
||||
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
|
||||
"WATCH", sizeof("WATCH") - 1,
|
||||
1, &redis_sock, 0, 1, 1);
|
||||
redis_sock->watching = 1;
|
||||
IF_ATOMIC() {
|
||||
redis_boolean_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
|
||||
redis_watch_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
|
||||
}
|
||||
REDIS_PROCESS_RESPONSE(redis_boolean_response);
|
||||
REDIS_PROCESS_RESPONSE(redis_watch_response);
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHPAPI void redis_clear_watch(RedisSock *redis_sock)
|
||||
{
|
||||
redis_sock->watching = 0;
|
||||
}
|
||||
|
||||
PHPAPI void redis_unwatch_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
|
||||
{
|
||||
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, ctx, redis_clear_watch);
|
||||
}
|
||||
|
||||
/* {{{ proto boolean Redis::unwatch()
|
||||
*/
|
||||
PHP_METHOD(Redis, unwatch)
|
||||
{
|
||||
char cmd[] = "*1" _NL "$7" _NL "UNWATCH" _NL;
|
||||
generic_empty_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, estrdup(cmd), sizeof(cmd)-1);
|
||||
generic_empty_cmdi_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, estrdup(cmd), sizeof(cmd)-1, redis_unwatch_response);
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
@@ -2777,8 +2798,7 @@ PHP_METHOD(Redis, lSet) {
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
PHPAPI void generic_empty_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...) {
|
||||
PHPAPI void generic_empty_cmd_impl(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ResultCallback result_callback) {
|
||||
zval *object;
|
||||
RedisSock *redis_sock;
|
||||
|
||||
@@ -2793,9 +2813,13 @@ PHPAPI void generic_empty_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_l
|
||||
|
||||
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
|
||||
IF_ATOMIC() {
|
||||
redis_boolean_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
|
||||
result_callback(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
|
||||
}
|
||||
REDIS_PROCESS_RESPONSE(redis_boolean_response);
|
||||
REDIS_PROCESS_RESPONSE(result_callback);
|
||||
}
|
||||
|
||||
PHPAPI void generic_empty_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...) {
|
||||
generic_empty_cmd_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, cmd, cmd_len, redis_boolean_response);
|
||||
}
|
||||
|
||||
/* {{{ proto string Redis::save()
|
||||
@@ -4748,10 +4772,12 @@ PHP_METHOD(Redis, exec)
|
||||
zval_dtor(return_value);
|
||||
free_reply_callbacks(object, redis_sock);
|
||||
redis_sock->mode = ATOMIC;
|
||||
redis_sock->watching = 0;
|
||||
RETURN_FALSE;
|
||||
}
|
||||
free_reply_callbacks(object, redis_sock);
|
||||
redis_sock->mode = ATOMIC;
|
||||
redis_sock->watching = 0;
|
||||
}
|
||||
|
||||
IF_PIPELINE() {
|
||||
|
||||
Reference in New Issue
Block a user