Skip to content

Commit

Permalink
REDIS for Window using Libuv
Browse files Browse the repository at this point in the history
  • Loading branch information
sophiebits committed Dec 8, 2011
1 parent 3fac86f commit 809c231
Show file tree
Hide file tree
Showing 55 changed files with 4,735 additions and 290 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
@@ -0,0 +1,3 @@
[submodule "deps/libuv"]
path = deps/libuv
url = https://github.com/spicyj/libuv.git
9 changes: 8 additions & 1 deletion deps/hiredis/async.c
Expand Up @@ -30,14 +30,21 @@
*/

#include <string.h>
#ifndef _WIN32
#include <strings.h>
#endif
#include <assert.h>
#include <ctype.h>
#include "async.h"
#include "dict.c"
#include "sds.h"
#include "util.h"

#ifdef _WIN32
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#endif

/* Forward declaration of function in hiredis.c */
void __redisAppendCommand(redisContext *c, char *cmd, size_t len);

Expand All @@ -47,8 +54,8 @@ static unsigned int callbackHash(const void *key) {
}

static void *callbackValDup(void *privdata, const void *src) {
((void) privdata);
redisCallback *dup = malloc(sizeof(*dup));
((void) privdata);
memcpy(dup,src,sizeof(*dup));
return dup;
}
Expand Down
17 changes: 17 additions & 0 deletions deps/hiredis/example.c
Expand Up @@ -2,12 +2,29 @@
#include <stdlib.h>
#include <string.h>

#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
#endif

#include "hiredis.h"

int main(void) {
unsigned int j;
redisContext *c;
redisReply *reply;
#ifdef _WIN32
WSADATA t_wsa;
WORD wVers = MAKEWORD(2, 2); // Set the version number to 2.2
int iError = WSAStartup(wVers, &t_wsa);

if(iError != NO_ERROR || LOBYTE(t_wsa.wVersion) != 2 || HIBYTE(t_wsa.wVersion) != 2 ) {
printf("Winsock2 init error: %d\n", iError);
exit(1);
}

atexit((void(*)(void)) WSACleanup);
#endif

struct timeval timeout = { 1, 500000 }; // 1.5 seconds
c = redisConnectWithTimeout((char*)"127.0.0.2", 6379, timeout);
Expand Down
81 changes: 79 additions & 2 deletions deps/hiredis/hiredis.c
Expand Up @@ -31,7 +31,9 @@

#include <string.h>
#include <stdlib.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <assert.h>
#include <errno.h>
#include <ctype.h>
Expand All @@ -41,6 +43,15 @@
#include "sds.h"
#include "util.h"

#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
#endif

#ifdef _WIN32
#define va_copy(d,s) d = (s)
#endif

typedef struct redisReader {
struct redisReplyObjectFunctions *fn;
sds error; /* holds optional error */
Expand Down Expand Up @@ -596,7 +607,7 @@ static int intlen(int i) {
/* Helper function for redisvFormatCommand(). */
static void addArgument(sds a, char ***argv, int *argc, int *totlen) {
(*argc)++;
if ((*argv = realloc(*argv, sizeof(char*)*(*argc))) == NULL) redisOOM();
if ((*argv = (char **)realloc(*argv, sizeof(char*)*(*argc))) == NULL) redisOOM();
if (totlen) *totlen = *totlen+1+intlen(sdslen(a))+2+sdslen(a)+2;
(*argv)[(*argc)-1] = a;
}
Expand Down Expand Up @@ -697,7 +708,11 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
}

/* Consume and discard vararg */
#ifdef _WIN32
va_arg(ap,void*);
#else
va_arg(ap,void);
#endif
}
}
touched = 1;
Expand All @@ -717,11 +732,15 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
totlen += 1+intlen(argc)+2;

