durable_rules 0.33.13 → 0.34.01

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 14164e8dd6116391e91df6a34c18dadc3ff24a0f
4
- data.tar.gz: 556e9724071ab335c72228114c8c5168b497cfa6
3
+ metadata.gz: fb52f7512b46132ca90ab9cb4038c7dcb5973dfe
4
+ data.tar.gz: 62eaa3495f4deb49bb499e4cd4c876b05857b50f
5
5
  SHA512:
6
- metadata.gz: 9df7fe66c5ee833b6866922883031e114661cd1085c254156fea8754c4d2e489c46998822283db472316c6ca2c2414976272b47173a3397bf0f6e1dd3bc9b204
7
- data.tar.gz: 3920871e93fa6bf162207352d7f05e170ceec0c7f4fe8c93f3a7a7069678baa2dbe2e30848610f1aa8dd703b24b2d0b1f1e08d7627eee54404ef9e00d7d425a7
6
+ metadata.gz: 73013f0de7d4fb5eb3624a61a15fa6dd4d6d287a56d48de1877b48eacb5a7b646abc9f7f20ffd207a4ba945632c2a31ab4683759a684512f4fdd40da26436047
7
+ data.tar.gz: b5e83a8ce76c35b5e8e6c010b7f04c2bf135c8dd7de9641173db3f9a5e14fc53098a71b9412b30c10a879264d2a53a8d07cfc55b5119fe5284cff88960d3adb4
@@ -3,15 +3,41 @@
3
3
  # Copyright (C) 2010-2011 Pieter Noordhuis <pcnoordhuis at gmail dot com>
4
4
  # This file is released under the BSD license, see the COPYING file
5
5
 
6
- OBJ=net.o hiredis.o sds.o async.o
7
- BINS=hiredis-example hiredis-test
6
+ OBJ=net.o hiredis.o sds.o async.o read.o
7
+ EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib
8
+ TESTS=hiredis-test
8
9
  LIBNAME=libhiredis
10
+ PKGCONFNAME=hiredis.pc
9
11
 
10
- HIREDIS_MAJOR=0
11
- HIREDIS_MINOR=10
12
+ HIREDIS_MAJOR=$(shell grep HIREDIS_MAJOR hiredis.h | awk '{print $$3}')
13
+ HIREDIS_MINOR=$(shell grep HIREDIS_MINOR hiredis.h | awk '{print $$3}')
14
+ HIREDIS_PATCH=$(shell grep HIREDIS_PATCH hiredis.h | awk '{print $$3}')
15
+ HIREDIS_SONAME=$(shell grep HIREDIS_SONAME hiredis.h | awk '{print $$3}')
16
+
17
+ # Installation related variables and target
18
+ PREFIX?=/usr/local
19
+ INCLUDE_PATH?=include/hiredis
20
+ LIBRARY_PATH?=lib
21
+ PKGCONF_PATH?=pkgconfig
22
+ INSTALL_INCLUDE_PATH= $(DESTDIR)$(PREFIX)/$(INCLUDE_PATH)
23
+ INSTALL_LIBRARY_PATH= $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH)
24
+ INSTALL_PKGCONF_PATH= $(INSTALL_LIBRARY_PATH)/$(PKGCONF_PATH)
25
+
26
+ # redis-server configuration used for testing
27
+ REDIS_PORT=56379
28
+ REDIS_SERVER=redis-server
29
+ define REDIS_TEST_CONFIG
30
+ daemonize yes
31
+ pidfile /tmp/hiredis-test-redis.pid
32
+ port $(REDIS_PORT)
33
+ bind 127.0.0.1
34
+ unixsocket /tmp/hiredis-test-redis.sock
35
+ endef
36
+ export REDIS_TEST_CONFIG
12
37
 
13
38
  # Fallback to gcc when $CC is not in $PATH.
14
39
  CC:=$(shell sh -c 'type $(CC) >/dev/null 2>/dev/null && echo $(CC) || echo gcc')
40
+ CXX:=$(shell sh -c 'type $(CXX) >/dev/null 2>/dev/null && echo $(CXX) || echo g++')
15
41
  OPTIMIZATION?=-O3
16
42
  WARNINGS=-Wall -W -Wstrict-prototypes -Wwrite-strings
17
43
  DEBUG?= -g -ggdb
