Normalize Redis callback prototypes and stop typecasting. (#1935)

This commit is contained in:
Michael Grunder
2021-02-25 10:03:53 -08:00
committed by GitHub
parent 1f2a7ef6b5
commit e61ee1da45
7 changed files with 111 additions and 80 deletions

View File

@@ -139,7 +139,7 @@ typedef enum {
#define REDIS_SAVE_CALLBACK(callback, closure_context) do { \
fold_item *fi = malloc(sizeof(fold_item)); \
fi->fun = (void *)callback; \
fi->fun = callback; \
fi->ctx = closure_context; \
fi->next = NULL; \
if (redis_sock->current) { \
@@ -194,7 +194,7 @@ typedef enum {
REDIS_PROCESS_RESPONSE_CLOSURE(resp_func, ctx) \
}
/* Process a command but with a specific command building function
/* Process a command but with a specific command building function
* and keyword which is passed to us*/
#define REDIS_PROCESS_KW_CMD(kw, cmdfunc, resp_func) \
RedisSock *redis_sock; char *cmd; int cmd_len; void *ctx=NULL; \
@@ -255,12 +255,6 @@ typedef enum {
#endif
#endif
typedef struct fold_item {
zval * (*fun)(INTERNAL_FUNCTION_PARAMETERS, void *, ...);
void *ctx;
struct fold_item *next;
} fold_item;
/* {{{ struct RedisSock */
typedef struct {
php_stream *stream;
@@ -285,8 +279,8 @@ typedef struct {
zend_string *prefix;
short mode;
fold_item *head;
fold_item *current;
struct fold_item *head;
struct fold_item *current;
zend_string *pipeline_cmd;
@@ -301,6 +295,16 @@ typedef struct {
} RedisSock;
/* }}} */
/* Redis response handler function callback prototype */
typedef void (*ResultCallback)(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
typedef int (*FailableResultCallback)(INTERNAL_FUNCTION_PARAMETERS, RedisSock*, zval*, void*);
typedef struct fold_item {
FailableResultCallback fun;
void *ctx;
struct fold_item *next;
} fold_item;
typedef struct {
zend_llist list;
int nb_active;

104
library.c
View File

@@ -1013,7 +1013,8 @@ int redis_cmd_append_sstr_arrkey(smart_string *cmd, zend_string *kstr, zend_ulon
return redis_cmd_append_sstr(cmd, arg, len);
}
PHP_REDIS_API void redis_bulk_double_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API int
redis_bulk_double_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
char *response;
int response_len;
@@ -1021,32 +1022,36 @@ PHP_REDIS_API void redis_bulk_double_response(INTERNAL_FUNCTION_PARAMETERS, Redi
if ((response = redis_sock_read(redis_sock, &response_len)) == NULL) {
if (IS_ATOMIC(redis_sock)) {
RETURN_FALSE;
RETVAL_FALSE;
} else {
add_next_index_bool(z_tab, 0);
}
add_next_index_bool(z_tab, 0);
return;
return FAILURE;
}
ret = atof(response);
efree(response);
if (IS_ATOMIC(redis_sock)) {
RETURN_DOUBLE(ret);
RETVAL_DOUBLE(ret);
} else {
add_next_index_double(z_tab, ret);
}
return SUCCESS;
}
PHP_REDIS_API void redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API int redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
char *response;
int response_len;
long l;
if ((response = redis_sock_read(redis_sock, &response_len)) == NULL) {
if (IS_ATOMIC(redis_sock)) {
RETURN_FALSE;
RETVAL_FALSE;
} else {
add_next_index_bool(z_tab, 0);
}
add_next_index_bool(z_tab, 0);
return;
return FAILURE;
}
if (strncmp(response, "+string", 7) == 0) {
@@ -1067,20 +1072,23 @@ PHP_REDIS_API void redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *
efree(response);
if (IS_ATOMIC(redis_sock)) {
RETURN_LONG(l);
RETVAL_LONG(l);
} else {
add_next_index_long(z_tab, l);
}
return SUCCESS;
}
PHP_REDIS_API void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API int redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
char *response;
int response_len;
zval z_ret;
/* Read bulk response */
if ((response = redis_sock_read(redis_sock, &response_len)) == NULL) {
RETURN_FALSE;
RETVAL_FALSE;
return FAILURE;
}
/* Parse it into a zval array */
@@ -1095,6 +1103,8 @@ PHP_REDIS_API void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *
} else {
add_next_index_zval(z_tab, &z_ret);
}
return SUCCESS;
}
PHP_REDIS_API void
@@ -1151,14 +1161,16 @@ redis_parse_info_response(char *response, zval *z_ret)
* Specialized handling of the CLIENT LIST output so it comes out in a simple way for PHP userland code
* to handle.
*/
PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab) {
PHP_REDIS_API int
redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
char *resp;
int resp_len;
zval z_ret;
/* Make sure we can read the bulk response from Redis */
if ((resp = redis_sock_read(redis_sock, &resp_len)) == NULL) {
RETURN_FALSE;
RETVAL_FALSE;
return FAILURE;
}
/* Parse it out */
@@ -1173,6 +1185,8 @@ PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSo
} else {
add_next_index_zval(z_tab, &z_ret);
}
return SUCCESS;
}
PHP_REDIS_API void
@@ -1270,7 +1284,7 @@ redis_parse_client_list_response(char *response, zval *z_ret)
}
}
PHP_REDIS_API void
PHP_REDIS_API int
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
zval *z_tab, void *ctx,
SuccessCallback success_callback)
@@ -1289,36 +1303,38 @@ redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
success_callback(redis_sock);
}
if (IS_ATOMIC(redis_sock)) {
RETURN_BOOL(ret);
RETVAL_BOOL(ret);
} else {
add_next_index_bool(z_tab, ret);
}
return ret ? SUCCESS : FAILURE;
}
PHP_REDIS_API void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS,
PHP_REDIS_API int 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);
return redis_boolean_response_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock,
z_tab, ctx, NULL);
}
PHP_REDIS_API void redis_long_response(INTERNAL_FUNCTION_PARAMETERS,
RedisSock *redis_sock, zval * z_tab,
void *ctx)
PHP_REDIS_API int redis_long_response(INTERNAL_FUNCTION_PARAMETERS,
RedisSock *redis_sock, zval * z_tab,
void *ctx)
{
char *response;
int response_len;
if ((response = redis_sock_read(redis_sock, &response_len))
== NULL)
{
if ((response = redis_sock_read(redis_sock, &response_len)) == NULL) {
if (IS_ATOMIC(redis_sock)) {
RETURN_FALSE;
RETVAL_FALSE;
} else {
add_next_index_bool(z_tab, 0);
}
add_next_index_bool(z_tab, 0);
return;
return FAILURE;
}
if(response[0] == ':') {
@@ -1343,8 +1359,12 @@ PHP_REDIS_API void redis_long_response(INTERNAL_FUNCTION_PARAMETERS,
} else {
add_next_index_null(z_tab);
}
efree(response);
return FAILURE;
}
efree(response);
return SUCCESS;
}
/* Helper method to convert [key, value, key, value] into [key => value,
@@ -1925,7 +1945,7 @@ PHP_REDIS_API int redis_mbulk_reply_zipped_vals(INTERNAL_FUNCTION_PARAMETERS, Re
z_tab, UNSERIALIZE_VALS, SCORE_DECODE_NONE);
}
PHP_REDIS_API void
PHP_REDIS_API int
redis_1_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
{
char *response;
@@ -1938,13 +1958,15 @@ redis_1_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_ta
}
if (IS_ATOMIC(redis_sock)) {
RETURN_BOOL(ret);
RETVAL_BOOL(ret);
} else {
add_next_index_bool(z_tab, ret);
}
return ret ? SUCCESS : FAILURE;
}
PHP_REDIS_API void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API int redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
char *response;
int response_len;
@@ -1953,10 +1975,11 @@ PHP_REDIS_API void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock
== NULL)
{
if (IS_ATOMIC(redis_sock)) {
RETURN_FALSE;
RETVAL_FALSE;
} else {
add_next_index_bool(z_tab, 0);
}
add_next_index_bool(z_tab, 0);
return;
return FAILURE;
}
if (IS_ATOMIC(redis_sock)) {
if (!redis_unpack(redis_sock, response, response_len, return_value)) {
@@ -1970,7 +1993,9 @@ PHP_REDIS_API void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock
add_next_index_stringl(z_tab, response, response_len);
}
}
efree(response);
return SUCCESS;
}
PHP_REDIS_API
@@ -1998,7 +2023,7 @@ void redis_single_line_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock
}
/* like string response, but never unserialized. */
PHP_REDIS_API void
PHP_REDIS_API int
redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
zval *z_tab, void *ctx)
{
@@ -2010,17 +2035,20 @@ redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
== NULL)
{
if (IS_ATOMIC(redis_sock)) {
RETURN_FALSE;
RETVAL_FALSE;
} else {
add_next_index_bool(z_tab, 0);
}
add_next_index_bool(z_tab, 0);
return;
return FAILURE;
}
if (IS_ATOMIC(redis_sock)) {
RETVAL_STRINGL(response, response_len);
} else {
add_next_index_stringl(z_tab, response, response_len);
}
efree(response);
return SUCCESS;
}
/* Response for DEBUG object which is a formatted single line reply */

