Skip to content

Commit 9f88736

Browse files
committed
fix #76: get returns NOTFOUND on TIMEOUT
1 parent 4b7c2c7 commit 9f88736

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

src/libmemcached/fetch.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr, memcached_result_
141141
memcached_instance_st *server;
142142
memcached_return_t read_ret = MEMCACHED_SUCCESS;
143143
bool connection_failures = false;
144+
bool timeouts = false;
144145
while ((server = memcached_io_get_readable_server(ptr, read_ret))) {
145146
char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
146147
*error = memcached_response(server, buffer, sizeof(buffer), result);
@@ -150,6 +151,8 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr, memcached_result_
150151
} else if (*error == MEMCACHED_CONNECTION_FAILURE) {
151152
connection_failures = true;
152153
continue;
154+
} else if (*error == MEMCACHED_TIMEOUT) {
155+
timeouts = true;
153156
} else if (*error == MEMCACHED_SUCCESS) {
154157
result->count++;
155158
return result;
@@ -175,6 +178,8 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr, memcached_result_
175178
that.
176179
*/
177180
*error = MEMCACHED_CONNECTION_FAILURE;
181+
} else if (timeouts) {
182+
*error = MEMCACHED_TIMEOUT;
178183
} else if (*error == MEMCACHED_SUCCESS) {
179184
*error = MEMCACHED_END;
180185
} else if (result->count == 0) {

test/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ if(NOT MEMCACHED_BINARY)
4545
set(ENV{INVALID_CONFIGURATION} 1)
4646
endif()
4747

48+
add_executable(timeout timeout.c)
49+
4850
file(GLOB_RECURSE TESTING_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
4951
set(TESTING_ROOT "${CMAKE_CURRENT_BINARY_DIR}")
5052
set(SOURCES_ROOT "${CMAKE_SOURCE_DIR}")
@@ -66,7 +68,7 @@ if(NOT (thread IN_LIST ENABLE_SANITIZERS))
6668
endif()
6769
endif()
6870

69-
add_dependencies(runtests ${CLIENTS})
71+
add_dependencies(runtests ${CLIENTS} timeout)
7072
if(TARGET memaslap)
7173
configure_set(HAVE_MEMASLAP 1)
7274
add_dependencies(runtests memaslap)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "test/lib/common.hpp"
2+
#include "test/lib/random.hpp"
3+
#include "test/lib/Server.hpp"
4+
#include "test/lib/ReturnMatcher.hpp"
5+
6+
TEST_CASE("memcached_regression_lp1540680") {
7+
Server timeout{TESTING_ROOT "/timeout", {"-p", random_port_string}};
8+
MemcachedPtr memc;
9+
LoneReturnMatcher test{*memc};
10+
11+
REQUIRE(timeout.start());
12+
this_thread::sleep_for(500ms);
13+
14+
REQUIRE_SUCCESS(memcached_server_add(*memc, "localhost", get<int>(timeout.getSocketOrPort())));
15+
16+
memcached_return_t rc;
17+
Malloced val(memcached_get(*memc, S("not-found"), nullptr, nullptr, &rc));
18+
REQUIRE_RC(MEMCACHED_TIMEOUT, rc);
19+
REQUIRE_FALSE(*val);
20+
}

test/timeout.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <unistd.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <memory.h>
5+
#include <arpa/inet.h>
6+
#include <sys/socket.h>
7+
8+
// $0 -u nobody -p <port>
9+
int main(int argc, char **argv) {
10+
short port = argc == 5 ? atoi(argv[4]) : 11211;
11+
struct sockaddr_in servaddr;
12+
memset(&servaddr, 0, sizeof(struct sockaddr_in));
13+
14+
servaddr.sin_family = AF_INET;
15+
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
16+
servaddr.sin_port = htons(port);
17+
18+
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
19+
bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
20+
listen(listen_fd, 10);
21+
printf("Listening (%d) on port %d\n", listen_fd, port);
22+
23+
int comm_fd = accept(listen_fd, NULL, NULL);
24+
printf("Connection (%d) accepted, now do nothing...\n", comm_fd);
25+
26+
pause();
27+
}

0 commit comments

Comments
 (0)