/* Build the command at protocol level */
cmd = malloc(totlen+1);
cmd = (char*)malloc(totlen+1);
if (!cmd) redisOOM();
pos = sprintf(cmd,"*%d\r\n",argc);
for (j = 0; j < argc; j++) {
#ifdef _WIN32
pos += sprintf(cmd+pos,"$%llu\r\n",(unsigned long long)sdslen(argv[j]));
#else
pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(argv[j]));
#endif
memcpy(cmd+pos,argv[j],sdslen(argv[j]));
pos += sdslen(argv[j]);
sdsfree(argv[j]);
Expand Down Expand Up @@ -780,7 +799,11 @@ int redisFormatCommandArgv(char **target, int argc, const char **argv, const siz
pos = sprintf(cmd,"*%d\r\n",argc);
for (j = 0; j < argc; j++) {
len = argvlen ? argvlen[j] : strlen(argv[j]);
#ifdef _WIN32
pos += sprintf(cmd+pos,"$%llu\r\n",(unsigned long long)len);
#else
pos += sprintf(cmd+pos,"$%zu\r\n",len);
#endif
memcpy(cmd+pos,argv[j],len);
pos += len;
cmd[pos++] = '\r';
Expand Down Expand Up @@ -815,7 +838,11 @@ static redisContext *redisContextInit(void) {

void redisFree(redisContext *c) {
if (c->fd > 0)
#ifdef _WIN32
closesocket(c->fd);
#else
close(c->fd);
#endif
if (c->errstr != NULL)
sdsfree(c->errstr);
if (c->obuf != NULL)
Expand Down Expand Up @@ -870,6 +897,21 @@ redisContext *redisConnectUnixNonBlock(const char *path) {
return c;
}

/* initializers if caller handles connection */
redisContext *redisConnected() {
redisContext *c = redisContextInit();
c->fd = -1;
c->flags |= REDIS_BLOCK;
return c;
}

redisContext *redisConnectedNonBlock() {
redisContext *c = redisContextInit();
c->fd = -1;
c->flags &= ~REDIS_BLOCK;
return c;
}

/* Set read/write timeout on a blocking socket. */
int redisSetTimeout(redisContext *c, struct timeval tv) {
if (c->flags & REDIS_BLOCK)
Expand Down Expand Up @@ -902,7 +944,16 @@ static void __redisCreateReplyReader(redisContext *c) {
* see if there is a reply available. */
int redisBufferRead(redisContext *c) {
char buf[2048];
#ifdef _WIN32
int nread = recv((SOCKET)c->fd,buf,sizeof(buf),0);
if (nread == -1) {
errno = WSAGetLastError();
if ((errno == ENOENT) || (errno == WSAEWOULDBLOCK))
errno = EAGAIN;
}
#else
int nread = read(c->fd,buf,sizeof(buf));
#endif
if (nread == -1) {
if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
/* Try again later */
Expand All @@ -921,6 +972,23 @@ int redisBufferRead(redisContext *c) {
return REDIS_OK;
}

/* Use this function if the caller has already read the data. It will
* feed bytes to the reply parser.
*
* After this function is called, you may use redisContextReadReply to
* see if there is a reply available. */
int redisBufferReadDone(redisContext *c, char *buf, int nread) {
if (nread == 0) {
__redisSetError(c,REDIS_ERR_EOF,
sdsnew("Server closed the connection"));
return REDIS_ERR;
} else {
__redisCreateReplyReader(c);
redisReplyReaderFeed(c->reader,buf,nread);
}
return REDIS_OK;
}

/* Write the output buffer to the socket.
*
* Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
Expand All @@ -933,7 +1001,16 @@ int redisBufferRead(redisContext *c) {
int redisBufferWrite(redisContext *c, int *done) {
int nwritten;
if (sdslen(c->obuf) > 0) {
#ifdef _WIN32
nwritten = send((SOCKET)c->fd,c->obuf,sdslen(c->obuf),0);
if (nwritten == -1) {
errno = WSAGetLastError();
if ((errno == ENOENT) || (errno == WSAEWOULDBLOCK))
errno = EAGAIN;
}
#else
nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
#endif
if (nwritten == -1) {
if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
/* Try again later */
Expand Down
13 changes: 13 additions & 0 deletions deps/hiredis/hiredis.h
Expand Up @@ -33,7 +33,13 @@
#define __HIREDIS_H
#include <stdio.h> /* for size_t */
#include <stdarg.h> /* for va_list */
#ifndef _WIN32
#include <sys/time.h> /* for struct timeval */
#endif
#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
#endif

#define HIREDIS_MAJOR 0
#define HIREDIS_MINOR 9
Expand Down Expand Up @@ -117,7 +123,11 @@ struct redisContext; /* need forward declaration of redisContext */

/* Context for a connection to Redis */
typedef struct redisContext {
#ifdef _WIN32
SOCKET fd;
#else
int fd;
#endif
int flags;
char *obuf; /* Write buffer */
int err; /* Error flags, 0 when there is no error */
Expand Down Expand Up @@ -149,10 +159,13 @@ redisContext *redisConnectNonBlock(const char *ip, int port);
redisContext *redisConnectUnix(const char *path);
redisContext *redisConnectUnixWithTimeout(const char *path, struct timeval tv);
redisContext *redisConnectUnixNonBlock(const char *path);
redisContext *redisConnected();
redisContext *redisConnectedNonBlock();
int redisSetTimeout(redisContext *c, struct timeval tv);
int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn);
void redisFree(redisContext *c);
int redisBufferRead(redisContext *c);
int redisBufferReadDone(redisContext *c, char *buf, int nread);
int redisBufferWrite(redisContext *c, int *done);

/* In a blocking context, this function first checks if there are unconsumed
Expand Down

0 comments on commit 809c231

Please sign in to comment.