View File

@@ -49,20 +49,20 @@ PHP_REDIS_API zend_string *redis_pool_spprintf(RedisSock *redis_sock, char *fmt,
PHP_REDIS_API char *redis_sock_read(RedisSock *redis_sock, int *buf_len);
PHP_REDIS_API int redis_sock_gets(RedisSock *redis_sock, char *buf, int buf_size, size_t* line_len);
PHP_REDIS_API void redis_1_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_long_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval* z_tab, void *ctx);
PHP_REDIS_API int redis_1_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_long_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval* z_tab, void *ctx);
typedef void (*SuccessCallback)(RedisSock *redis_sock);
PHP_REDIS_API void redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx, SuccessCallback success_callback);
PHP_REDIS_API void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_bulk_double_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx, SuccessCallback success_callback);
PHP_REDIS_API int redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_bulk_double_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_single_line_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
zval *z_tab, void *ctx);
PHP_REDIS_API void redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_parse_info_response(char *response, zval *z_ret);
PHP_REDIS_API void redis_parse_client_list_response(char *response, zval *z_ret);
PHP_REDIS_API void redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API RedisSock* redis_sock_create(char *host, int host_len, int port, double timeout, double read_timeout, int persistent, char *persistent_id, long retry_interval);
PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock);
PHP_REDIS_API int redis_sock_server_open(RedisSock *redis_sock);
@@ -149,7 +149,7 @@ PHP_REDIS_API int redis_read_multibulk_recursive(RedisSock *redis_sock, long lon
PHP_REDIS_API int redis_read_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_read_raw_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_read_variant_reply_strings(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab);
PHP_REDIS_API int redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
/* Helper methods to get configuration values from a HashTable. */

View File

@@ -276,11 +276,6 @@ PHP_MINIT_FUNCTION(redis);
PHP_MSHUTDOWN_FUNCTION(redis);
PHP_MINFO_FUNCTION(redis);
/* Redis response handler function callback prototype */
typedef void (*ResultCallback)(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
typedef int (*FailableResultCallback)(INTERNAL_FUNCTION_PARAMETERS, RedisSock*, zval*, void*);
PHP_REDIS_API int redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent);
PHP_REDIS_API int redis_response_enqueued(RedisSock *redis_sock);

23
redis.c
View File

@@ -1088,10 +1088,10 @@ redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
}
/* {{{ proto long Redis::bitop(string op, string key, ...) */
PHP_METHOD(Redis, bitop)
{
PHP_METHOD(Redis, bitop) {
REDIS_PROCESS_CMD(bitop, redis_long_response);
}
/* }}} */
/* {{{ proto long Redis::bitcount(string key, [int start], [int end])
@@ -1227,8 +1227,7 @@ PHP_METHOD(Redis, incrBy){
/* {{{ proto float Redis::incrByFloat(string key, float value)
*/
PHP_METHOD(Redis, incrByFloat) {
REDIS_PROCESS_KW_CMD("INCRBYFLOAT", redis_key_dbl_cmd,
redis_bulk_double_response);
REDIS_PROCESS_KW_CMD("INCRBYFLOAT", redis_key_dbl_cmd, redis_bulk_double_response);
}
/* }}} */
@@ -1324,10 +1323,10 @@ PHP_REDIS_API void redis_set_watch(RedisSock *redis_sock)
redis_sock->watching = 1;
}
PHP_REDIS_API void redis_watch_response(INTERNAL_FUNCTION_PARAMETERS,
PHP_REDIS_API int redis_watch_response(INTERNAL_FUNCTION_PARAMETERS,
RedisSock *redis_sock, zval *z_tab, void *ctx)
{
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock,
return redis_boolean_response_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock,
z_tab, ctx, redis_set_watch);
}
@@ -1344,12 +1343,12 @@ PHP_REDIS_API void redis_clear_watch(RedisSock *redis_sock)
redis_sock->watching = 0;
}
PHP_REDIS_API void redis_unwatch_response(INTERNAL_FUNCTION_PARAMETERS,
PHP_REDIS_API int 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);
return redis_boolean_response_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock,
z_tab, ctx, redis_clear_watch);
}
/* {{{ proto boolean Redis::unwatch()
@@ -2047,7 +2046,7 @@ PHP_METHOD(Redis, move) {
/* }}} */
static
void generic_mset(INTERNAL_FUNCTION_PARAMETERS, char *kw, ResultCallback fun)
void generic_mset(INTERNAL_FUNCTION_PARAMETERS, char *kw, FailableResultCallback fun)
{
RedisSock *redis_sock;
smart_string cmd = {0};
@@ -2093,6 +2092,7 @@ void generic_mset(INTERNAL_FUNCTION_PARAMETERS, char *kw, ResultCallback fun)
if (IS_ATOMIC(redis_sock)) {
fun(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
}
REDIS_PROCESS_RESPONSE(fun);
}
@@ -3475,8 +3475,7 @@ PHP_METHOD(Redis, client) {
/* We handle CLIENT LIST with a custom response function */
if(!strncasecmp(opt, "list", 4)) {
if (IS_ATOMIC(redis_sock)) {
redis_client_list_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU,redis_sock,
NULL);
redis_client_list_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU,redis_sock, NULL, NULL);
}
REDIS_PROCESS_RESPONSE(redis_client_list_reply);
} else {

View File

@@ -30,7 +30,7 @@ create_sentinel_object(zend_class_entry *ce)
return &obj->std;
}
PHP_REDIS_API void
PHP_REDIS_API int
sentinel_mbulk_reply_zipped_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
{
char inbuf[4096];
@@ -40,14 +40,17 @@ sentinel_mbulk_reply_zipped_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis
/* Throws exception on failure */
if (redis_sock_gets(redis_sock, inbuf, sizeof(inbuf) - 1, &len) < 0) {
RETURN_FALSE;
RETVAL_FALSE;
return FAILURE;
}
if (*inbuf != TYPE_MULTIBULK) {
if (*inbuf == TYPE_ERR) {
redis_sock_set_err(redis_sock, inbuf + 1, len - 1);
}
RETURN_FALSE;
RETVAL_FALSE;
return FAILURE;
}
array_init(&z_ret);
nelem = atoi(inbuf + 1);
@@ -57,5 +60,7 @@ sentinel_mbulk_reply_zipped_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis
redis_mbulk_reply_zipped_raw(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, ctx);
add_next_index_zval(&z_ret, return_value);
}
RETURN_ZVAL(&z_ret, 0, 1);
RETVAL_ZVAL(&z_ret, 0, 1);
return SUCCESS;
}

View File

@@ -8,6 +8,6 @@ typedef redis_object redis_sentinel_object;
zend_object *create_sentinel_object(zend_class_entry *ce);
PHP_REDIS_API void sentinel_mbulk_reply_zipped_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int sentinel_mbulk_reply_zipped_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
#endif /* REDIS_SENTINEL_LIBRARY_H */