diff options
author | michael-grunder <michael.grunder@gmail.com> | 2022-08-25 12:08:20 -0700 |
---|---|---|
committer | michael-grunder <michael.grunder@gmail.com> | 2022-08-26 10:14:47 -0700 |
commit | 6a3e96ad2149584e441b0e8a5827dc6c2624035b (patch) | |
tree | 04fd2496251b711109b73046270f1231a61eb662 /async.c | |
parent | e7afd998f9ce3e6dfaa5e6534f779cab6a1c5a7b (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.c | 55 |
1 files changed, 41 insertions, 14 deletions
@@ -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); } } } |