Skip to content
This repository
Fetching contributors…

Cannot retrieve contributors at this time

file 186 lines (154 sloc) 4.942 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
#include "php.h"
#include "php_ini.h"

#ifndef REDIS_COMMON_H
#define REDIS_COMMON_H

#define redis_sock_name "Redis Socket Buffer"
#define REDIS_SOCK_STATUS_FAILED 0
#define REDIS_SOCK_STATUS_DISCONNECTED 1
#define REDIS_SOCK_STATUS_UNKNOWN 2
#define REDIS_SOCK_STATUS_CONNECTED 3

#define redis_multi_access_type_name "Redis Multi type access"

#define _NL "\r\n"

/* properties */
#define REDIS_NOT_FOUND 0
#define REDIS_STRING 1
#define REDIS_SET 2
#define REDIS_LIST 3
#define REDIS_ZSET 4
#define REDIS_HASH 5

/* reply types */
typedef enum _REDIS_REPLY_TYPE {
TYPE_LINE = '+',
TYPE_INT = ':',
TYPE_ERR = '-',
TYPE_BULK = '$',
TYPE_MULTIBULK = '*'
} REDIS_REPLY_TYPE;

/* options */
#define REDIS_OPT_SERIALIZER 1
#define REDIS_OPT_PREFIX 2

/* serializers */
#define REDIS_SERIALIZER_NONE 0
#define REDIS_SERIALIZER_PHP 1
#define REDIS_SERIALIZER_IGBINARY 2

#define IF_MULTI() if(redis_sock->mode == MULTI)
#define IF_MULTI_OR_ATOMIC() if(redis_sock->mode == MULTI || redis_sock->mode == ATOMIC)\

#define IF_MULTI_OR_PIPELINE() if(redis_sock->mode == MULTI || redis_sock->mode == PIPELINE)
#define IF_PIPELINE() if(redis_sock->mode == PIPELINE)
#define IF_NOT_MULTI() if(redis_sock->mode != MULTI)
#define IF_ATOMIC() if(redis_sock->mode == ATOMIC)
#define ELSE_IF_MULTI() else if(redis_sock->mode == MULTI) { \
if(redis_response_enqueued(redis_sock TSRMLS_CC) == 1) {\
RETURN_ZVAL(getThis(), 1, 0);\
} else {\
RETURN_FALSE;\
} \
}

#define ELSE_IF_PIPELINE() else IF_PIPELINE() { \
RETURN_ZVAL(getThis(), 1, 0);\
}


#define MULTI_RESPONSE(callback) IF_MULTI_OR_PIPELINE() { \
fold_item *f1, *current; \
f1 = malloc(sizeof(fold_item)); \
f1->fun = (void *)callback; \
f1->next = NULL; \
current = redis_sock->current;\
if(current) current->next = f1; \
redis_sock->current = f1; \
}

#define PIPELINE_ENQUEUE_COMMAND(cmd, cmd_len) request_item *tmp; \
struct request_item *current_request;\
tmp = malloc(sizeof(request_item));\
tmp->request_str = calloc(cmd_len, 1);\
memcpy(tmp->request_str, cmd, cmd_len);\
tmp->request_size = cmd_len;\
tmp->next = NULL;\
current_request = redis_sock->pipeline_current; \
if(current_request) {\
current_request->next = tmp;\
} \
redis_sock->pipeline_current = tmp; \
if(NULL == redis_sock->pipeline_head) { \
redis_sock->pipeline_head = redis_sock->pipeline_current;\
}

#define SOCKET_WRITE_COMMAND(redis_sock, cmd, cmd_len) if(redis_sock_write(redis_sock, cmd, cmd_len TSRMLS_CC) < 0) { \
efree(cmd); \
RETURN_FALSE; \
}

#define REDIS_SAVE_CALLBACK(callback, closure_context) IF_MULTI_OR_PIPELINE() { \
fold_item *f1, *current; \
f1 = malloc(sizeof(fold_item)); \
f1->fun = (void *)callback; \
f1->ctx = closure_context; \
f1->next = NULL; \
current = redis_sock->current;\
if(current) current->next = f1; \
redis_sock->current = f1; \
if(NULL == redis_sock->head) { \
redis_sock->head = redis_sock->current;\
}\
}

#define REDIS_ELSE_IF_MULTI(function, closure_context) \
else if(redis_sock->mode == MULTI) { \
if(redis_response_enqueued(redis_sock TSRMLS_CC) == 1) {\
REDIS_SAVE_CALLBACK(function, closure_context); \
RETURN_ZVAL(getThis(), 1, 0);\
} else {\
RETURN_FALSE;\
}\
}

#define REDIS_ELSE_IF_PIPELINE(function, closure_context) else IF_PIPELINE() { \
REDIS_SAVE_CALLBACK(function, closure_context); \
RETURN_ZVAL(getThis(), 1, 0);\
}

#define REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len) \
IF_MULTI_OR_ATOMIC() { \
SOCKET_WRITE_COMMAND(redis_sock, cmd, cmd_len); \
efree(cmd); \
}\
IF_PIPELINE() { \
PIPELINE_ENQUEUE_COMMAND(cmd, cmd_len); \
efree(cmd); \
}

#define REDIS_PROCESS_RESPONSE_CLOSURE(function, closure_context) \
REDIS_ELSE_IF_MULTI(function, closure_context) \
REDIS_ELSE_IF_PIPELINE(function, closure_context);

#define REDIS_PROCESS_RESPONSE(function) REDIS_PROCESS_RESPONSE_CLOSURE(function, NULL)

typedef enum {ATOMIC, MULTI, PIPELINE} redis_mode;

typedef struct fold_item {
zval * (*fun)(INTERNAL_FUNCTION_PARAMETERS, void *, ...);
void *ctx;
struct fold_item *next;
} fold_item;

typedef struct request_item {
char *request_str;
int request_size; /* size_t */
struct request_item *next;
} request_item;

/* {{{ struct RedisSock */
typedef struct {
    php_stream *stream;
    char *host;
    short port;
    double timeout;
    int failed;
    int status;
    int persistent;
    int watching;
    char *persistent_id;

    int serializer;
    long dbNumber;

    char *prefix;
    int prefix_len;

    redis_mode mode;
    fold_item *head;
    fold_item *current;

    request_item *pipeline_head;
    request_item *pipeline_current;

    char *err;
    int err_len;
} RedisSock;
/* }}} */

void
free_reply_callbacks(zval *z_this, RedisSock *redis_sock);

#endif
Something went wrong with that request. Please try again.