Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
hiredis
Commits
8cb4d52c
Commit
8cb4d52c
authored
Dec 28, 2010
by
Pieter Noordhuis
Browse files
Run pending callbacks with a NULL reply on redisAsyncFree()
parent
29ea901b
Changes
1
Hide whitespace changes
Inline
Side-by-side
async.c
View file @
8cb4d52c
...
@@ -154,16 +154,29 @@ static int __redisShiftCallback(redisCallbackList *list, redisCallback *target)
...
@@ -154,16 +154,29 @@ static int __redisShiftCallback(redisCallbackList *list, redisCallback *target)
/* Helper function to free the context. */
/* Helper function to free the context. */
static
void
__redisAsyncFree
(
redisAsyncContext
*
ac
)
{
static
void
__redisAsyncFree
(
redisAsyncContext
*
ac
)
{
redisContext
*
c
=
&
(
ac
->
c
);
redisContext
*
c
=
&
(
ac
->
c
);
redisCallback
cb
;
/* Clear callback list */
/* Execute pending callbacks with NULL reply. */
while
(
__redisShiftCallback
(
&
ac
->
replies
,
NULL
)
==
REDIS_OK
);
while
(
__redisShiftCallback
(
&
ac
->
replies
,
&
cb
)
==
REDIS_OK
)
{
if
(
cb
.
fn
!=
NULL
)
{
c
->
flags
|=
REDIS_IN_CALLBACK
;
cb
.
fn
(
ac
,
NULL
,
cb
.
privdata
);
c
->
flags
&=
~
REDIS_IN_CALLBACK
;
}
}
/* Signal event lib to clean up */
/* Signal event lib to clean up */
if
(
ac
->
evCleanup
)
ac
->
evCleanup
(
ac
->
_adapter_data
);
if
(
ac
->
evCleanup
)
ac
->
evCleanup
(
ac
->
_adapter_data
);
/* Execute callback with proper status */
/* Execute disconnect callback. When redisAsyncFree() initiated destroying
if
(
ac
->
onDisconnect
&&
(
c
->
flags
&
REDIS_CONNECTED
))
* this context, the status will always be REDIS_OK. */
ac
->
onDisconnect
(
ac
,
(
ac
->
err
==
0
)
?
REDIS_OK
:
REDIS_ERR
);
if
(
ac
->
onDisconnect
&&
(
c
->
flags
&
REDIS_CONNECTED
))
{
if
(
c
->
flags
&
REDIS_FREEING
)
{
ac
->
onDisconnect
(
ac
,
REDIS_OK
);
}
else
{
ac
->
onDisconnect
(
ac
,(
ac
->
err
==
0
)
?
REDIS_OK
:
REDIS_ERR
);
}
}
/* Cleanup self */
/* Cleanup self */
redisFree
(
c
);
redisFree
(
c
);
...
@@ -175,39 +188,29 @@ static void __redisAsyncFree(redisAsyncContext *ac) {
...
@@ -175,39 +188,29 @@ static void __redisAsyncFree(redisAsyncContext *ac) {
* redisProcessCallbacks(). Otherwise, the context is immediately free'd. */
* redisProcessCallbacks(). Otherwise, the context is immediately free'd. */
void
redisAsyncFree
(
redisAsyncContext
*
ac
)
{
void
redisAsyncFree
(
redisAsyncContext
*
ac
)
{
redisContext
*
c
=
&
(
ac
->
c
);
redisContext
*
c
=
&
(
ac
->
c
);
if
(
c
->
flags
&
REDIS_IN_CALLBACK
)
{
c
->
flags
|=
REDIS_FREEING
;
c
->
flags
|=
REDIS_FREEING
;
if
(
!
(
c
->
flags
&
REDIS_IN_CALLBACK
))
}
else
{
__redisAsyncFree
(
ac
);
__redisAsyncFree
(
ac
);
}
}
}
/* Helper function to make the disconnect happen and clean up. */
/* Helper function to make the disconnect happen and clean up. */
static
void
__redisAsyncDisconnect
(
redisAsyncContext
*
ac
)
{
static
void
__redisAsyncDisconnect
(
redisAsyncContext
*
ac
)
{
redisContext
*
c
=
&
(
ac
->
c
);
redisContext
*
c
=
&
(
ac
->
c
);
redisCallback
cb
;
/* Make sure error is accessible if there is any */
/* Make sure error is accessible if there is any */
__redisAsyncCopyError
(
ac
);
__redisAsyncCopyError
(
ac
);
if
(
ac
->
err
==
0
)
{
if
(
ac
->
err
==
0
)
{
/* When the connection is cleanly disconnected, there should not
/* For clean disconnects, there should be no pending callbacks. */
* be pending callbacks. */
assert
(
__redisShiftCallback
(
&
ac
->
replies
,
NULL
)
==
REDIS_ERR
);
assert
(
__redisShiftCallback
(
&
ac
->
replies
,
NULL
)
==
REDIS_ERR
);
}
else
{
}
else
{
/* Callbacks should not be able to issue new commands. */
/* Disconnection is caused by an error, make sure that pending
* callbacks cannot call new commands. */
c
->
flags
|=
REDIS_DISCONNECTING
;
c
->
flags
|=
REDIS_DISCONNECTING
;
/* Execute pending callbacks with NULL reply. */
while
(
__redisShiftCallback
(
&
ac
->
replies
,
&
cb
)
==
REDIS_OK
)
{
if
(
cb
.
fn
!=
NULL
)
{
c
->
flags
|=
REDIS_IN_CALLBACK
;
cb
.
fn
(
ac
,
NULL
,
cb
.
privdata
);
c
->
flags
&=
~
REDIS_IN_CALLBACK
;
}
}
}
}
/* For non-clean disconnects, __redisAsyncFree() will execute pending
* callbacks with a NULL-reply. */
__redisAsyncFree
(
ac
);
__redisAsyncFree
(
ac
);
}
}
...
@@ -219,11 +222,9 @@ static void __redisAsyncDisconnect(redisAsyncContext *ac) {
...
@@ -219,11 +222,9 @@ static void __redisAsyncDisconnect(redisAsyncContext *ac) {
* when there are no pending callbacks. */
* when there are no pending callbacks. */
void
redisAsyncDisconnect
(
redisAsyncContext
*
ac
)
{
void
redisAsyncDisconnect
(
redisAsyncContext
*
ac
)
{
redisContext
*
c
=
&
(
ac
->
c
);
redisContext
*
c
=
&
(
ac
->
c
);
if
(
c
->
flags
&
REDIS_IN_CALLBACK
||
ac
->
replies
.
head
!=
NULL
)
{
c
->
flags
|=
REDIS_DISCONNECTING
;
c
->
flags
|=
REDIS_DISCONNECTING
;
if
(
!
(
c
->
flags
&
REDIS_IN_CALLBACK
)
&&
ac
->
replies
.
head
==
NULL
)
}
else
{
__redisAsyncDisconnect
(
ac
);
__redisAsyncDisconnect
(
ac
);
}
}
}
void
redisProcessCallbacks
(
redisAsyncContext
*
ac
)
{
void
redisProcessCallbacks
(
redisAsyncContext
*
ac
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment