Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
hiredis
Commits
47e1f771
Commit
47e1f771
authored
Oct 31, 2010
by
Pieter Noordhuis
Browse files
Refactor internal function flow and add redisAppendCommand* family
parent
298e9325
Changes
2
Show whitespace changes
Inline
Side-by-side
hiredis.c
View file @
47e1f771
...
@@ -730,15 +730,6 @@ int redisBufferRead(redisContext *c) {
...
@@ -730,15 +730,6 @@ int redisBufferRead(redisContext *c) {
return
REDIS_OK
;
return
REDIS_OK
;
}
}
int
redisGetReply
(
redisContext
*
c
,
void
**
reply
)
{
if
(
redisReplyReaderGetReply
(
c
->
reader
,
reply
)
==
REDIS_ERR
)
{
/* Copy the (protocol) error from the reader to the context. */
c
->
error
=
sdsnew
(((
redisReader
*
)
c
->
reader
)
->
error
);
return
REDIS_ERR
;
}
return
REDIS_OK
;
}
/* Write the output buffer to the socket.
/* Write the output buffer to the socket.
*
*
* Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
* Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
...
@@ -774,69 +765,137 @@ int redisBufferWrite(redisContext *c, int *done) {
...
@@ -774,69 +765,137 @@ int redisBufferWrite(redisContext *c, int *done) {
return
REDIS_OK
;
return
REDIS_OK
;
}
}
static
int
redisCommandWriteBlock
(
redisContext
*
c
,
void
**
reply
,
char
*
str
,
size_t
len
)
{
/* Internal helper function to try and get a reply from the reader,
* or set an error in the context otherwise. */
static
int
__redisGetReply
(
redisContext
*
c
,
void
**
reply
)
{
if
(
redisReplyReaderGetReply
(
c
->
reader
,
reply
)
==
REDIS_ERR
)
{
/* Copy the (protocol) error from the reader to the context. */
c
->
error
=
sdsnew
(((
redisReader
*
)
c
->
reader
)
->
error
);
return
REDIS_ERR
;
}
return
REDIS_OK
;
}
int
redisGetReply
(
redisContext
*
c
,
void
**
reply
)
{
int
wdone
=
0
;
int
wdone
=
0
;
void
*
aux
=
NULL
;
void
*
aux
=
NULL
;
assert
(
c
->
flags
&
REDIS_BLOCK
);
c
->
obuf
=
sdscatlen
(
c
->
obuf
,
str
,
len
);
/* Write until done. */
/* Try to read pending replies */
if
(
__redisGetReply
(
c
,
&
aux
)
==
REDIS_ERR
)
{
return
REDIS_ERR
;
}
else
{
/* Return immediately if there was a pending reply */
if
(
aux
!=
NULL
)
return
REDIS_OK
;
}
/* For the blocking context, flush output buffer and read reply */
if
(
c
->
flags
&
REDIS_BLOCK
)
{
/* Write until done */
do
{
do
{
if
(
redisBufferWrite
(
c
,
&
wdone
)
==
REDIS_ERR
)
if
(
redisBufferWrite
(
c
,
&
wdone
)
==
REDIS_ERR
)
return
REDIS_ERR
;
return
REDIS_ERR
;
}
while
(
!
wdone
);
}
while
(
!
wdone
);
/* Read until there is a reply
.
*/
/* Read until there is a reply */
do
{
do
{
if
(
redisBufferRead
(
c
)
==
REDIS_ERR
)
if
(
redisBufferRead
(
c
)
==
REDIS_ERR
)
return
REDIS_ERR
;
return
REDIS_ERR
;
if
(
redisGetReply
(
c
,
&
aux
)
==
REDIS_ERR
)
if
(
__
redisGetReply
(
c
,
&
aux
)
==
REDIS_ERR
)
return
REDIS_ERR
;
return
REDIS_ERR
;
}
while
(
aux
==
NULL
);
}
while
(
aux
==
NULL
);
/* Set reply object. */
/* Set reply object */
if
(
reply
!=
NULL
)
if
(
reply
!=
NULL
)
*
reply
=
aux
;
*
reply
=
aux
;
}
return
REDIS_OK
;
return
REDIS_OK
;
}
}
static
int
redisCommandWriteNonBlock
(
redisContext
*
c
,
char
*
str
,
size_t
len
)
{
assert
(
!
(
c
->
flags
&
REDIS_BLOCK
));
/* Helper function for the redisAppendCommand* family of functions.
c
->
obuf
=
sdscatlen
(
c
->
obuf
,
str
,
len
);
*
* Write a formatted command to the output buffer. When this family
* is used, you need to call redisGetReply yourself to retrieve
* the reply (or replies in pub/sub).
*/
void
__redisAppendCommand
(
redisContext
*
c
,
char
*
cmd
,
size_t
len
)
{
c
->
obuf
=
sdscatlen
(
c
->
obuf
,
cmd
,
len
);
/* Fire write callback */
/* Fire write callback */
if
(
c
->
cbCommand
.
fn
!=
NULL
)
if
(
c
->
cbCommand
.
fn
!=
NULL
)
c
->
cbCommand
.
fn
(
c
,
c
->
cbCommand
.
privdata
);
c
->
cbCommand
.
fn
(
c
,
c
->
cbCommand
.
privdata
);
}
return
REDIS_OK
;
void
redisvAppendCommand
(
redisContext
*
c
,
const
char
*
format
,
va_list
ap
)
{
char
*
cmd
;
int
len
;
len
=
redisvFormatCommand
(
&
cmd
,
format
,
ap
);
__redisAppendCommand
(
c
,
cmd
,
len
);
free
(
cmd
);
}
}
/* Write a formatted command to the output buffer. If the given context is
void
redisAppendCommand
(
redisContext
*
c
,
const
char
*
format
,
...)
{
va_list
ap
;
va_start
(
ap
,
format
);
redisvAppendCommand
(
c
,
format
,
ap
);
va_end
(
ap
);
}
void
redisAppendCommandArgv
(
redisContext
*
c
,
int
argc
,
const
char
**
argv
,
const
size_t
*
argvlen
)
{
char
*
cmd
;
int
len
;
len
=
redisFormatCommandArgv
(
&
cmd
,
argc
,
argv
,
argvlen
);
__redisAppendCommand
(
c
,
cmd
,
len
);
free
(
cmd
);
}
/* Helper function for the redisCommand* family of functions.
*
* Write a formatted command to the output buffer. If the given context is
* blocking, immediately read the reply into the "reply" pointer. When the
* blocking, immediately read the reply into the "reply" pointer. When the
* context is non-blocking, the "reply" pointer will not be used and the
* context is non-blocking, the "reply" pointer will not be used and the
* command is simply appended to the write buffer.
* command is simply appended to the write buffer.
*
*
* Returns the reply when a reply was succesfully retrieved. Returns NULL
* Returns the reply when a reply was succesfully retrieved. Returns NULL
* otherwise. When NULL is returned in a blocking context, the error field
* otherwise. When NULL is returned in a blocking context, the error field
* in the context will be set. */
* in the context will be set.
void
*
redisCommand
(
redisContext
*
c
,
const
char
*
format
,
...)
{
*/
va_list
ap
;
static
void
*
__redisCommand
(
redisContext
*
c
,
char
*
cmd
,
size_t
len
)
{
void
*
aux
=
NULL
;
__redisAppendCommand
(
c
,
cmd
,
len
);
if
(
c
->
flags
&
REDIS_BLOCK
)
{
if
(
redisGetReply
(
c
,
&
aux
)
==
REDIS_OK
)
return
aux
;
return
NULL
;
}
return
NULL
;
}
void
*
redisvCommand
(
redisContext
*
c
,
const
char
*
format
,
va_list
ap
)
{
char
*
cmd
;
char
*
cmd
;
int
len
;
int
len
;
void
*
reply
=
NULL
;
void
*
reply
=
NULL
;
va_start
(
ap
,
format
);
len
=
redisvFormatCommand
(
&
cmd
,
format
,
ap
);
len
=
redisvFormatCommand
(
&
cmd
,
format
,
ap
);
reply
=
__redisCommand
(
c
,
cmd
,
len
);
free
(
cmd
);
return
reply
;
}
void
*
redisCommand
(
redisContext
*
c
,
const
char
*
format
,
...)
{
va_list
ap
;
void
*
reply
=
NULL
;
va_start
(
ap
,
format
);
reply
=
redisvCommand
(
c
,
format
,
ap
);
va_end
(
ap
);
va_end
(
ap
);
return
reply
;
}
if
(
c
->
flags
&
REDIS_BLOCK
)
{
void
*
redisCommandArgv
(
redisContext
*
c
,
int
argc
,
const
char
**
argv
,
const
size_t
*
argvlen
)
{
if
(
redisCommandWriteBlock
(
c
,
&
reply
,
cmd
,
len
)
==
REDIS_OK
)
{
char
*
cmd
;
int
len
;
void
*
reply
=
NULL
;
len
=
redisFormatCommandArgv
(
&
cmd
,
argc
,
argv
,
argvlen
);
reply
=
__redisCommand
(
c
,
cmd
,
len
);
free
(
cmd
);
free
(
cmd
);
return
reply
;
return
reply
;
}
}
else
{
redisCommandWriteNonBlock
(
c
,
cmd
,
len
);
}
free
(
cmd
);
return
NULL
;
}
}
hiredis.h
View file @
47e1f771
...
@@ -120,6 +120,11 @@ void redisDisconnect(redisContext *c);
...
@@ -120,6 +120,11 @@ void redisDisconnect(redisContext *c);
void
redisFree
(
redisContext
*
c
);
void
redisFree
(
redisContext
*
c
);
int
redisBufferRead
(
redisContext
*
c
);
int
redisBufferRead
(
redisContext
*
c
);
int
redisBufferWrite
(
redisContext
*
c
,
int
*
done
);
int
redisBufferWrite
(
redisContext
*
c
,
int
*
done
);
/* In a blocking context, this function first checks if there are unconsumed
* replies to return and returns one if so. Otherwise, it flushes the output
* buffer to the socket and reads until it has a reply. In a non-blocking
* context, it will return unconsumed replies until there are no more. */
int
redisGetReply
(
redisContext
*
c
,
void
**
reply
);
int
redisGetReply
(
redisContext
*
c
,
void
**
reply
);
/* The disconnect callback is called *immediately* when redisDisconnect()
/* The disconnect callback is called *immediately* when redisDisconnect()
...
@@ -136,11 +141,19 @@ void redisSetCommandCallback(redisContext *c, redisContextCallbackFn *fn, void *
...
@@ -136,11 +141,19 @@ void redisSetCommandCallback(redisContext *c, redisContextCallbackFn *fn, void *
* release resources that depend/use the redisContext that is being free'd. */
* release resources that depend/use the redisContext that is being free'd. */
void
redisSetFreeCallback
(
redisContext
*
c
,
redisContextCallbackFn
*
fn
,
void
*
privdata
);
void
redisSetFreeCallback
(
redisContext
*
c
,
redisContextCallbackFn
*
fn
,
void
*
privdata
);
/* Issue a command to Redis. In a blocking context, it returns the reply. When
/* Write a command to the output buffer. Use these functions in blocking mode
* an error occurs, it returns NULL and you should read redisContext->error
* to get a pipeline of commands. */
* to find out what's wrong. In a non-blocking context, it has the same effect
void
redisvAppendCommand
(
redisContext
*
c
,
const
char
*
format
,
va_list
ap
);
* as calling redisCommandWithCallback() with a NULL callback, and will always
void
redisAppendCommand
(
redisContext
*
c
,
const
char
*
format
,
...);
* return NULL. */
void
redisAppendCommandArgv
(
redisContext
*
c
,
int
argc
,
const
char
**
argv
,
const
size_t
*
argvlen
);
/* Issue a command to Redis. In a blocking context, it is identical to calling
* redisAppendCommand, followed by redisGetReply. The function will return
* NULL if there was an error in performing the request, otherwise it will
* return the reply. In a non-blocking context, it is identical to calling
* only redisAppendCommand and will always return NULL. */
void
*
redisvCommand
(
redisContext
*
c
,
const
char
*
format
,
va_list
ap
);
void
*
redisCommand
(
redisContext
*
c
,
const
char
*
format
,
...);
void
*
redisCommand
(
redisContext
*
c
,
const
char
*
format
,
...);
void
*
redisCommandArgv
(
redisContext
*
c
,
int
argc
,
const
char
**
argv
,
const
size_t
*
argvlen
);
#endif
#endif
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