Change redisWriteBuffer to return OK on an empty buffer

This commit is contained in:
Pieter Noordhuis 2010-10-18 15:49:52 +02:00
parent a68cb9686e
commit e332a32b35
2 changed files with 50 additions and 18 deletions

View File

@ -714,25 +714,35 @@ int redisProcessCallbacks(redisContext *c) {
return REDIS_OK; return REDIS_OK;
} }
/* Use this function to try and write the entire output buffer to the /* Write the output buffer to the socket.
* descriptor. Returns 1 when the entire buffer was written, 0 otherwise. */ *
* Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
* succesfully written to the socket. When the buffer is empty after the
* write operation, "wdone" is set to 1 (if given).
*
* Returns REDIS_ERR if an error occured trying to write and sets
* c->error to hold the appropriate error string.
*/
int redisBufferWrite(redisContext *c, int *done) { int redisBufferWrite(redisContext *c, int *done) {
int nwritten = write(c->fd,c->obuf,sdslen(c->obuf)); int nwritten;
if (nwritten == -1) { if (sdslen(c->obuf) > 0) {
if (errno == EAGAIN) { nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
/* Try again later */ if (nwritten == -1) {
} else { if (errno == EAGAIN) {
/* Set error in context */ /* Try again later */
c->error = sdscatprintf(sdsempty(), } else {
"write: %s", strerror(errno)); /* Set error in context */
return REDIS_ERR; c->error = sdscatprintf(sdsempty(),
} "write: %s", strerror(errno));
} else if (nwritten > 0) { return REDIS_ERR;
if (nwritten == (signed)sdslen(c->obuf)) { }
sdsfree(c->obuf); } else if (nwritten > 0) {
c->obuf = sdsempty(); if (nwritten == (signed)sdslen(c->obuf)) {
} else { sdsfree(c->obuf);
c->obuf = sdsrange(c->obuf,nwritten,-1); c->obuf = sdsempty();
} else {
c->obuf = sdsrange(c->obuf,nwritten,-1);
}
} }
} }
if (done != NULL) *done = (sdslen(c->obuf) == 0); if (done != NULL) *done = (sdslen(c->obuf) == 0);

22
test.c
View File

@ -4,6 +4,7 @@
#include <strings.h> #include <strings.h>
#include <sys/time.h> #include <sys/time.h>
#include <assert.h> #include <assert.h>
#include <unistd.h>
#include "hiredis.h" #include "hiredis.h"
@ -203,6 +204,7 @@ static void __test_callback(redisContext *c, const void *privdata) {
static void test_nonblocking_connection() { static void test_nonblocking_connection() {
redisContext *c; redisContext *c;
int wdone = 0;
__test_callback_flags = 0; __test_callback_flags = 0;
test("Calls command callback when command is issued: "); test("Calls command callback when command is issued: ");
@ -227,6 +229,26 @@ static void test_nonblocking_connection() {
redisSetFreeCallback(c,__test_callback,(const void*)4); redisSetFreeCallback(c,__test_callback,(const void*)4);
redisFree(c); redisFree(c);
test_cond(__test_callback_flags == ((2 << 8) | 4)); test_cond(__test_callback_flags == ((2 << 8) | 4));
test("redisBufferWrite against empty write buffer: ");
c = redisConnectNonBlock("127.0.0.1", 6379, NULL);
test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1);
redisFree(c);
test("redisBufferWrite against not yet connected fd: ");
c = redisConnectNonBlock("127.0.0.1", 6379, NULL);
redisCommand(c,"PING");
test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
strncmp(c->error,"write:",6) == 0);
redisFree(c);
test("redisBufferWrite against closed fd: ");
c = redisConnectNonBlock("127.0.0.1", 6379, NULL);
redisCommand(c,"PING");
redisDisconnect(c);
test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
strncmp(c->error,"write:",6) == 0);
redisFree(c);
} }
int main(void) { int main(void) {