Skip to content

Commit 9938771

Browse files
committed
Merge branch 'master' of https://github.com/imvu/phpredis into imvu-master
2 parents 1a1a81b + 39df0b7 commit 9938771

File tree

5 files changed

+63
-13
lines changed

5 files changed

+63
-13
lines changed

common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ typedef struct {
150150
int failed;
151151
int status;
152152
int persistent;
153+
int watching;
153154
char *persistent_id;
154155

155156
int serializer;

library.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,25 @@ PHPAPI void redis_stream_close(RedisSock *redis_sock TSRMLS_DC) {
3131

3232
PHPAPI int redis_check_eof(RedisSock *redis_sock TSRMLS_DC)
3333
{
34-
35-
int eof = redis_sock->stream == NULL ? 1 : php_stream_eof(redis_sock->stream);
34+
int eof = php_stream_eof(redis_sock->stream);
3635
int count = 0;
3736
while(eof) {
38-
if(count++ == 10) { /* too many failures */
37+
if((MULTI == redis_sock->mode) || redis_sock->watching || count++ == 10) { /* too many failures */
3938
if(redis_sock->stream) { /* close stream if still here */
40-
redis_stream_close(redis_sock TSRMLS_CC);
39+
php_stream_close(redis_sock->stream);
4140
redis_sock->stream = NULL;
4241
redis_sock->mode = ATOMIC;
4342
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
43+
redis_sock->watching = 0;
4444
}
4545
zend_throw_exception(redis_exception_ce, "Connection lost", 0 TSRMLS_CC);
4646
return -1;
4747
}
4848
if(redis_sock->stream) { /* close existing stream before reconnecting */
49-
redis_stream_close(redis_sock TSRMLS_CC);
49+
php_stream_close(redis_sock->stream);
5050
redis_sock->stream = NULL;
5151
redis_sock->mode = ATOMIC;
52+
redis_sock->watching = 0;
5253
}
5354
redis_sock_connect(redis_sock TSRMLS_CC); /* reconnect */
5455
if(redis_sock->stream) { /* check for EOF again. */
@@ -72,6 +73,7 @@ PHPAPI zval *redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS,
7273
redis_sock->stream = NULL;
7374
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
7475
redis_sock->mode = ATOMIC;
76+
redis_sock->watching = 0;
7577
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
7678
return NULL;
7779
}
@@ -146,6 +148,7 @@ PHPAPI char *redis_sock_read(RedisSock *redis_sock, int *buf_len TSRMLS_DC)
146148
redis_sock->stream = NULL;
147149
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
148150
redis_sock->mode = ATOMIC;
151+
redis_sock->watching = 0;
149152
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
150153
return NULL;
151154
}
@@ -478,7 +481,7 @@ PHPAPI void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_s
478481
}
479482
}
480483

481-
PHPAPI void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
484+
PHPAPI void redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx, SuccessCallback success_callback) {
482485

483486
char *response;
484487
int response_len;
@@ -496,19 +499,29 @@ PHPAPI void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redi
496499

497500
IF_MULTI_OR_PIPELINE() {
498501
if (ret == '+') {
502+
if (success_callback != NULL) {
503+
success_callback(redis_sock);
504+
}
499505
add_next_index_bool(z_tab, 1);
500506
} else {
501507
add_next_index_bool(z_tab, 0);
502508
}
503509
} else {
504510
if (ret == '+') {
511+
if (success_callback != NULL) {
512+
success_callback(redis_sock);
513+
}
505514
RETURN_TRUE;
506515
} else {
507516
RETURN_FALSE;
508517
}
509518
}
510519
}
511520

521+
PHPAPI void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
522+
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, ctx, NULL);
523+
}
524+
512525
PHPAPI void redis_long_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval * z_tab, void *ctx) {
513526

514527
char *response;
@@ -570,6 +583,7 @@ PHPAPI int redis_sock_read_multibulk_reply_zipped_with_flag(INTERNAL_FUNCTION_PA
570583
redis_sock->stream = NULL;
571584
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
572585
redis_sock->mode = ATOMIC;
586+
redis_sock->watching = 0;
573587
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
574588
return -1;
575589
}
@@ -701,6 +715,7 @@ PHPAPI RedisSock* redis_sock_create(char *host, int host_len, unsigned short por
701715
redis_sock->host = estrndup(host, host_len);
702716
redis_sock->stream = NULL;
703717
redis_sock->status = REDIS_SOCK_STATUS_DISCONNECTED;
718+
redis_sock->watching = 0;
704719

705720
redis_sock->persistent = persistent;
706721

@@ -841,6 +856,7 @@ PHPAPI int redis_sock_disconnect(RedisSock *redis_sock TSRMLS_DC)
841856
}
842857

843858
redis_sock->status = REDIS_SOCK_STATUS_DISCONNECTED;
859+
redis_sock->watching = 0;
844860
if(redis_sock->stream && !redis_sock->persistent) { /* still valid after the write? */
845861
php_stream_close(redis_sock->stream);
846862
}
@@ -893,6 +909,7 @@ PHPAPI int redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSo
893909
redis_sock->stream = NULL;
894910
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
895911
redis_sock->mode = ATOMIC;
912+
redis_sock->watching = 0;
896913
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
897914
return -1;
898915
}
@@ -934,6 +951,7 @@ PHPAPI int redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, Red
934951
redis_sock->stream = NULL;
935952
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
936953
redis_sock->mode = ATOMIC;
954+
redis_sock->watching = 0;
937955
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
938956
return -1;
939957
}
@@ -1007,6 +1025,7 @@ PHPAPI int redis_sock_read_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, R
10071025
redis_sock->stream = NULL;
10081026
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
10091027
redis_sock->mode = ATOMIC;
1028+
redis_sock->watching = 0;
10101029
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
10111030
return -1;
10121031
}

