+/* Large mget() of missing keys with binary proto
+ *
+ * If many binary quiet commands (such as getq's in an mget) fill the output
+ * buffer and the server chooses not to respond, memcached_flush hangs. See
+ * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
+ */
+
+/* sighandler_t function that always asserts false */
+static void fail(int unused __attribute__((unused)))
+{
+ assert(0);
+}
+
+
+static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
+{
+ memcached_return rc;
+ unsigned int x;
+ char **keys;
+ size_t* key_lengths;
+ void (*oldalarm)(int);
+ memcached_st *memc_clone;
+
+ memc_clone= memcached_clone(NULL, memc);
+ assert(memc_clone);
+
+ /* only binproto uses getq for mget */
+ memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
+
+ /* empty the cache to ensure misses (hence non-responses) */
+ rc= memcached_flush(memc_clone, 0);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ key_lengths= calloc(key_count, sizeof(size_t));
+ keys= calloc(key_count, sizeof(char *));
+ assert(keys);
+ for (x= 0; x < key_count; x++)
+ {
+ char buffer[30];
+
+ snprintf(buffer, 30, "%u", x);
+ keys[x]= strdup(buffer);
+ key_lengths[x]= strlen(keys[x]);
+ }
+
+ oldalarm= signal(SIGALRM, fail);
+ alarm(5);
+
+ rc= memcached_mget(memc_clone, (const char **)keys, key_lengths, key_count);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ alarm(0);
+ signal(SIGALRM, oldalarm);
+
+ assert(fetch_all_results(memc) == TEST_SUCCESS);
+
+ for (x= 0; x < key_count; x++)
+ free(keys[x]);
+ free(keys);
+ free(key_lengths);
+
+ memcached_free(memc_clone);
+
+ return TEST_SUCCESS;
+}
+
+static memcached_return pre_binary(memcached_st *memc);
+
+static test_return_t user_supplied_bug21(memcached_st *memc)
+{
+ if (pre_binary(memc) != MEMCACHED_SUCCESS)
+ return TEST_SKIPPED;
+
+ test_return_t rc;
+
+ /* should work as of r580 */
+ rc= _user_supplied_bug21(memc, 10);
+ assert(rc == TEST_SUCCESS);
+
+ /* should fail as of r580 */
+ rc= _user_supplied_bug21(memc, 1000);
+ assert(rc == TEST_SUCCESS);
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t auto_eject_hosts(memcached_st *trash)