summaryrefslogtreecommitdiff
path: root/async.c
diff options
context:
space:
mode:
authormichael-grunder <michael.grunder@gmail.com>2022-08-25 12:08:20 -0700
committermichael-grunder <michael.grunder@gmail.com>2022-08-26 10:14:47 -0700
commit6a3e96ad2149584e441b0e8a5827dc6c2624035b (patch)
tree04fd2496251b711109b73046270f1231a61eb662 /async.c
parente7afd998f9ce3e6dfaa5e6534f779cab6a1c5a7b (diff)
Maintain backward compatibiliy withour onConnect callback.
In f69fac7690fb22a7fc19dba61ef70e5f79ccb2e9, our async onConnect callback was improved to take a non-const redisAsyncContext allowing it to be reentrant. Unfortunately, this is a breaking change we can't make until hiredis v2.0.0. This commit creates a separate callback member and corresponding function that allows us to use the new functionality, while maintaining our existing API for legacy code. Fixes #1086
Diffstat (limited to 'async.c')
-rw-r--r--async.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/async.c b/async.c
index 73b7980..ae097df 100644
--- a/async.c
+++ b/async.c
@@ -140,6 +140,7 @@ static redisAsyncContext *redisAsyncInitialize(redisContext *c) {
ac->ev.scheduleTimer = NULL;
ac->onConnect = NULL;
+ ac->onConnectNC = NULL;
ac->onDisconnect = NULL;
ac->replies.head = NULL;
@@ -226,17 +227,34 @@ redisAsyncContext *redisAsyncConnectUnix(const char *path) {
return redisAsyncConnectWithOptions(&options);
}
-int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) {
- if (ac->onConnect == NULL) {
- ac->onConnect = fn;
+static int
+redisAsyncSetConnectCallbackImpl(redisAsyncContext *ac, redisConnectCallback *fn,
+ redisConnectCallbackNC *fn_nc)
+{
+ /* If either are already set, this is an error */
+ if (ac->onConnect || ac->onConnectNC)
+ return REDIS_ERR;
- /* The common way to detect an established connection is to wait for
- * the first write event to be fired. This assumes the related event
- * library functions are already set. */
- _EL_ADD_WRITE(ac);
- return REDIS_OK;
+ if (fn) {
+ ac->onConnect = fn;
+ } else if (fn_nc) {
+ ac->onConnectNC = fn_nc;
}
- return REDIS_ERR;
+
+ /* The common way to detect an established connection is to wait for
+ * the first write event to be fired. This assumes the related event
+ * library functions are already set. */
+ _EL_ADD_WRITE(ac);
+
+ return REDIS_OK;
+}
+
+int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) {
+ return redisAsyncSetConnectCallbackImpl(ac, fn, NULL);
+}
+
+int redisAsyncSetConnectCallbackNC(redisAsyncContext *ac, redisConnectCallbackNC *fn) {
+ return redisAsyncSetConnectCallbackImpl(ac, NULL, fn);
}
int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn) {
@@ -305,14 +323,23 @@ static void __redisRunPushCallback(redisAsyncContext *ac, redisReply *reply) {
static void __redisRunConnectCallback(redisAsyncContext *ac, int status)
{
- if (ac->onConnect) {
- if (!(ac->c.flags & REDIS_IN_CALLBACK)) {
- ac->c.flags |= REDIS_IN_CALLBACK;
+ if (ac->onConnect == NULL && ac->onConnectNC == NULL)
+ return;
+
+ if (!(ac->c.flags & REDIS_IN_CALLBACK)) {
+ ac->c.flags |= REDIS_IN_CALLBACK;
+ if (ac->onConnect) {
ac->onConnect(ac, status);
- ac->c.flags &= ~REDIS_IN_CALLBACK;
} else {
- /* already in callback */
+ ac->onConnectNC(ac, status);
+ }
+ ac->c.flags &= ~REDIS_IN_CALLBACK;
+ } else {
+ /* already in callback */
+ if (ac->onConnect) {
ac->onConnect(ac, status);
+ } else {
+ ac->onConnectNC(ac, status);
}
}
}