From 3ebac1ab74b47f394862412d629f825275249e41 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 27 Oct 2020 17:36:26 +0100 Subject: [PATCH] fix #95 --- ChangeLog-1.1.md | 2 ++ src/libmemcached/get.cc | 10 +++++++--- test/fixtures/callbacks.hpp | 2 +- test/lib/ReturnMatcher.cpp | 8 +++++++- test/lib/ReturnMatcher.hpp | 6 +++--- test/tests/memcached/callbacks.cpp | 32 ++++++++++++++++++++---------- 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/ChangeLog-1.1.md b/ChangeLog-1.1.md index 46540555..6cd72b1f 100644 --- a/ChangeLog-1.1.md +++ b/ChangeLog-1.1.md @@ -100,6 +100,8 @@ was incremented due to the following changes: [gh #64](https://github.com/m6w6/libmemcached/issues/64) and [gh #21](https://github.com/m6w6/libmemcached/issues/21): clarify documentation on replication. +* Fix [gh #95](https://github.com/m6w6/libmemcached/issues/95): + MEMCACHED_CALLBACK_GET_FAILURE and MEMCACHED_BEHAVIOR_BUFFER_REQUESTS --- diff --git a/src/libmemcached/get.cc b/src/libmemcached/get.cc index 93330f45..4dd88061 100644 --- a/src/libmemcached/get.cc +++ b/src/libmemcached/get.cc @@ -98,8 +98,12 @@ char *memcached_get_by_key(memcached_st *shell, const char *group_key, size_t gr if (rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED) { *error = rc; - *value_length = memcached_result_length(result_ptr); - *flags = memcached_result_flags(result_ptr); + if (value_length) { + *value_length = memcached_result_length(result_ptr); + } + if (flags) { + *flags = memcached_result_flags(result_ptr); + } char *result_value = memcached_string_take_value(&result_ptr->value); memcached_result_free(result_ptr); @@ -178,7 +182,7 @@ static memcached_return_t __mget_by_key_real(memcached_st *ptr, const char *grou if (instance->response_count()) { char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - if (ptr->flags.no_block) { + if (ptr->flags.no_block || ptr->flags.buffer_requests) { memcached_io_write(instance); } diff --git a/test/fixtures/callbacks.hpp b/test/fixtures/callbacks.hpp index 5e01c4b4..6ccb4ff8 100644 --- a/test/fixtures/callbacks.hpp +++ b/test/fixtures/callbacks.hpp @@ -49,7 +49,7 @@ static inline memcached_return_t delete_trigger(memcached_st *, const char *, si return MEMCACHED_SUCCESS; } -static inline memcached_return_t read_through_trigger(memcached_st *, char *, size_t, +static inline memcached_return_t get_failure(memcached_st *, char *, size_t, memcached_result_st *result) { return memcached_result_set_value(result, S("updated by read through trigger")); } diff --git a/test/lib/ReturnMatcher.cpp b/test/lib/ReturnMatcher.cpp index cbc9a95b..926214e7 100644 --- a/test/lib/ReturnMatcher.cpp +++ b/test/lib/ReturnMatcher.cpp @@ -1,7 +1,13 @@ #include "ReturnMatcher.hpp" bool ReturnMatcher::match(const memcached_return_t &arg) const { - return arg == expected; + if (arg != expected) { + if (expected == MEMCACHED_SUCCESS && arg == MEMCACHED_BUFFERED && memc) { + return memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS); + } + return false; + } + return true; } ReturnMatcher ReturnMatcher::success() { diff --git a/test/lib/ReturnMatcher.hpp b/test/lib/ReturnMatcher.hpp index f50212c4..f95eb2f3 100644 --- a/test/lib/ReturnMatcher.hpp +++ b/test/lib/ReturnMatcher.hpp @@ -19,7 +19,7 @@ class ReturnMatcher : public Catch::MatcherBase { public: - explicit ReturnMatcher(const memcached_st *memc_, + explicit ReturnMatcher(memcached_st *memc_, memcached_return_t expected_ = MEMCACHED_SUCCESS) : memc{memc_} , expected{expected_} {} @@ -35,13 +35,13 @@ protected: string describe() const override; private: - const memcached_st *memc; + memcached_st *memc; memcached_return_t expected{MEMCACHED_SUCCESS}; }; class LoneReturnMatcher { public: ReturnMatcher returns; - explicit LoneReturnMatcher(const memcached_st *memc) + explicit LoneReturnMatcher(memcached_st *memc) : returns{memc} {} }; diff --git a/test/tests/memcached/callbacks.cpp b/test/tests/memcached/callbacks.cpp index 1fc20ef6..625698b6 100644 --- a/test/tests/memcached/callbacks.cpp +++ b/test/tests/memcached/callbacks.cpp @@ -30,25 +30,37 @@ TEST_CASE("memcached_callbacks") { } SECTION("get_failure callback") { - void *gptr = reinterpret_cast(reinterpret_cast(&read_through_trigger)); + void *gptr = reinterpret_cast(reinterpret_cast(&get_failure)); Malloced empty(memcached_get(memc, S(__func__), nullptr, nullptr, &rc)); REQUIRE_FALSE(*empty); REQUIRE_RC(MEMCACHED_NOTFOUND, rc); - REQUIRE_SUCCESS(memcached_callback_set(memc, MEMCACHED_CALLBACK_GET_FAILURE, gptr)); - REQUIRE(gptr == memcached_callback_get(memc, MEMCACHED_CALLBACK_GET_FAILURE, &rc)); - REQUIRE_SUCCESS(rc); + uint64_t buffering = GENERATE(0, 1); + + DYNAMIC_SECTION("buffering: " << buffering) { + REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, buffering)); + REQUIRE_SUCCESS(memcached_callback_set(memc, MEMCACHED_CALLBACK_GET_FAILURE, gptr)); + REQUIRE(gptr == memcached_callback_get(memc, MEMCACHED_CALLBACK_GET_FAILURE, &rc)); + REQUIRE_SUCCESS(rc); - for (int twice = 0; twice < 2; ++twice) { - uint32_t flags; - size_t len; - Malloced val(memcached_get(memc, S(__func__), &len, &flags, &rc)); + for (int twice = 0; twice < 2; ++twice) { + uint32_t flags; + size_t len; + Malloced val(memcached_get(memc, S(__func__), &len, &flags, &rc)); + REQUIRE_SUCCESS(rc); + REQUIRE(string("updated by read through trigger") == string(*val, len)); + REQUIRE_FALSE((*val)[len]); + } + + REQUIRE_SUCCESS(memcached_set(memc, S(__func__), S("changed"), 0, 0)); + memcached_quit(memc); + Malloced val(memcached_get(memc, S(__func__), nullptr, nullptr, &rc)); REQUIRE_SUCCESS(rc); - REQUIRE(string("updated by read through trigger") == string(*val, len)); - REQUIRE_FALSE((*val)[len]); + REQUIRE("changed"s == *val); } } + SECTION("clone callback") { void *cptr = reinterpret_cast(reinterpret_cast(&clone_callback)); -- 2.30.2