diff options
-rw-r--r-- | CMakeLists.txt | 28 | ||||
-rw-r--r-- | async.c | 1 | ||||
-rw-r--r-- | hiredis.c | 15 | ||||
-rw-r--r-- | sds.c | 4 | ||||
-rw-r--r-- | test.c | 38 |
5 files changed, 69 insertions, 17 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b2e89a..a8dfaa9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,8 @@ PROJECT(hiredis VERSION "${VERSION}") # Hiredis requires C99 SET(CMAKE_C_STANDARD 99) +SET(CMAKE_POSITION_INDEPENDENT_CODE ON) +SET(CMAKE_DEBUG_POSTFIX d) SET(ENABLE_EXAMPLES OFF CACHE BOOL "Enable building hiredis examples") @@ -49,6 +51,10 @@ ADD_LIBRARY(hiredis_static STATIC ${hiredis_sources}) SET_TARGET_PROPERTIES(hiredis PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE VERSION "${HIREDIS_SONAME}") +SET_TARGET_PROPERTIES(hiredis_static + PROPERTIES COMPILE_PDB_NAME hiredis_static) +SET_TARGET_PROPERTIES(hiredis_static + PROPERTIES COMPILE_PDB_NAME_DEBUG hiredis_static${CMAKE_DEBUG_POSTFIX}) IF(WIN32 OR MINGW) TARGET_LINK_LIBRARIES(hiredis PUBLIC ws2_32 crypt32) TARGET_LINK_LIBRARIES(hiredis_static PUBLIC ws2_32 crypt32) @@ -91,6 +97,15 @@ INSTALL(TARGETS hiredis hiredis_static LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if (MSVC) + INSTALL(FILES $<TARGET_PDB_FILE:hiredis> + DESTINATION ${CMAKE_INSTALL_BINDIR} + CONFIGURATIONS Debug RelWithDebInfo) + INSTALL(FILES $<TARGET_FILE_DIR:hiredis_static>/$<TARGET_FILE_BASE_NAME:hiredis_static>.pdb + DESTINATION ${CMAKE_INSTALL_LIBDIR} + CONFIGURATIONS Debug RelWithDebInfo) +endif() + # For NuGet packages INSTALL(FILES hiredis.targets DESTINATION build/native) @@ -146,6 +161,10 @@ IF(ENABLE_SSL) PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE VERSION "${HIREDIS_SONAME}") + SET_TARGET_PROPERTIES(hiredis_ssl_static + PROPERTIES COMPILE_PDB_NAME hiredis_ssl_static) + SET_TARGET_PROPERTIES(hiredis_ssl_static + PROPERTIES COMPILE_PDB_NAME_DEBUG hiredis_ssl_static${CMAKE_DEBUG_POSTFIX}) TARGET_INCLUDE_DIRECTORIES(hiredis_ssl PRIVATE "${OPENSSL_INCLUDE_DIR}") TARGET_INCLUDE_DIRECTORIES(hiredis_ssl_static PRIVATE "${OPENSSL_INCLUDE_DIR}") @@ -163,6 +182,15 @@ IF(ENABLE_SSL) LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + if (MSVC) + INSTALL(FILES $<TARGET_PDB_FILE:hiredis_ssl> + DESTINATION ${CMAKE_INSTALL_BINDIR} + CONFIGURATIONS Debug RelWithDebInfo) + INSTALL(FILES $<TARGET_FILE_DIR:hiredis_ssl_static>/$<TARGET_FILE_BASE_NAME:hiredis_ssl_static>.pdb + DESTINATION ${CMAKE_INSTALL_LIBDIR} + CONFIGURATIONS Debug RelWithDebInfo) + endif() + INSTALL(FILES hiredis_ssl.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis) @@ -703,6 +703,7 @@ void redisAsyncHandleTimeout(redisAsyncContext *ac) { if (!c->err) { __redisSetError(c, REDIS_ERR_TIMEOUT, "Timeout"); + __redisAsyncCopyError(ac); } if (!(c->flags & REDIS_CONNECTED) && ac->onConnect) { @@ -257,7 +257,8 @@ static void *createNilObject(const redisReadTask *task) { parent = task->parent->obj; assert(parent->type == REDIS_REPLY_ARRAY || parent->type == REDIS_REPLY_MAP || - parent->type == REDIS_REPLY_SET); + parent->type == REDIS_REPLY_SET || + parent->type == REDIS_REPLY_PUSH); parent->element[task->idx] = r; } return r; @@ -938,13 +939,11 @@ int redisBufferRead(redisContext *c) { return REDIS_ERR; nread = c->funcs->read(c, buf, sizeof(buf)); - if (nread > 0) { - if (redisReaderFeed(c->reader, buf, nread) != REDIS_OK) { - __redisSetError(c, c->reader->err, c->reader->errstr); - return REDIS_ERR; - } else { - } - } else if (nread < 0) { + if (nread < 0) { + return REDIS_ERR; + } + if (nread > 0 && redisReaderFeed(c->reader, buf, nread) != REDIS_OK) { + __redisSetError(c, c->reader->err, c->reader->errstr); return REDIS_ERR; } return REDIS_OK; @@ -72,7 +72,7 @@ static inline char sdsReqType(size_t string_size) { * and 'initlen'. * If NULL is used for 'init' the string is initialized with zero bytes. * - * The string is always null-termined (all the sds strings are, always) so + * The string is always null-terminated (all the sds strings are, always) so * even if you create an sds string with: * * mystring = sdsnewlen("abc",3); @@ -415,7 +415,7 @@ sds sdscpylen(sds s, const char *t, size_t len) { return s; } -/* Like sdscpylen() but 't' must be a null-termined string so that the length +/* Like sdscpylen() but 't' must be a null-terminated string so that the length * of the string is obtained with strlen(). */ sds sdscpy(sds s, const char *t) { return sdscpylen(s, t, strlen(t)); @@ -53,6 +53,11 @@ struct privdata { int dtor_counter; }; +struct pushCounters { + int nil; + int str; +}; + #ifdef HIREDIS_TEST_SSL redisSSLContext *_ssl_ctx = NULL; #endif @@ -677,11 +682,25 @@ static void test_blocking_connection_errors(void) { #endif } -/* Dummy push handler */ -void push_handler(void *privdata, void *reply) { - int *counter = privdata; +/* Test push handler */ +void push_handler(void *privdata, void *r) { + struct pushCounters *pcounts = privdata; + redisReply *reply = r, *payload; + + assert(reply && reply->type == REDIS_REPLY_PUSH && reply->elements == 2); + + payload = reply->element[1]; + if (payload->type == REDIS_REPLY_ARRAY) { + payload = payload->element[0]; + } + + if (payload->type == REDIS_REPLY_STRING) { + pcounts->str++; + } else if (payload->type == REDIS_REPLY_NIL) { + pcounts->nil++; + } + freeReplyObject(reply); - *counter += 1; } /* Dummy function just to test setting a callback with redisOptions */ @@ -691,16 +710,16 @@ void push_handler_async(redisAsyncContext *ac, void *reply) { } static void test_resp3_push_handler(redisContext *c) { + struct pushCounters pc = {0}; redisPushFn *old = NULL; redisReply *reply; void *privdata; - int n = 0; /* Switch to RESP3 and turn on client tracking */ send_hello(c, 3); send_client_tracking(c, "ON"); privdata = c->privdata; - c->privdata = &n; + c->privdata = &pc; reply = redisCommand(c, "GET key:0"); assert(reply != NULL); @@ -717,7 +736,12 @@ static void test_resp3_push_handler(redisContext *c) { old = redisSetPushCallback(c, push_handler); test("We can set a custom RESP3 PUSH handler: "); reply = redisCommand(c, "SET key:0 val:0"); - test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && n == 1); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && pc.str == 1); + freeReplyObject(reply); + + test("We properly handle a NIL invalidation payload: "); + reply = redisCommand(c, "FLUSHDB"); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && pc.nil == 1); freeReplyObject(reply); /* Unset the push callback and generate an invalidate message making |