@@ -20,7 +46,7 @@ REAL_LDFLAGS=$(LDFLAGS) $(ARCH)
20
46
 
21
47
  DYLIBSUFFIX=so
22
48
  STLIBSUFFIX=a
23
- DYLIB_MINOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_MAJOR).$(HIREDIS_MINOR)
49
+ DYLIB_MINOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_SONAME)
24
50
  DYLIB_MAJOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_MAJOR)
25
51
  DYLIBNAME=$(LIBNAME).$(DYLIBSUFFIX)
26
52
  DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
@@ -36,20 +62,20 @@ ifeq ($(uname_S),SunOS)
36
62
  endif
37
63
  ifeq ($(uname_S),Darwin)
38
64
  DYLIBSUFFIX=dylib
39
- DYLIB_MINOR_NAME=$(LIBNAME).$(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(DYLIBSUFFIX)
40
- DYLIB_MAJOR_NAME=$(LIBNAME).$(HIREDIS_MAJOR).$(DYLIBSUFFIX)
65
+ DYLIB_MINOR_NAME=$(LIBNAME).$(HIREDIS_SONAME).$(DYLIBSUFFIX)
41
66
  DYLIB_MAKE_CMD=$(CC) -shared -Wl,-install_name,$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
42
67
  endif
43
68
 
44
- all: $(DYLIBNAME) $(BINS)
69
+ all: $(DYLIBNAME) $(STLIBNAME) hiredis-test $(PKGCONFNAME)
45
70
 
46
71
  # Deps (use make dep to generate this)
47
- net.o: net.c fmacros.h net.h hiredis.h
48
- async.o: async.c async.h hiredis.h sds.h dict.c dict.h
49
- example.o: example.c hiredis.h
50
- hiredis.o: hiredis.c fmacros.h hiredis.h net.h sds.h
72
+ async.o: async.c fmacros.h async.h hiredis.h read.h sds.h net.h dict.c dict.h
73
+ dict.o: dict.c fmacros.h dict.h
74
+ hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h net.h
75
+ net.o: net.c fmacros.h net.h hiredis.h read.h sds.h
76
+ read.o: read.c fmacros.h read.h sds.h
51
77
  sds.o: sds.c sds.h
52
- test.o: test.c hiredis.h
78
+ test.o: test.c fmacros.h hiredis.h read.h sds.h
53
79
 
54
80
  $(DYLIBNAME): $(OBJ)
55
81
  $(DYLIB_MAKE_CMD) $(OBJ)
@@ -61,36 +87,68 @@ dynamic: $(DYLIBNAME)
61
87
  static: $(STLIBNAME)
62
88
 
63
89
  # Binaries:
64
- hiredis-example-libevent: example-libevent.c adapters/libevent.h $(STLIBNAME)
65
- $(CC) -o $@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -levent example-libevent.c $(STLIBNAME)
90
+ hiredis-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLIBNAME)
91
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -levent $(STLIBNAME)
92
+
93
+ hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME)
94
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -lev $(STLIBNAME)
95
+
96
+ hiredis-example-glib: examples/example-glib.c adapters/glib.h $(STLIBNAME)
97
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) $(shell pkg-config --cflags --libs glib-2.0) -I. $< $(STLIBNAME)
66
98
 
67
- hiredis-example-libev: example-libev.c adapters/libev.h $(STLIBNAME)
68
- $(CC) -o $@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -lev example-libev.c $(STLIBNAME)
99
+ hiredis-example-ivykis: examples/example-ivykis.c adapters/ivykis.h $(STLIBNAME)
100
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -livykis $(STLIBNAME)
101
+
102
+ hiredis-example-macosx: examples/example-macosx.c adapters/macosx.h $(STLIBNAME)
103
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -framework CoreFoundation $(STLIBNAME)
69
104
 
70
105
  ifndef AE_DIR
71
106
  hiredis-example-ae:
72
107
  @echo "Please specify AE_DIR (e.g. <redis repository>/src)"
73
108
  @false
74
109
  else
