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
a66ec18e
Commit
a66ec18e
authored
Nov 01, 2010
by
Pieter Noordhuis
Browse files
Make push/shift functions for callbacks responsible for malloc/free
parent
e25db30f
Changes
1
Hide whitespace changes
Inline
Side-by-side
async.c
View file @
a66ec18e
...
@@ -69,22 +69,38 @@ int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallba
...
@@ -69,22 +69,38 @@ int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallba
}
}
/* Helper functions to push/shift callbacks */
/* Helper functions to push/shift callbacks */
static
void
__redisPushCallback
(
redisCallbackList
*
list
,
redisCallback
*
cb
)
{
static
int
__redisPushCallback
(
redisCallbackList
*
list
,
redisCallback
*
source
)
{
redisCallback
*
cb
;
/* Copy callback from stack to heap */
cb
=
calloc
(
1
,
sizeof
(
*
cb
));
if
(
!
cb
)
redisOOM
();
if
(
source
!=
NULL
)
memcpy
(
cb
,
source
,
sizeof
(
*
cb
));
/* Store callback in list */
if
(
list
->
head
==
NULL
)
if
(
list
->
head
==
NULL
)
list
->
head
=
cb
;
list
->
head
=
cb
;
if
(
list
->
tail
!=
NULL
)
if
(
list
->
tail
!=
NULL
)
list
->
tail
->
next
=
cb
;
list
->
tail
->
next
=
cb
;
list
->
tail
=
cb
;
list
->
tail
=
cb
;
return
REDIS_OK
;
}
}
static
redisCallback
*
__redisShiftCallback
(
redisCallbackList
*
list
)
{
static
int
__redisShiftCallback
(
redisCallbackList
*
list
,
redisCallback
*
target
)
{
redisCallback
*
cb
=
list
->
head
;
redisCallback
*
cb
=
list
->
head
;
if
(
cb
!=
NULL
)
{
if
(
cb
!=
NULL
)
{
list
->
head
=
cb
->
next
;
list
->
head
=
cb
->
next
;
if
(
cb
==
list
->
tail
)
if
(
cb
==
list
->
tail
)
list
->
tail
=
NULL
;
list
->
tail
=
NULL
;
/* Copy callback from heap to stack */
if
(
target
!=
NULL
)
memcpy
(
target
,
cb
,
sizeof
(
*
cb
));
free
(
cb
);
return
REDIS_OK
;
}
}
return
cb
;
return
REDIS_ERR
;
}
}
/* Tries to do a clean disconnect from Redis, meaning it stops new commands
/* Tries to do a clean disconnect from Redis, meaning it stops new commands
...
@@ -102,7 +118,7 @@ void redisAsyncDisconnect(redisAsyncContext *ac) {
...
@@ -102,7 +118,7 @@ void redisAsyncDisconnect(redisAsyncContext *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
;
redisCallback
cb
;
int
status
;
int
status
;
/* Make sure error is accessible if there is any */
/* Make sure error is accessible if there is any */
...
@@ -112,15 +128,15 @@ static void __redisAsyncDisconnect(redisAsyncContext *ac) {
...
@@ -112,15 +128,15 @@ static void __redisAsyncDisconnect(redisAsyncContext *ac) {
if
(
status
==
REDIS_OK
)
{
if
(
status
==
REDIS_OK
)
{
/* When the connection is cleanly disconnected, there should not
/* When the connection is cleanly disconnected, there should not
* be pending callbacks. */
* be pending callbacks. */
assert
(
(
cb
=
__redisShiftCallback
(
&
ac
->
replies
))
==
NULL
);
assert
(
__redisShiftCallback
(
&
ac
->
replies
,
NULL
)
==
REDIS_ERR
);
}
else
{
}
else
{
/* Callbacks should not be able to issue new commands. */
/* Callbacks should not be able to issue new commands. */
c
->
flags
|=
REDIS_DISCONNECTING
;
c
->
flags
|=
REDIS_DISCONNECTING
;
/* Execute pending callbacks with NULL reply. */
/* Execute pending callbacks with NULL reply. */
while
(
(
cb
=
__redisShiftCallback
(
&
ac
->
replies
)
)
!
=
NULL
)
{
while
(
__redisShiftCallback
(
&
ac
->
replies
,
&
cb
)
=
=
REDIS_OK
)
{
if
(
cb
->
fn
!=
NULL
)
if
(
cb
.
fn
!=
NULL
)
cb
->
fn
(
ac
,
NULL
,
cb
->
privdata
);
cb
.
fn
(
ac
,
NULL
,
cb
.
privdata
);
}
}
}
}
...
@@ -136,7 +152,7 @@ static void __redisAsyncDisconnect(redisAsyncContext *ac) {
...
@@ -136,7 +152,7 @@ static void __redisAsyncDisconnect(redisAsyncContext *ac) {
void
redisProcessCallbacks
(
redisAsyncContext
*
ac
)
{
void
redisProcessCallbacks
(
redisAsyncContext
*
ac
)
{
redisContext
*
c
=
&
(
ac
->
c
);
redisContext
*
c
=
&
(
ac
->
c
);
redisCallback
*
cb
;
redisCallback
cb
;
void
*
reply
=
NULL
;
void
*
reply
=
NULL
;
int
status
;
int
status
;
...
@@ -155,10 +171,9 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
...
@@ -155,10 +171,9 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
}
}
/* Shift callback and execute it */
/* Shift callback and execute it */
cb
=
__redisShiftCallback
(
&
ac
->
replies
);
assert
(
__redisShiftCallback
(
&
ac
->
replies
,
&
cb
)
==
REDIS_OK
);
assert
(
cb
!=
NULL
);
if
(
cb
.
fn
!=
NULL
)
{
if
(
cb
->
fn
!=
NULL
)
{
cb
.
fn
(
ac
,
reply
,
cb
.
privdata
);
cb
->
fn
(
ac
,
reply
,
cb
->
privdata
);
}
else
{
}
else
{
c
->
fn
->
freeObject
(
reply
);
c
->
fn
->
freeObject
(
reply
);
}
}
...
@@ -210,18 +225,16 @@ void redisAsyncHandleWrite(redisAsyncContext *ac) {
...
@@ -210,18 +225,16 @@ void redisAsyncHandleWrite(redisAsyncContext *ac) {
*/
*/
static
int
__redisAsyncCommand
(
redisAsyncContext
*
ac
,
redisCallbackFn
*
fn
,
void
*
privdata
,
char
*
cmd
,
size_t
len
)
{
static
int
__redisAsyncCommand
(
redisAsyncContext
*
ac
,
redisCallbackFn
*
fn
,
void
*
privdata
,
char
*
cmd
,
size_t
len
)
{
redisContext
*
c
=
&
(
ac
->
c
);
redisContext
*
c
=
&
(
ac
->
c
);
redisCallback
*
cb
;
redisCallback
cb
;
/* Don't accept new commands when the connection is lazily closed. */
/* Don't accept new commands when the connection is lazily closed. */
if
(
c
->
flags
&
REDIS_DISCONNECTING
)
return
REDIS_ERR
;
if
(
c
->
flags
&
REDIS_DISCONNECTING
)
return
REDIS_ERR
;
c
->
obuf
=
sdscatlen
(
c
->
obuf
,
cmd
,
len
);
c
->
obuf
=
sdscatlen
(
c
->
obuf
,
cmd
,
len
);
/* Store callback */
/* Store callback */
cb
=
calloc
(
1
,
sizeof
(
redisCallback
));
cb
.
fn
=
fn
;
if
(
!
cb
)
redisOOM
();
cb
.
privdata
=
privdata
;
cb
->
fn
=
fn
;
__redisPushCallback
(
&
ac
->
replies
,
&
cb
);
cb
->
privdata
=
privdata
;
__redisPushCallback
(
&
(
ac
->
replies
),
cb
);
/* Always schedule a write when the write buffer is non-empty */
/* Always schedule a write when the write buffer is non-empty */
if
(
ac
->
evAddWrite
)
ac
->
evAddWrite
(
ac
->
data
);
if
(
ac
->
evAddWrite
)
ac
->
evAddWrite
(
ac
->
data
);
...
...
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