Skip to content

Commit

Permalink
Use zend_string to store strings in RedisSock
Browse files Browse the repository at this point in the history
Following fields were changed: err, prefix, persistent_id, auth and host
  • Loading branch information
yatsukhnenko committed Aug 16, 2017
1 parent acc84cc commit 2bf7b2f
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 117 deletions.
14 changes: 5 additions & 9 deletions cluster_library.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,19 +489,16 @@ cluster_set_err(redisCluster *c, char *err, int err_len)
{
// Free our last error
if (c->err != NULL) {
efree(c->err);
zend_string_release(c->err);
c->err = NULL;
}
if (err != NULL && err_len > 0) {
c->err = zend_string_init(err, err_len, 0);
if (err_len >= sizeof("CLUSTERDOWN") - 1 &&
!memcmp(err, "CLUSTERDOWN", sizeof("CLUSTERDOWN") - 1)
) {
c->clusterdown = 1;
}
c->err = estrndup(err, err_len);
c->err_len = err_len;
} else {
c->err = NULL;
c->err_len = 0;
}
}

Expand Down Expand Up @@ -819,7 +816,6 @@ PHP_REDIS_API redisCluster *cluster_create(double timeout, double read_timeout,
c->failover = failover;
c->persistent = persistent;
c->err = NULL;
c->err_len = 0;

/* Set up our waitms based on timeout */
c->waitms = (long)(1000 * timeout);
Expand Down Expand Up @@ -849,7 +845,7 @@ PHP_REDIS_API void cluster_free(redisCluster *c) {
efree(c->nodes);

/* Free any error we've got */
if (c->err) efree(c->err);
if (c->err) zend_string_release(c->err);

/* Free structure itself */
efree(c);
Expand Down Expand Up @@ -1328,7 +1324,7 @@ PHP_REDIS_API short cluster_find_slot(redisCluster *c, const char *host,
for(i=0;i<REDIS_CLUSTER_SLOTS;i++) {
if(c->master[i] && c->master[i]->sock &&
c->master[i]->sock->port == port &&
!strcasecmp(c->master[i]->sock->host, host))
!strcasecmp(ZSTR_VAL(c->master[i]->sock->host), host))
{
return i;
}
Expand Down
19 changes: 10 additions & 9 deletions cluster_library.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
/* Compare redirection slot information with what we have */
#define CLUSTER_REDIR_CMP(c) \
(SLOT_SOCK(c,c->redir_slot)->port != c->redir_port || \
strlen(SLOT_SOCK(c,c->redir_slot)->host) != c->redir_host_len || \
memcmp(SLOT_SOCK(c,c->redir_slot)->host,c->redir_host,c->redir_host_len))
ZSTR_LEN(SLOT_SOCK(c,c->redir_slot)->host) != c->redir_host_len || \
memcmp(ZSTR_VAL(SLOT_SOCK(c,c->redir_slot)->host),c->redir_host,c->redir_host_len))

/* Lazy connect logic */
#define CLUSTER_LAZY_CONNECT(s) \
Expand All @@ -59,11 +59,13 @@
}

/* Clear out our "last error" */
#define CLUSTER_CLEAR_ERROR(c) \
if(c->err) efree(c->err); \
c->err = NULL; \
c->err_len = 0; \
c->clusterdown = 0;
#define CLUSTER_CLEAR_ERROR(c) do { \
if (c->err) { \
zend_string_release(c->err); \
c->err = NULL; \
} \
c->clusterdown = 0; \
} while (0)