75
- hiredis-example-ae: example-ae.c adapters/ae.h $(STLIBNAME)
76
- $(CC) -o $@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I$(AE_DIR) $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o example-ae.c $(STLIBNAME)
110
+ hiredis-example-ae: examples/example-ae.c adapters/ae.h $(STLIBNAME)
111
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(AE_DIR) $< $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o $(AE_DIR)/../deps/jemalloc/lib/libjemalloc.a -pthread $(STLIBNAME)
112
+ endif
113
+
114
+ ifndef LIBUV_DIR
115
+ hiredis-example-libuv:
116
+ @echo "Please specify LIBUV_DIR (e.g. ../libuv/)"
117
+ @false
118
+ else
119
+ hiredis-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME)
120
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(LIBUV_DIR)/include $< $(LIBUV_DIR)/.libs/libuv.a -lpthread -lrt $(STLIBNAME)
77
121
  endif
78
122
 
123
+ ifeq ($(and $(QT_MOC),$(QT_INCLUDE_DIR),$(QT_LIBRARY_DIR)),)
124
+ hiredis-example-qt:
125
+ @echo "Please specify QT_MOC, QT_INCLUDE_DIR AND QT_LIBRARY_DIR"
126
+ @false
127
+ else
128
+ hiredis-example-qt: examples/example-qt.cpp adapters/qt.h $(STLIBNAME)
129
+ $(QT_MOC) adapters/qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \
130
+ $(CXX) -x c++ -o qt-adapter-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore
131
+ $(QT_MOC) examples/example-qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \
132
+ $(CXX) -x c++ -o qt-example-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore
133
+ $(CXX) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore -L$(QT_LIBRARY_DIR) qt-adapter-moc.o qt-example-moc.o $< -pthread $(STLIBNAME) -lQtCore
134
+ endif
135
+
136
+ hiredis-example: examples/example.c $(STLIBNAME)
137
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< $(STLIBNAME)
138
+
139
+ examples: $(EXAMPLES)
140
+
141
+ hiredis-test: test.o $(STLIBNAME)
142
+
79
143
  hiredis-%: %.o $(STLIBNAME)
80
- $(CC) -o $@ $(REAL_LDFLAGS) $< $(STLIBNAME)
144
+ $(CC) $(REAL_CFLAGS) -o $@ $(REAL_LDFLAGS) $< $(STLIBNAME)
81
145
 
82
146
  test: hiredis-test
83
147
  ./hiredis-test
84
148
 
85
149
  check: hiredis-test
86
- echo \
87
- "daemonize yes\n" \
88
- "pidfile /tmp/hiredis-test-redis.pid\n" \
89
- "port 56379\n" \
90
- "bind 127.0.0.1\n" \
91
- "unixsocket /tmp/hiredis-test-redis.sock" \
92
- | redis-server -
93
- ./hiredis-test -h 127.0.0.1 -p 56379 -s /tmp/hiredis-test-redis.sock || \
150
+ @echo "$$REDIS_TEST_CONFIG" | $(REDIS_SERVER) -
151
+ $(PRE) ./hiredis-test -h 127.0.0.1 -p $(REDIS_PORT) -s /tmp/hiredis-test-redis.sock || \
94
152
  ( kill `cat /tmp/hiredis-test-redis.pid` && false )
95
153
  kill `cat /tmp/hiredis-test-redis.pid`
96
154
 
@@ -98,31 +156,38 @@ check: hiredis-test
98
156
  $(CC) -std=c99 -pedantic -c $(REAL_CFLAGS) $<
99
157
 
100
158
  clean:
101
- rm -rf $(DYLIBNAME) $(STLIBNAME) $(BINS) hiredis-example* *.o *.gcda *.gcno *.gcov
159
+ rm -rf $(DYLIBNAME) $(STLIBNAME) $(TESTS) $(PKGCONFNAME) examples/hiredis-example* *.o *.gcda *.gcno *.gcov
102
160
 
103
161
  dep:
104
162
  $(CC) -MM *.c
105
163
 
106
- # Installation related variables and target
107
- PREFIX?=/usr/local
108
- INCLUDE_PATH?=include/hiredis
109
- LIBRARY_PATH?=lib
110
- INSTALL_INCLUDE_PATH= $(PREFIX)/$(INCLUDE_PATH)
111
- INSTALL_LIBRARY_PATH= $(PREFIX)/$(LIBRARY_PATH)
112
-
113
164
  ifeq ($(uname_S),SunOS)
114
165
  INSTALL?= cp -r
115
166
  endif
116
167
 
117
168
  INSTALL?= cp -a
118
169
 
119
- install: $(DYLIBNAME) $(STLIBNAME)
170
+ $(PKGCONFNAME): hiredis.h
171
+ @echo "Generating $@ for pkgconfig..."
172
+ @echo prefix=$(PREFIX) > $@
173
+ @echo exec_prefix=\$${prefix} >> $@
174
+ @echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@
175
+ @echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@
176
+ @echo >> $@
177
+ @echo Name: hiredis >> $@
178
+ @echo Description: Minimalistic C client library for Redis. >> $@
179
+ @echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@
180
+ @echo Libs: -L\$${libdir} -lhiredis >> $@
181
+ @echo Cflags: -I\$${includedir} -D_FILE_OFFSET_BITS=64 >> $@
182
+
183
+ install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME)
120
184
  mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_LIBRARY_PATH)
121
- $(INSTALL) hiredis.h async.h adapters $(INSTALL_INCLUDE_PATH)
185
+ $(INSTALL) hiredis.h async.h read.h sds.h adapters $(INSTALL_INCLUDE_PATH)
122
186
  $(INSTALL) $(DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(DYLIB_MINOR_NAME)
123
- cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIB_MAJOR_NAME)
124
- cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MAJOR_NAME) $(DYLIBNAME)
187
+ cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIBNAME)
125
188
  $(INSTALL) $(STLIBNAME) $(INSTALL_LIBRARY_PATH)
189
+ mkdir -p $(INSTALL_PKGCONF_PATH)
190
+ $(INSTALL) $(PKGCONFNAME) $(INSTALL_PKGCONF_PATH)
126
191
 
127
192
  32bit:
128
193
  @echo ""
@@ -130,6 +195,10 @@ install: $(DYLIBNAME) $(STLIBNAME)
130
195
  @echo ""
131
196
  $(MAKE) CFLAGS="-m32" LDFLAGS="-m32"
132
197
 
198
+ 32bit-vars:
199
+ $(eval CFLAGS=-m32)
200
+ $(eval LDFLAGS=-m32)
201
+
133
202
  gprof:
134
203
  $(MAKE) CFLAGS="-pg" LDFLAGS="-pg"
135
204
 
@@ -145,4 +214,4 @@ coverage: gcov
145
214
  noopt:
146
215
  $(MAKE) OPTIMIZATION=""
147
216
 
148
- .PHONY: all test check clean dep install 32bit gprof gcov noopt
217
+ .PHONY: all test check clean dep install 32bit 32bit-vars gprof gcov noopt
data/deps/hiredis/async.c CHANGED
@@ -58,11 +58,12 @@
58
58
  } while(0);
59
59
 
60
60
  /* Forward declaration of function in hiredis.c */
61
- void __redisAppendCommand(redisContext *c, char *cmd, size_t len);
61
+ int __redisAppendCommand(redisContext *c, const char *cmd, size_t len);
62
62
 
63
63
  /* Functions managing dictionary of callbacks for pub/sub. */
64
64
  static unsigned int callbackHash(const void *key) {
65
- return dictGenHashFunction((unsigned char*)key,sdslen((char*)key));
65
+ return dictGenHashFunction((const unsigned char *)key,
66
+ sdslen((const sds)key));
66
67
  }
67
68
 
68
69
  static void *callbackValDup(void *privdata, const void *src) {
@@ -76,8 +77,8 @@ static int callbackKeyCompare(void *privdata, const void *key1, const void *key2
76
77
  int l1, l2;
77
78
  ((void) privdata);
78
79
 
79
- l1 = sdslen((sds)key1);
80
- l2 = sdslen((sds)key2);
80
+ l1 = sdslen((const sds)key1);
81
+ l2 = sdslen((const sds)key2);
81
82
  if (l1 != l2) return 0;
82
83
  return memcmp(key1,key2,l1) == 0;
83
84
  }
@@ -102,7 +103,12 @@ static dictType callbackDict = {
102
103
  };
103
104
 
104
105
  static redisAsyncContext *redisAsyncInitialize(redisContext *c) {
105
- redisAsyncContext *ac = realloc(c,sizeof(redisAsyncContext));
106
+ redisAsyncContext *ac;
107
+
108
+ ac = realloc(c,sizeof(redisAsyncContext));
109
+ if (ac == NULL)
110
+ return NULL;
111
+
106
112
  c = &(ac->c);
107
113
 
108
114
  /* The regular connect functions will always set the flag REDIS_CONNECTED.
@@ -136,25 +142,66 @@ static redisAsyncContext *redisAsyncInitialize(redisContext *c) {
136
142
  /* We want the error field to be accessible directly instead of requiring
137
143
  * an indirection to the redisContext struct. */
138
144
  static void __redisAsyncCopyError(redisAsyncContext *ac) {
145
+ if (!ac)
146
+ return;
147
+
139
148
  redisContext *c = &(ac->c);
140
149
  ac->err = c->err;
141
150
  ac->errstr = c->errstr;
142
151
  }
143
152
 
144
153
  redisAsyncContext *redisAsyncConnect(const char *ip, int port) {
145
- redisContext *c = redisConnectNonBlock(ip,port);
154
+ redisContext *c;
155
+ redisAsyncContext *ac;
156
+
157
+ c = redisConnectNonBlock(ip,port);
158
+ if (c == NULL)
159
+ return NULL;
160
+
161
+ ac = redisAsyncInitialize(c);
162
+ if (ac == NULL) {
163
+ redisFree(c);
164
+ return NULL;
165
+ }
166
+
167
+ __redisAsyncCopyError(ac);
168
+ return ac;
169
+ }
170
+
171
+ redisAsyncContext *redisAsyncConnectBind(const char *ip, int port,
172
+ const char *source_addr) {
173
+ redisContext *c = redisConnectBindNonBlock(ip,port,source_addr);
146
174
  redisAsyncContext *ac = redisAsyncInitialize(c);
147
175
  __redisAsyncCopyError(ac);
148
176
  return ac;
149
177
  }
150
178
 
151
- redisAsyncContext *redisAsyncConnectUnix(const char *path) {
152
- redisContext *c = redisConnectUnixNonBlock(path);
179
+ redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port,
180
+ const char *source_addr) {
181
+ redisContext *c = redisConnectBindNonBlockWithReuse(ip,port,source_addr);
153
182
  redisAsyncContext *ac = redisAsyncInitialize(c);
154
183
  __redisAsyncCopyError(ac);
155
184
  return ac;
156
185
  }
157
186
 
187
+ redisAsyncContext *redisAsyncConnectUnix(const char *path) {
188
+ redisContext *c;
189
+ redisAsyncContext *ac;
190
+
191
+ c = redisConnectUnixNonBlock(path);
192
+ if (c == NULL)
193
+ return NULL;
194
+
195
+ ac = redisAsyncInitialize(c);
196
+ if (ac == NULL) {
197
+ redisFree(c);
198
+ return NULL;
199
+ }
200
+
201
+ __redisAsyncCopyError(ac);
202
+ return ac;
203
+ }
204
+
158
205
  int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) {
159
206
  if (ac->onConnect == NULL) {
160
207
  ac->onConnect = fn;
@@ -182,6 +229,9 @@ static int __redisPushCallback(redisCallbackList *list, redisCallback *source) {
182
229
 
183
230
  /* Copy callback from stack to heap */
184
231
  cb = malloc(sizeof(*cb));
232
+ if (cb == NULL)
233
+ return REDIS_ERR_OOM;
234
+
185
235
  if (source != NULL) {
186
236
  memcpy(cb,source,sizeof(*cb));
187
237
  cb->next = NULL;
@@ -360,7 +410,7 @@ static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply,
360
410
 
361
411
  void redisProcessCallbacks(redisAsyncContext *ac) {
362
412
  redisContext *c = &(ac->c);
363
- redisCallback cb;
413
+ redisCallback cb = {NULL, NULL, NULL};
364
414
  void *reply = NULL;
365
415
  int status;
366
416
 
@@ -368,11 +418,12 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
368
418
  if (reply == NULL) {
369
419
  /* When the connection is being disconnected and there are
370
420
  * no more replies, this is the cue to really disconnect. */
371
- if (c->flags & REDIS_DISCONNECTING && sdslen(c->obuf) == 0) {
421
+ if (c->flags & REDIS_DISCONNECTING && sdslen(c->obuf) == 0
422
+ && ac->replies.head == NULL) {
372
423
  __redisAsyncDisconnect(ac);
373
424
  return;
374
425
  }
375
-
426
+
376
427
  /* If monitor mode, repush callback */
377
428
  if(c->flags & REDIS_MONITORING) {
378
429
  __redisPushCallback(&ac->replies,&cb);
@@ -404,6 +455,7 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
404
455
  if (((redisReply*)reply)->type == REDIS_REPLY_ERROR) {
405
456
  c->err = REDIS_ERR_OTHER;
406
457
  snprintf(c->errstr,sizeof(c->errstr),"%s",((redisReply*)reply)->str);
458
+ c->reader->fn->freeObject(reply);
407
459
  __redisAsyncDisconnect(ac);
408
460
  return;
409
461
  }
@@ -442,7 +494,7 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
442
494
  static int __redisAsyncHandleConnect(redisAsyncContext *ac) {
443
495
  redisContext *c = &(ac->c);
444
496
 
445
- if (redisCheckSocketError(c,c->fd) == REDIS_ERR) {
497
+ if (redisCheckSocketError(c) == REDIS_ERR) {
446
498
  /* Try again later when connect(2) is still in progress. */
447
499
  if (errno == EINPROGRESS)
448
500
  return REDIS_OK;
@@ -511,8 +563,8 @@ void redisAsyncHandleWrite(redisAsyncContext *ac) {
511
563
 
512
564
  /* Sets a pointer to the first argument and its length starting at p. Returns
513
565
  * the number of bytes to skip to get to the following argument. */
514
- static char *nextArgument(char *start, char **str, size_t *len) {
515
- char *p = start;
566
+ static const char *nextArgument(const char *start, const char **str, size_t *len) {
567
+ const char *p = start;
516
568
  if (p[0] != '$') {
517
569
  p = strchr(p,'$');
518
570
  if (p == NULL) return NULL;
@@ -528,14 +580,15 @@ static char *nextArgument(char *start, char **str, size_t *len) {
528
580
  /* Helper function for the redisAsyncCommand* family of functions. Writes a
529
581
  * formatted command to the output buffer and registers the provided callback
530
582
  * function with the context. */
531
- static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, char *cmd, size_t len) {
583
+ static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) {
532
584
  redisContext *c = &(ac->c);
533
585
  redisCallback cb;
534
586
  int pvariant, hasnext;
535
- char *cstr, *astr;
587
+ const char *cstr, *astr;
536
588
  size_t clen, alen;
537
- char *p;
589
+ const char *p;
538
590
  sds sname;
591
+ int ret;
539
592
 
540
593
  /* Don't accept new commands when the connection is about to be closed. */
541
594
  if (c->flags & (REDIS_DISCONNECTING | REDIS_FREEING)) return REDIS_ERR;
@@ -559,9 +612,11 @@ static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void
559
612
  while ((p = nextArgument(p,&astr,&alen)) != NULL) {
560
613
  sname = sdsnewlen(astr,alen);
561
614
  if (pvariant)
562
- dictReplace(ac->sub.patterns,sname,&cb);
615
+ ret = dictReplace(ac->sub.patterns,sname,&cb);
563
616
  else
564
- dictReplace(ac->sub.channels,sname,&cb);
617
+ ret = dictReplace(ac->sub.channels,sname,&cb);
618
+
619
+ if (ret == 0) sdsfree(sname);
565
620
  }
566
621
  } else if (strncasecmp(cstr,"unsubscribe\r\n",13) == 0) {
567
622
  /* It is only useful to call (P)UNSUBSCRIBE when the context is
@@ -597,6 +652,11 @@ int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdat
597
652
  int len;
598
653
  int status;
599
654
  len = redisvFormatCommand(&cmd,format,ap);
655
+
656
+ /* We don't want to pass -1 or -2 to future functions as a length. */
657
+ if (len < 0)
658
+ return REDIS_ERR;
659
+
600
660
  status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
601
661
  free(cmd);
602
662
  return status;
@@ -612,11 +672,16 @@ int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata
612
672
  }
613
673
 
614
674
  int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) {
615
- char *cmd;
675
+ sds cmd;
616
676
  int len;
617
677
  int status;
618
- len = redisFormatCommandArgv(&cmd,argc,argv,argvlen);
678
+ len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen);
619
679
  status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
620
- free(cmd);
680
+ sdsfree(cmd);
681
+ return status;
682
+ }
683
+
684
+ int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) {
685
+ int status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
621
686
  return status;
622
687
  }