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
e3776bfa
"src/parser.c" did not exist on "ec934e92d88fec4ffff7e4a98f4b7d948a66873b"
Commit
e3776bfa
authored
Dec 28, 2010
by
Pieter Noordhuis
Browse files
Add function to explicitly free an async context
parent
3d76f3fe
Changes
4
Hide whitespace changes
Inline
Side-by-side
async.c
View file @
e3776bfa
...
...
@@ -151,6 +151,39 @@ static int __redisShiftCallback(redisCallbackList *list, redisCallback *target)
return
REDIS_ERR
;
}
/* Helper function to free the context. */
static
void
__redisAsyncFree
(
redisAsyncContext
*
ac
)
{
redisContext
*
c
=
&
(
ac
->
c
);
/* Clear callback list */
while
(
__redisShiftCallback
(
&
ac
->
replies
,
NULL
)
==
REDIS_OK
);
/* Signal event lib to clean up */
if
(
ac
->
evCleanup
)
ac
->
evCleanup
(
ac
->
_adapter_data
);
/* Execute callback with proper status */
if
(
ac
->
onDisconnect
&&
(
c
->
flags
&
REDIS_CONNECTED
))
ac
->
onDisconnect
(
ac
,
(
ac
->
err
==
0
)
?
REDIS_OK
:
REDIS_ERR
);
/* Cleanup self */
redisFree
(
c
);
}
/* Free's the async context. When REDIS_CONNECTED is set, it could only have
* been called from a command callback so we need to let control return to
* redisProcessCallbacks() before free'ing can continue.
*
* When REDIS_CONNECTED is not set, the first write event has not yet fired and
* we can free immediately. */
void
redisAsyncFree
(
redisAsyncContext
*
ac
)
{
redisContext
*
c
=
&
(
ac
->
c
);
if
(
c
->
flags
&
REDIS_CONNECTED
)
{
c
->
flags
|=
REDIS_FREEING
;
}
else
{
__redisAsyncFree
(
ac
);
}
}
/* Tries to do a clean disconnect from Redis, meaning it stops new commands
* from being issued, but tries to flush the output buffer and execute
* callbacks for all remaining replies.
...
...
@@ -167,13 +200,11 @@ void redisAsyncDisconnect(redisAsyncContext *ac) {
static
void
__redisAsyncDisconnect
(
redisAsyncContext
*
ac
)
{
redisContext
*
c
=
&
(
ac
->
c
);
redisCallback
cb
;
int
status
;
/* Make sure error is accessible if there is any */
__redisAsyncCopyError
(
ac
);
status
=
(
ac
->
err
==
0
)
?
REDIS_OK
:
REDIS_ERR
;
if
(
status
==
REDIS_OK
)
{
if
(
ac
->
err
==
0
)
{
/* When the connection is cleanly disconnected, there should not
* be pending callbacks. */
assert
(
__redisShiftCallback
(
&
ac
->
replies
,
NULL
)
==
REDIS_ERR
);
...
...
@@ -188,14 +219,7 @@ static void __redisAsyncDisconnect(redisAsyncContext *ac) {
}
}
/* Signal event lib to clean up */
if
(
ac
->
evCleanup
)
ac
->
evCleanup
(
ac
->
_adapter_data
);
/* Execute callback with proper status */
if
(
ac
->
onDisconnect
)
ac
->
onDisconnect
(
ac
,
status
);
/* Cleanup self */
redisFree
(
c
);
__redisAsyncFree
(
ac
);
}
void
redisProcessCallbacks
(
redisAsyncContext
*
ac
)
{
...
...
@@ -225,6 +249,12 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
}
else
{
c
->
fn
->
freeObject
(
reply
);
}
/* Proceed with free'ing when redisAsyncFree() was called. */
if
(
c
->
flags
&
REDIS_FREEING
)
{
__redisAsyncFree
(
ac
);
return
;
}
}
/* Disconnect when there was an error reading the reply */
...
...
@@ -281,8 +311,8 @@ static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void
redisContext
*
c
=
&
(
ac
->
c
);
redisCallback
cb
;
/* Don't accept new commands when the connection is
lazily
closed. */
if
(
c
->
flags
&
REDIS_DISCONNECTING
)
return
REDIS_ERR
;
/* Don't accept new commands when the connection is
about to be
closed. */
if
(
c
->
flags
&
(
REDIS_DISCONNECTING
|
REDIS_FREEING
)
)
return
REDIS_ERR
;
__redisAppendCommand
(
c
,
cmd
,
len
);
/* Store callback */
...
...
async.h
View file @
e3776bfa
...
...
@@ -95,6 +95,7 @@ int redisAsyncSetReplyObjectFunctions(redisAsyncContext *ac, redisReplyObjectFun
int
redisAsyncSetConnectCallback
(
redisAsyncContext
*
ac
,
redisConnectCallback
*
fn
);
int
redisAsyncSetDisconnectCallback
(
redisAsyncContext
*
ac
,
redisDisconnectCallback
*
fn
);
void
redisAsyncDisconnect
(
redisAsyncContext
*
ac
);
void
redisAsyncFree
(
redisAsyncContext
*
ac
);
/* Handle read/write events */
void
redisAsyncHandleRead
(
redisAsyncContext
*
ac
);
...
...
hiredis.c
View file @
e3776bfa
...
...
@@ -809,8 +809,7 @@ static redisContext *redisContextInit() {
}
void
redisFree
(
redisContext
*
c
)
{
/* Disconnect before free'ing if not yet disconnected. */
if
(
c
->
flags
&
REDIS_CONNECTED
)
if
(
c
->
fd
>
0
)
close
(
c
->
fd
);
if
(
c
->
errstr
!=
NULL
)
sdsfree
(
c
->
errstr
);
...
...
hiredis.h
View file @
e3776bfa
...
...
@@ -64,6 +64,10 @@
* should be terminated once all replies have been read. */
#define REDIS_DISCONNECTING 0x4
/* Flag specific to the async API which means that the context should be clean
* up as soon as possible. */
#define REDIS_FREEING 0x8
#define REDIS_REPLY_STRING 1
#define REDIS_REPLY_ARRAY 2
#define REDIS_REPLY_INTEGER 3
...
...
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