/* Protected sending of data down the wire to a RedisSock->stream */
#define CLUSTER_SEND_PAYLOAD(sock, buf, len) \
Expand Down Expand Up @@ -216,8 +218,7 @@ typedef struct redisCluster {
short clusterdown;

/* The last ERROR we encountered */
char *err;
int err_len;
zend_string *err;

/* The slot our command is operating on, as well as it's socket */
unsigned short cmd_slot;
Expand Down
26 changes: 19 additions & 7 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ typedef struct {
#define ZSTR_VAL(s) (s)->val
#define ZSTR_LEN(s) (s)->len

static zend_always_inline zend_string *
zend_string_init(const char *str, size_t len, int persistent)
{
zend_string *zstr = emalloc(sizeof(zend_string) + len + 1);

ZSTR_VAL(zstr) = (char *)zstr + sizeof(zend_string);
memcpy(ZSTR_VAL(zstr), str, len);
ZSTR_VAL(zstr)[len] = '\0';
zstr->len = len;
zstr->gc = 0x01;
return zstr;
}

#define zend_string_release(s) do { \
if ((s) && (s)->gc) { \
if ((s)->gc & 0x10 && ZSTR_VAL(s)) efree(ZSTR_VAL(s)); \
Expand Down Expand Up @@ -619,23 +632,22 @@ typedef struct fold_item {
/* {{{ struct RedisSock */
typedef struct {
php_stream *stream;
char *host;
zend_string *host;
short port;
char *auth;
zend_string *auth;
double timeout;
double read_timeout;
long retry_interval;
int failed;
int status;
int persistent;
int watching;
char *persistent_id;
zend_string *persistent_id;

int serializer;
long dbNumber;

char *prefix;
int prefix_len;
zend_string *prefix;

short mode;
fold_item *head;
Expand All @@ -644,8 +656,8 @@ typedef struct {
char *pipeline_cmd;
size_t pipeline_len;

char *err;
int err_len;
zend_string *err;

zend_bool lazy_connect;

int scan;
Expand Down
65 changes: 31 additions & 34 deletions library.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ static int resend_auth(RedisSock *redis_sock TSRMLS_DC) {
int cmd_len, response_len;

cmd_len = redis_spprintf(redis_sock, NULL TSRMLS_CC, &cmd, "AUTH", "s",
redis_sock->auth, strlen(redis_sock->auth));
ZSTR_VAL(redis_sock->auth), ZSTR_LEN(redis_sock->auth));

if (redis_sock_write(redis_sock, cmd, cmd_len TSRMLS_CC) < 0) {
efree(cmd);
Expand Down Expand Up @@ -117,11 +117,11 @@ static void
redis_error_throw(RedisSock *redis_sock TSRMLS_DC)
{
if (redis_sock != NULL && redis_sock->err != NULL &&
memcmp(redis_sock->err, "ERR", sizeof("ERR") - 1) != 0 &&
memcmp(redis_sock->err, "NOSCRIPT", sizeof("NOSCRIPT") - 1) != 0 &&
memcmp(redis_sock->err, "WRONGTYPE", sizeof("WRONGTYPE") - 1) != 0
memcmp(ZSTR_VAL(redis_sock->err), "ERR", sizeof("ERR") - 1) != 0 &&
memcmp(ZSTR_VAL(redis_sock->err), "NOSCRIPT", sizeof("NOSCRIPT") - 1) != 0 &&
memcmp(ZSTR_VAL(redis_sock->err), "WRONGTYPE", sizeof("WRONGTYPE") - 1) != 0
) {
zend_throw_exception(redis_exception_ce, redis_sock->err, 0 TSRMLS_CC);
zend_throw_exception(redis_exception_ce, ZSTR_VAL(redis_sock->err), 0 TSRMLS_CC);
}
}

Expand Down Expand Up @@ -1367,7 +1367,7 @@ redis_sock_create(char *host, int host_len, unsigned short port,
RedisSock *redis_sock;

redis_sock = ecalloc(1, sizeof(RedisSock));
redis_sock->host = estrndup(host, host_len);
redis_sock->host = zend_string_init(host, host_len, 0);
redis_sock->stream = NULL;
redis_sock->status = REDIS_SOCK_STATUS_DISCONNECTED;
redis_sock->watching = 0;
Expand All @@ -1377,8 +1377,8 @@ redis_sock_create(char *host, int host_len, unsigned short port,
redis_sock->lazy_connect = lazy_connect;
redis_sock->persistent_id = NULL;

if(persistent_id) {
redis_sock->persistent_id = estrdup(persistent_id);
if (persistent_id) {
redis_sock->persistent_id = zend_string_init(persistent_id, strlen(persistent_id), 0);
}

redis_sock->port = port;
Expand All @@ -1394,7 +1394,6 @@ redis_sock_create(char *host, int host_len, unsigned short port,
redis_sock->pipeline_len = 0;

redis_sock->err = NULL;
redis_sock->err_len = 0;

redis_sock->scan = REDIS_SCAN_NORETRY;

Expand Down Expand Up @@ -1428,8 +1427,8 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
read_tv.tv_sec = (time_t)redis_sock->read_timeout;
read_tv.tv_usec = (int)((redis_sock->read_timeout-read_tv.tv_sec)*1000000);

if(redis_sock->host[0] == '/' && redis_sock->port < 1) {
host_len = snprintf(host, sizeof(host), "unix://%s", redis_sock->host);
if (ZSTR_VAL(redis_sock->host)[0] == '/' && redis_sock->port < 1) {
host_len = snprintf(host, sizeof(host), "unix://%s", ZSTR_VAL(redis_sock->host));
usocket = 1;
} else {
if(redis_sock->port == 0)
Expand All @@ -1438,17 +1437,17 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
#ifdef HAVE_IPV6
/* If we've got IPv6 and find a colon in our address, convert to proper
* IPv6 [host]:port format */
if (strchr(redis_sock->host, ':') != NULL) {
if (strchr(ZSTR_VAL(redis_sock->host), ':') != NULL) {
fmtstr = "[%s]:%d";
}
#endif
host_len = snprintf(host, sizeof(host), fmtstr, redis_sock->host, redis_sock->port);
host_len = snprintf(host, sizeof(host), fmtstr, ZSTR_VAL(redis_sock->host), redis_sock->port);
}

if (redis_sock->persistent) {
if (redis_sock->persistent_id) {
spprintf(&persistent_id, 0, "phpredis:%s:%s", host,
redis_sock->persistent_id);
ZSTR_VAL(redis_sock->persistent_id));
} else {
spprintf(&persistent_id, 0, "phpredis:%s:%f", host,
redis_sock->timeout);
Expand Down Expand Up @@ -1541,17 +1540,13 @@ redis_sock_set_err(RedisSock *redis_sock, const char *msg, int msg_len)
{
// Free our last error
if (redis_sock->err != NULL) {
efree(redis_sock->err);
zend_string_release(redis_sock->err);
redis_sock->err = NULL;
}

if (msg != NULL && msg_len > 0) {
// Copy in our new error message
redis_sock->err = estrndup(msg, msg_len);
redis_sock->err_len = msg_len;
} else {
// Set to null, with zero length
redis_sock->err = NULL;
redis_sock->err_len = 0;
redis_sock->err = zend_string_init(msg, msg_len, 0);
}
}

Expand Down Expand Up @@ -1759,22 +1754,24 @@ redis_sock_write(RedisSock *redis_sock, char *cmd, size_t sz TSRMLS_DC)
*/
PHP_REDIS_API void redis_free_socket(RedisSock *redis_sock)
{
if(redis_sock->prefix) {
efree(redis_sock->prefix);
if (redis_sock->prefix) {
zend_string_release(redis_sock->prefix);
}
if (redis_sock->pipeline_cmd) {
efree(redis_sock->pipeline_cmd);
}
if(redis_sock->err) {
efree(redis_sock->err);
if (redis_sock->err) {
zend_string_release(redis_sock->err);
}
if (redis_sock->auth) {
zend_string_release(redis_sock->auth);
}
if(redis_sock->auth) {
efree(redis_sock->auth);
if (redis_sock->persistent_id) {
zend_string_release(redis_sock->persistent_id);
}
if(redis_sock->persistent_id) {
efree(redis_sock->persistent_id);
if (redis_sock->host) {
zend_string_release(redis_sock->host);
}
efree(redis_sock->host);
efree(redis_sock);
}

Expand Down Expand Up @@ -1931,14 +1928,14 @@ redis_key_prefix(RedisSock *redis_sock, char **key, strlen_t *key_len) {
int ret_len;
char *ret;

if(redis_sock->prefix == NULL || redis_sock->prefix_len == 0) {
if (redis_sock->prefix == NULL) {
return 0;
}

ret_len = redis_sock->prefix_len + *key_len;
ret_len = ZSTR_LEN(redis_sock->prefix) + *key_len;
ret = ecalloc(1 + ret_len, 1);
memcpy(ret, redis_sock->prefix, redis_sock->prefix_len);
memcpy(ret + redis_sock->prefix_len, *key, *key_len);
memcpy(ret, ZSTR_VAL(redis_sock->prefix), ZSTR_LEN(redis_sock->prefix));
memcpy(ret + ZSTR_LEN(redis_sock->prefix), *key, *key_len);

*key = ret;
*key_len = ret_len;
Expand Down
42 changes: 18 additions & 24 deletions redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ extern ps_module ps_mod_redis_cluster;

extern zend_class_entry *redis_array_ce;
extern zend_class_entry *redis_cluster_ce;
extern zend_class_entry *redis_cluster_exception_ce;

zend_class_entry *redis_ce;
zend_class_entry *redis_exception_ce;
extern zend_class_entry *redis_cluster_exception_ce;

extern zend_function_entry redis_array_functions[];
extern zend_function_entry redis_cluster_functions[];
Expand Down Expand Up @@ -3511,11 +3512,10 @@ PHP_METHOD(Redis, getLastError) {
}

/* Return our last error or NULL if we don't have one */
if(redis_sock->err != NULL && redis_sock->err_len > 0) {
RETURN_STRINGL(redis_sock->err, redis_sock->err_len);
} else {
RETURN_NULL();
}
if (redis_sock->err) {
RETURN_STRINGL(ZSTR_VAL(redis_sock->err), ZSTR_LEN(redis_sock->err));
}
RETURN_NULL();
}

/* {{{ proto Redis::clearLastError() */
Expand All @@ -3535,10 +3535,10 @@ PHP_METHOD(Redis, clearLastError) {
}

// Clear error message
if(redis_sock->err) {
efree(redis_sock->err);
if (redis_sock->err) {
zend_string_release(redis_sock->err);
redis_sock->err = NULL;
}
redis_sock->err = NULL;

RETURN_TRUE;
}
Expand Down Expand Up @@ -3599,7 +3599,7 @@ PHP_METHOD(Redis, getHost) {
RedisSock *redis_sock;

if((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU))) {
RETURN_STRING(redis_sock->host);
RETURN_STRINGL(ZSTR_VAL(redis_sock->host), ZSTR_LEN(redis_sock->host));
} else {
RETURN_FALSE;
}
Expand Down Expand Up @@ -3655,30 +3655,24 @@ PHP_METHOD(Redis, getReadTimeout) {
PHP_METHOD(Redis, getPersistentID) {
RedisSock *redis_sock;

if((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU))) {
if(redis_sock->persistent_id != NULL) {
RETURN_STRING(redis_sock->persistent_id);
} else {
RETURN_NULL();
}
} else {
if ((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU)) == NULL) {
RETURN_FALSE;
} else if (redis_sock->persistent_id == NULL) {
RETURN_NULL();
}
RETURN_STRINGL(ZSTR_VAL(redis_sock->persistent_id), ZSTR_LEN(redis_sock->persistent_id));
}

/* {{{ proto Redis::getAuth */
PHP_METHOD(Redis, getAuth) {
RedisSock *redis_sock;

if((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU))) {
if(redis_sock->auth != NULL) {
RETURN_STRING(redis_sock->auth);
} else {
RETURN_NULL();
}
} else {
if ((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU)) == NULL) {
RETURN_FALSE;
} else if (redis_sock->auth == NULL) {
RETURN_NULL();
}
RETURN_STRINGL(ZSTR_VAL(redis_sock->auth), ZSTR_LEN(redis_sock->auth));
}

/*
Expand Down
Loading

0 comments on commit 2bf7b2f

Please sign in to comment.