library.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ PHPAPI char * redis_sock_read(RedisSock *redis_sock, int *buf_len TSRMLS_DC);
77

88
PHPAPI void redis_1_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
99
PHPAPI void redis_long_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval* z_tab, void *ctx);
10+
typedef void (*SuccessCallback)(RedisSock *redis_sock);
11+
PHPAPI void redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx, SuccessCallback success_callback);
1012
PHPAPI void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
1113
PHPAPI void redis_bulk_double_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
1214
PHPAPI void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);

php_redis.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ PHPAPI void redis_atomic_increment(INTERNAL_FUNCTION_PARAMETERS, char *keyword,
176176
PHPAPI int generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int keyword_len,
177177
int min_argc, RedisSock **redis_sock, int has_timeout, int all_keys, int can_serialize);
178178
PHPAPI void generic_sort_cmd(INTERNAL_FUNCTION_PARAMETERS, char *sort, int use_alpha);
179+
typedef void (*ResultCallback)(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
180+
PHPAPI void generic_empty_cmd_impl(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ResultCallback result_callback);
179181
PHPAPI void generic_empty_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...);
180182
PHPAPI void generic_empty_long_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...);
181183

redis.c

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,16 @@ PHP_METHOD(Redis, delete)
11221122
}
11231123
/* }}} */
11241124

1125+
PHPAPI void redis_set_watch(RedisSock *redis_sock)
1126+
{
1127+
redis_sock->watching = 1;
1128+
}
1129+
1130+
PHPAPI void redis_watch_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
1131+
{
1132+
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, ctx, redis_set_watch);
1133+
}
1134+
11251135
/* {{{ proto boolean Redis::watch(string key1, string key2...)
11261136
*/
11271137
PHP_METHOD(Redis, watch)
@@ -1131,20 +1141,31 @@ PHP_METHOD(Redis, watch)
11311141
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
11321142
"WATCH", sizeof("WATCH") - 1,
11331143
1, &redis_sock, 0, 1, 1);
1144+
redis_sock->watching = 1;
11341145
IF_ATOMIC() {
1135-
redis_boolean_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
1146+
redis_watch_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
11361147
}
1137-
REDIS_PROCESS_RESPONSE(redis_boolean_response);
1148+
REDIS_PROCESS_RESPONSE(redis_watch_response);
11381149

11391150
}
11401151
/* }}} */
11411152

1153+
PHPAPI void redis_clear_watch(RedisSock *redis_sock)
1154+
{
1155+
redis_sock->watching = 0;
1156+
}
1157+
1158+
PHPAPI void redis_unwatch_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
1159+
{
1160+
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, ctx, redis_clear_watch);
1161+
}
1162+
11421163
/* {{{ proto boolean Redis::unwatch()
11431164
*/
11441165
PHP_METHOD(Redis, unwatch)
11451166
{
11461167
char cmd[] = "*1" _NL "$7" _NL "UNWATCH" _NL;
1147-
generic_empty_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, estrdup(cmd), sizeof(cmd)-1);
1168+
generic_empty_cmdi_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, estrdup(cmd), sizeof(cmd)-1, redis_unwatch_response);
11481169

11491170
}
11501171
/* }}} */
@@ -2777,8 +2798,7 @@ PHP_METHOD(Redis, lSet) {
27772798
}
27782799
/* }}} */
27792800

2780-
2781-
PHPAPI void generic_empty_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...) {
2801+
PHPAPI void generic_empty_cmd_impl(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ResultCallback result_callback) {
27822802
zval *object;
27832803
RedisSock *redis_sock;
27842804

@@ -2793,9 +2813,13 @@ PHPAPI void generic_empty_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_l
27932813

27942814
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
27952815
IF_ATOMIC() {
2796-
redis_boolean_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
2816+
result_callback(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
27972817
}
2798-
REDIS_PROCESS_RESPONSE(redis_boolean_response);
2818+
REDIS_PROCESS_RESPONSE(result_callback);
2819+
}
2820+
2821+
PHPAPI void generic_empty_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...) {
2822+
generic_empty_cmd_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, cmd, cmd_len, redis_boolean_response);
27992823
}
28002824

28012825
/* {{{ proto string Redis::save()
@@ -4748,10 +4772,12 @@ PHP_METHOD(Redis, exec)
47484772
zval_dtor(return_value);
47494773
free_reply_callbacks(object, redis_sock);
47504774
redis_sock->mode = ATOMIC;
4775+
redis_sock->watching = 0;
47514776
RETURN_FALSE;
47524777
}
47534778
free_reply_callbacks(object, redis_sock);
47544779
redis_sock->mode = ATOMIC;
4780+
redis_sock->watching = 0;
47554781
}
47564782

47574783
IF_PIPELINE() {

0 commit comments

Comments
 (0)