#include <sys/types.h>
#include <unistd.h>
-#include <libmemcached/memcached.h>
+#include <libmemcached-1.0/memcached.h>
+#include <libmemcached/close_socket.hpp>
#include <libmemcached/memcached/protocol_binary.h>
#include <libmemcached/byteorder.h>
#include <clients/utilities.h>
if (flags == -1)
{
perror("Failed to get socket flags");
- closesocket(sock);
+ memcached_close_socket(sock);
return INVALID_SOCKET;
}
if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1)
{
perror("Failed to set socket to nonblocking mode");
- closesocket(sock);
+ memcached_close_socket(sock);
return INVALID_SOCKET;
}
}
#include <event.h>
#include <libmemcachedprotocol-0.0/handler.h>
+#include <libmemcached/close_socket.hpp>
#include <example/byteorder.h>
-#include "storage.h"
-#include "memcached_light.h"
+#include "example/storage.h"
+#include "example/memcached_light.h"
extern memcached_binary_protocol_callback_st interface_v0_impl;
extern memcached_binary_protocol_callback_st interface_v1_impl;
/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#ifndef STORAGE_H
-#define STORAGE_H
+#pragma once
struct item {
uint64_t cas;
bool delete_item(const void* key, size_t nkey);
void flush(uint32_t when);
void release_item(struct item* item);
-
-#endif
if (getsockopt(instance->fd, SOL_SOCKET, SO_SNDBUF, &sock_size, &sock_length) < 0)
{
- memcached_set_errno(*ptr, errno, MEMCACHED_AT);
+ memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
return 0; /* Zero means error */
}
}
if (getsockopt(instance->fd, SOL_SOCKET, SO_RCVBUF, &sock_size, &sock_length) < 0)
{
- memcached_set_errno(*ptr, errno, MEMCACHED_AT);
+ memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
return 0; /* Zero means error */
}
-
}
return (uint64_t) sock_size;
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * LibMemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * Copyright (C) 2006-2009 Brian Aker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+
+/* To hide the platform differences between MS Windows and Unix, I am
+ * going to use the Microsoft way and #define the Microsoft-specific
+ * functions to the unix way. Microsoft use a separate subsystem for sockets,
+ * but Unix normally just use a filedescriptor on the same functions. It is
+ * a lot easier to map back to the unix way with macros than going the other
+ * way without side effect ;-)
+ */
+#ifdef WIN32
+#include "win32/wrappers.h"
+#define get_socket_errno() WSAGetLastError()
+#else
+#define INVALID_SOCKET -1
+#define SOCKET_ERROR -1
+#define closesocket(a) close(a)
+#define get_socket_errno() errno
+#endif
+
+#ifdef __cplusplus
+static inline void memcached_close_socket(int& socket_fd)
+{
+ closesocket(socket_fd);
+ socket_fd= INVALID_SOCKET;
+}
+#endif
+
+#ifndef HAVE_MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
+#ifndef HAVE_MSG_DONTWAIT
+#define MSG_DONTWAIT 0
+#endif
+
+#ifndef HAVE_MSG_MORE
+#define MSG_MORE 0
+#endif
+
+
#include <libmemcached/string.hpp>
#include <libmemcached/io.hpp>
#include <libmemcached/do.hpp>
+#include <libmemcached/close_socket.hpp>
#endif
#include <libmemcached/internal.h>
#include <libmemcached/array.h>
{
int err;
socklen_t len= sizeof (err);
- (void)getsockopt(server->fd, SOL_SOCKET, SO_ERROR, &err, &len);
-
- // We check the value to see what happened wth the socket.
- if (err == 0)
+ if (getsockopt(server->fd, SOL_SOCKET, SO_ERROR, &err, &len) == 0)
{
- return MEMCACHED_SUCCESS;
+ // We check the value to see what happened wth the socket.
+ if (err == 0)
+ {
+ return MEMCACHED_SUCCESS;
+ }
+ errno= err;
}
return memcached_set_errno(*server, err, MEMCACHED_AT);
if (fds[0].revents & POLLERR)
{
int err;
- socklen_t len= sizeof (err);
- (void)getsockopt(server->fd, SOL_SOCKET, SO_ERROR, &err, &len);
- memcached_set_errno(*server, (err == 0) ? get_socket_errno() : err, MEMCACHED_AT);
- }
- else
- {
- memcached_set_errno(*server, get_socket_errno(), MEMCACHED_AT);
+ socklen_t len= sizeof(err);
+ if (getsockopt(server->fd, SOL_SOCKET, SO_ERROR, &err, &len) == 0)
+ {
+ if (err == 0)
+ {
+ // This should never happen, if it does? Punt.
+ continue;
+ }
+ errno= err;
+ }
}
+ int local_errno= get_socket_errno(); // We cache in case closesocket() modifies errno
+
assert_msg(server->fd != INVALID_SOCKET, "poll() was passed an invalid file descriptor");
(void)closesocket(server->fd);
server->fd= INVALID_SOCKET;
server->state= MEMCACHED_SERVER_STATE_NEW;
- return memcached_set_errno(*server, get_socket_errno(), MEMCACHED_AT);
+ return memcached_set_errno(*server, local_errno, MEMCACHED_AT);
}
}
}
return;
}
- memcached_set_parser_error(*memc, MEMCACHED_AT, "%s", last_token_str ? last_token_str : " ");
+ if (last_token_str)
+ {
+ memcached_set_parser_error(*memc, MEMCACHED_AT, "%s", last_token_str);
+ return;
+ }
+
+ memcached_set_parser_error(*memc, MEMCACHED_AT, "unknown parsing error");
}
void Context::error(const char *error_arg, yytokentype last_token, const char *last_token_str)
return _hostname;
}
+bool Context::set_hash(memcached_hash_t hash)
+{
+ if (_has_hash)
+ {
+ return false;
+ }
+
+ if ((memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, hash)) != MEMCACHED_SUCCESS)
+ {
+ return false;
+ }
+
+ return _has_hash= true;
+}
memc(NULL),
rc(rc_arg),
_is_server(false),
- _end(false)
+ _end(false),
+ _has_hash(false)
{
_hostname[0]= 0;
buf= option_string;
_end= true;
}
+ bool set_hash(memcached_hash_t hash);
+
void set_server()
{
_is_server= true;
_is_server= false;
}
- bool is_server()
+ bool is_server() const
{
return _is_server;
}
const char *set_hostname(const char *str, size_t size);
- const char *hostname()
+ const char *hostname() const
{
return _hostname;
}
bool _is_server;
bool _end;
char _hostname[NI_MAXHOST];
+ bool _has_hash;
};
static const yytype_uint16 yyrline[] =
{
0, 172, 172, 173, 177, 179, 181, 183, 188, 193,
- 197, 201, 212, 220, 228, 235, 239, 243, 247, 251,
- 263, 270, 281, 288, 295, 302, 308, 312, 316, 320,
- 324, 328, 332, 336, 340, 344, 348, 352, 359, 363,
- 367, 371, 375, 379, 383, 387, 391, 395, 399, 403,
- 410, 411, 416, 417, 422, 426, 430, 434, 438, 442,
- 446, 450, 454, 461, 465, 472, 476, 480
+ 197, 201, 212, 222, 232, 241, 245, 249, 253, 257,
+ 269, 282, 295, 302, 309, 318, 324, 328, 332, 336,
+ 340, 344, 348, 352, 356, 360, 364, 368, 375, 379,
+ 383, 387, 391, 395, 399, 403, 407, 411, 415, 419,
+ 426, 427, 432, 433, 438, 442, 446, 450, 454, 458,
+ 462, 466, 470, 477, 481, 488, 492, 496
};
#endif
#line 189 "libmemcached/csl/parser.yy"
{
context->rc= MEMCACHED_PARSE_USER_ERROR;
- parser_abort(context, NULL);
+ parser_abort(context, "ERROR called directly");
}
break;
{
if ((context->rc= memcached_parse_configure_file(*context->memc, (yyvsp[(3) - (3)].string).c_str, (yyvsp[(3) - (3)].string).size)) != MEMCACHED_SUCCESS)
{
- parser_abort(context, NULL);
+ parser_abort(context, "Failed to parse configuration file");
}
}
break;
{
if (memcached_failed(context->rc= memcached_server_add_with_weight(context->memc, (yyvsp[(2) - (4)].server).c_str, (yyvsp[(3) - (4)].number), (yyvsp[(4) - (4)].number))))
{
- parser_abort(context, NULL);
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "Failed to add server: %s:%u", (yyvsp[(2) - (4)].server).c_str, uint32_t((yyvsp[(3) - (4)].number)));
+ parser_abort(context, buffer);
}
context->unset_server();
}
case 13:
/* Line 1806 of yacc.c */
-#line 221 "libmemcached/csl/parser.yy"
+#line 223 "libmemcached/csl/parser.yy"
{
if (memcached_failed(context->rc= memcached_server_add_with_weight(context->memc, (yyvsp[(2) - (4)].server).c_str, (yyvsp[(3) - (4)].number), (yyvsp[(4) - (4)].number))))
{
- parser_abort(context, NULL);
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "Failed to add server: %s:%u", (yyvsp[(2) - (4)].server).c_str, uint32_t((yyvsp[(3) - (4)].number)));
+ parser_abort(context, buffer);
}
context->unset_server();
}
case 14:
/* Line 1806 of yacc.c */
-#line 229 "libmemcached/csl/parser.yy"
+#line 233 "libmemcached/csl/parser.yy"
{
if (memcached_failed(context->rc= memcached_server_add_unix_socket_with_weight(context->memc, (yyvsp[(2) - (3)].string).c_str, (yyvsp[(3) - (3)].number))))
{
- parser_abort(context, NULL);
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "Failed to add server: %s", (yyvsp[(2) - (3)].string).c_str);
+ parser_abort(context, buffer);
}
}
break;
case 15:
/* Line 1806 of yacc.c */
-#line 236 "libmemcached/csl/parser.yy"
+#line 242 "libmemcached/csl/parser.yy"
{
memcached_set_configuration_file(context->memc, (yyvsp[(2) - (2)].string).c_str, (yyvsp[(2) - (2)].string).size);
}
case 16:
/* Line 1806 of yacc.c */
-#line 240 "libmemcached/csl/parser.yy"
+#line 246 "libmemcached/csl/parser.yy"
{
context->memc->configure.initial_pool_size= (yyvsp[(2) - (2)].number);
}
case 17:
/* Line 1806 of yacc.c */
-#line 244 "libmemcached/csl/parser.yy"
+#line 250 "libmemcached/csl/parser.yy"
{
context->memc->configure.max_pool_size= (yyvsp[(2) - (2)].number);
}
case 19:
/* Line 1806 of yacc.c */
-#line 252 "libmemcached/csl/parser.yy"
+#line 258 "libmemcached/csl/parser.yy"
{
if (memcached_callback_get(context->memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL))
{
case 20:
/* Line 1806 of yacc.c */
-#line 264 "libmemcached/csl/parser.yy"
+#line 270 "libmemcached/csl/parser.yy"
{
+ // Check to see if DISTRIBUTION has already been set
+ if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, (yyvsp[(2) - (2)].distribution))) != MEMCACHED_SUCCESS)
+ {
+ parser_abort(context, "--DISTRIBUTION can only be called once");
+ }
+
if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, (yyvsp[(2) - (2)].distribution))) != MEMCACHED_SUCCESS)
{
parser_abort(context, memcached_last_error_message(context->memc));;
case 21:
/* Line 1806 of yacc.c */
-#line 271 "libmemcached/csl/parser.yy"
+#line 283 "libmemcached/csl/parser.yy"
{
+ // Check to see if DISTRIBUTION has already been set
if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, (yyvsp[(2) - (4)].distribution))) != MEMCACHED_SUCCESS)
{
- parser_abort(context, NULL);
+ parser_abort(context, "--DISTRIBUTION can only be called once");
}
+
if ((context->rc= memcached_behavior_set_distribution_hash(context->memc, (yyvsp[(4) - (4)].hash))) != MEMCACHED_SUCCESS)
{
- parser_abort(context, NULL);
+ parser_abort(context, "Unable to set the hash for the DISTRIBUTION requested");
}
}
break;
case 22:
/* Line 1806 of yacc.c */
-#line 282 "libmemcached/csl/parser.yy"
+#line 296 "libmemcached/csl/parser.yy"
{
- if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_HASH, (yyvsp[(2) - (2)].hash))) != MEMCACHED_SUCCESS)
+ if (context->set_hash((yyvsp[(2) - (2)].hash)) == false)
{
- parser_abort(context, NULL);
+ parser_abort(context, "--HASH can only be set once");
}
}
break;
case 23:
/* Line 1806 of yacc.c */
-#line 289 "libmemcached/csl/parser.yy"
+#line 303 "libmemcached/csl/parser.yy"
{
if ((context->rc= memcached_behavior_set(context->memc, (yyvsp[(1) - (2)].behavior), (yyvsp[(2) - (2)].number))) != MEMCACHED_SUCCESS)
{
- parser_abort(context, NULL);
+ parser_abort(context, "Unable to set behavior");
}
}
break;
case 24:
/* Line 1806 of yacc.c */
-#line 296 "libmemcached/csl/parser.yy"
+#line 310 "libmemcached/csl/parser.yy"
{
if ((context->rc= memcached_behavior_set(context->memc, (yyvsp[(1) - (1)].behavior), true)) != MEMCACHED_SUCCESS)
{
- parser_abort(context, NULL);
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "Could not set: %s", libmemcached_string_behavior((yyvsp[(1) - (1)].behavior)));
+ parser_abort(context, buffer);
}
}
break;
case 25:
/* Line 1806 of yacc.c */
-#line 303 "libmemcached/csl/parser.yy"
+#line 319 "libmemcached/csl/parser.yy"
{
}
break;
case 26:
/* Line 1806 of yacc.c */
-#line 309 "libmemcached/csl/parser.yy"
+#line 325 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS;
}
case 27:
/* Line 1806 of yacc.c */
-#line 313 "libmemcached/csl/parser.yy"
+#line 329 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT;
}
case 28:
/* Line 1806 of yacc.c */
-#line 317 "libmemcached/csl/parser.yy"
+#line 333 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK;
}
case 29:
/* Line 1806 of yacc.c */
-#line 321 "libmemcached/csl/parser.yy"
+#line 337 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK;
}
case 30:
/* Line 1806 of yacc.c */
-#line 325 "libmemcached/csl/parser.yy"
+#line 341 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH;
}
case 31:
/* Line 1806 of yacc.c */
-#line 329 "libmemcached/csl/parser.yy"
+#line 345 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS;
}
case 32:
/* Line 1806 of yacc.c */
-#line 333 "libmemcached/csl/parser.yy"
+#line 349 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_POLL_TIMEOUT;
}
case 33:
/* Line 1806 of yacc.c */
-#line 337 "libmemcached/csl/parser.yy"
+#line 353 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_RCV_TIMEOUT;
}
case 34:
/* Line 1806 of yacc.c */
-#line 341 "libmemcached/csl/parser.yy"
+#line 357 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_RETRY_TIMEOUT;
}
case 35:
/* Line 1806 of yacc.c */
-#line 345 "libmemcached/csl/parser.yy"
+#line 361 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_SND_TIMEOUT;
}
case 36:
/* Line 1806 of yacc.c */
-#line 349 "libmemcached/csl/parser.yy"
+#line 365 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE;
}
case 37:
/* Line 1806 of yacc.c */
-#line 353 "libmemcached/csl/parser.yy"
+#line 369 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE;
}
case 38:
/* Line 1806 of yacc.c */
-#line 360 "libmemcached/csl/parser.yy"
+#line 376 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_BINARY_PROTOCOL;
}
case 39:
/* Line 1806 of yacc.c */
-#line 364 "libmemcached/csl/parser.yy"
+#line 380 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_BUFFER_REQUESTS;
}
case 40:
/* Line 1806 of yacc.c */
-#line 368 "libmemcached/csl/parser.yy"
+#line 384 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY;
}
case 41:
/* Line 1806 of yacc.c */
-#line 372 "libmemcached/csl/parser.yy"
+#line 388 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_NOREPLY;
}
case 42:
/* Line 1806 of yacc.c */
-#line 376 "libmemcached/csl/parser.yy"
+#line 392 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ;
}
case 43:
/* Line 1806 of yacc.c */
-#line 380 "libmemcached/csl/parser.yy"
+#line 396 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_SORT_HOSTS;
}
case 44:
/* Line 1806 of yacc.c */
-#line 384 "libmemcached/csl/parser.yy"
+#line 400 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_SUPPORT_CAS;
}
case 45:
/* Line 1806 of yacc.c */
-#line 388 "libmemcached/csl/parser.yy"
+#line 404 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_TCP_NODELAY;
}
case 46:
/* Line 1806 of yacc.c */
-#line 392 "libmemcached/csl/parser.yy"
+#line 408 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_TCP_KEEPALIVE;
}
case 47:
/* Line 1806 of yacc.c */
-#line 396 "libmemcached/csl/parser.yy"
+#line 412 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_TCP_KEEPIDLE;
}
case 48:
/* Line 1806 of yacc.c */
-#line 400 "libmemcached/csl/parser.yy"
+#line 416 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_USE_UDP;
}
case 49:
/* Line 1806 of yacc.c */
-#line 404 "libmemcached/csl/parser.yy"
+#line 420 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_VERIFY_KEY;
}
case 50:
/* Line 1806 of yacc.c */
-#line 410 "libmemcached/csl/parser.yy"
+#line 426 "libmemcached/csl/parser.yy"
{ (yyval.number)= MEMCACHED_DEFAULT_PORT;}
break;
case 51:
/* Line 1806 of yacc.c */
-#line 412 "libmemcached/csl/parser.yy"
+#line 428 "libmemcached/csl/parser.yy"
{ }
break;
case 52:
/* Line 1806 of yacc.c */
-#line 416 "libmemcached/csl/parser.yy"
+#line 432 "libmemcached/csl/parser.yy"
{ (yyval.number)= 1; }
break;
case 53:
/* Line 1806 of yacc.c */
-#line 418 "libmemcached/csl/parser.yy"
+#line 434 "libmemcached/csl/parser.yy"
{ }
break;
case 54:
/* Line 1806 of yacc.c */
-#line 423 "libmemcached/csl/parser.yy"
+#line 439 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_MD5;
}
case 55:
/* Line 1806 of yacc.c */
-#line 427 "libmemcached/csl/parser.yy"
+#line 443 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_CRC;
}
case 56:
/* Line 1806 of yacc.c */
-#line 431 "libmemcached/csl/parser.yy"
+#line 447 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_FNV1_64;
}
case 57:
/* Line 1806 of yacc.c */
-#line 435 "libmemcached/csl/parser.yy"
+#line 451 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_FNV1A_64;
}
case 58:
/* Line 1806 of yacc.c */
-#line 439 "libmemcached/csl/parser.yy"
+#line 455 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_FNV1_32;
}
case 59:
/* Line 1806 of yacc.c */
-#line 443 "libmemcached/csl/parser.yy"
+#line 459 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_FNV1A_32;
}
case 60:
/* Line 1806 of yacc.c */
-#line 447 "libmemcached/csl/parser.yy"
+#line 463 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_HSIEH;
}
case 61:
/* Line 1806 of yacc.c */
-#line 451 "libmemcached/csl/parser.yy"
+#line 467 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_MURMUR;
}
case 62:
/* Line 1806 of yacc.c */
-#line 455 "libmemcached/csl/parser.yy"
+#line 471 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_JENKINS;
}
case 63:
/* Line 1806 of yacc.c */
-#line 462 "libmemcached/csl/parser.yy"
+#line 478 "libmemcached/csl/parser.yy"
{
(yyval.string)= (yyvsp[(1) - (1)].string);
}
case 64:
/* Line 1806 of yacc.c */
-#line 466 "libmemcached/csl/parser.yy"
+#line 482 "libmemcached/csl/parser.yy"
{
(yyval.string)= (yyvsp[(1) - (1)].string);
}
case 65:
/* Line 1806 of yacc.c */
-#line 473 "libmemcached/csl/parser.yy"
+#line 489 "libmemcached/csl/parser.yy"
{
(yyval.distribution)= MEMCACHED_DISTRIBUTION_CONSISTENT;
}
case 66:
/* Line 1806 of yacc.c */
-#line 477 "libmemcached/csl/parser.yy"
+#line 493 "libmemcached/csl/parser.yy"
{
(yyval.distribution)= MEMCACHED_DISTRIBUTION_MODULA;
}
case 67:
/* Line 1806 of yacc.c */
-#line 481 "libmemcached/csl/parser.yy"
+#line 497 "libmemcached/csl/parser.yy"
{
(yyval.distribution)= MEMCACHED_DISTRIBUTION_RANDOM;
}
/* Line 1806 of yacc.c */
-#line 2156 "libmemcached/csl/parser.cc"
+#line 2172 "libmemcached/csl/parser.cc"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
/* Line 2067 of yacc.c */
-#line 486 "libmemcached/csl/parser.yy"
+#line 502 "libmemcached/csl/parser.yy"
void Context::start()
| ERROR
{
context->rc= MEMCACHED_PARSE_USER_ERROR;
- parser_abort(context, NULL);
+ parser_abort(context, "ERROR called directly");
}
| RESET
{
{
if ((context->rc= memcached_parse_configure_file(*context->memc, $3.c_str, $3.size)) != MEMCACHED_SUCCESS)
{
- parser_abort(context, NULL);
+ parser_abort(context, "Failed to parse configuration file");
}
}
;
{
if (memcached_failed(context->rc= memcached_server_add_with_weight(context->memc, $2.c_str, $3, $4)))
{
- parser_abort(context, NULL);
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "Failed to add server: %s:%u", $2.c_str, uint32_t($3));
+ parser_abort(context, buffer);
}
context->unset_server();
}
{
if (memcached_failed(context->rc= memcached_server_add_with_weight(context->memc, $2.c_str, $3, $4)))
{
- parser_abort(context, NULL);
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "Failed to add server: %s:%u", $2.c_str, uint32_t($3));
+ parser_abort(context, buffer);
}
context->unset_server();
}
{
if (memcached_failed(context->rc= memcached_server_add_unix_socket_with_weight(context->memc, $2.c_str, $3)))
{
- parser_abort(context, NULL);
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "Failed to add server: %s", $2.c_str);
+ parser_abort(context, buffer);
}
}
| CONFIGURE_FILE string
}
| DISTRIBUTION distribution
{
+ // Check to see if DISTRIBUTION has already been set
+ if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $2)) != MEMCACHED_SUCCESS)
+ {
+ parser_abort(context, "--DISTRIBUTION can only be called once");
+ }
+
if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $2)) != MEMCACHED_SUCCESS)
{
parser_abort(context, memcached_last_error_message(context->memc));;
}
| DISTRIBUTION distribution ',' hash
{
+ // Check to see if DISTRIBUTION has already been set
if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $2)) != MEMCACHED_SUCCESS)
{
- parser_abort(context, NULL);
+ parser_abort(context, "--DISTRIBUTION can only be called once");
}
+
if ((context->rc= memcached_behavior_set_distribution_hash(context->memc, $4)) != MEMCACHED_SUCCESS)
{
- parser_abort(context, NULL);
+ parser_abort(context, "Unable to set the hash for the DISTRIBUTION requested");
}
}
| HASH hash
{
- if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_HASH, $2)) != MEMCACHED_SUCCESS)
+ if (context->set_hash($2) == false)
{
- parser_abort(context, NULL);
+ parser_abort(context, "--HASH can only be set once");
}
}
| behavior_number NUMBER
{
if ((context->rc= memcached_behavior_set(context->memc, $1, $2)) != MEMCACHED_SUCCESS)
{
- parser_abort(context, NULL);
+ parser_abort(context, "Unable to set behavior");
}
}
| behavior_boolean
{
if ((context->rc= memcached_behavior_set(context->memc, $1, true)) != MEMCACHED_SUCCESS)
{
- parser_abort(context, NULL);
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "Could not set: %s", libmemcached_string_behavior($1));
+ parser_abort(context, buffer);
}
}
| USER_DATA
libmemcached/byteorder.h \
libmemcached/common.h \
libmemcached/continuum.hpp \
+ libmemcached/close_socket.hpp \
libmemcached/do.hpp \
libmemcached/error.hpp \
libmemcached/initialize_query.h \
{
int err;
socklen_t len= sizeof (err);
- (void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
- memcached_set_errno(*ptr, (err == 0) ? get_socket_errno() : err, MEMCACHED_AT);
+ if (getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len) == 0)
+ {
+ if (err == 0)
+ {
+ continue;
+ }
+ errno= err;
+ }
}
else
{
memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
}
+ int local_errno= get_socket_errno(); // We cache in case memcached_quit_server() modifies errno
memcached_quit_server(ptr, true);
- return memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
+ return memcached_set_errno(*ptr, local_errno, MEMCACHED_AT);
}
}
}
#include <libmemcachedprotocol-0.0/handler.h>
#include <libmemcachedprotocol/cache.h>
#include <libmemcached/byteorder.h>
+#include <libmemcached/close_socket.hpp>
/*
* I don't really need the following two functions as function pointers
#include "util/string.hpp"
#define test_literal_param util_literal_param
+#define test_literal_compare_param util_literal_compare_param
#define test_literal_param_size util_literal_param_size
#define test_string_make_from_cstr util_string_make_from_cstr
#define test_array_length util_array_length
{
test_true(container);
test_true(container->memc);
- return func(container->memc);
+ test_return_t ret;
+ try {
+ ret= func(container->memc);
+ }
+ catch (std::exception& e)
+ {
+ Error << e.what();
+ return TEST_FAILURE;
+ }
+
+ return ret;
}
return TEST_SUCCESS;
{ ARRAY, make_scanner_string("--HASH=CRC"), scanner_string_null, NULL },
{ ARRAY, make_scanner_string("--HASH=FNV1A_32"), scanner_string_null, NULL },
{ ARRAY, make_scanner_string("--HASH=FNV1_32"), scanner_string_null, NULL },
+#if 0
{ ARRAY, make_scanner_string("--HASH=JENKINS"), scanner_string_null, NULL },
+#endif
{ ARRAY, make_scanner_string("--HASH=MD5"), scanner_string_null, NULL },
{ NIL, scanner_string_null, scanner_string_null, NULL}
};
for (scanner_variable_t *ptr= scanner; ptr->type != NIL; ptr++)
{
memcached_st *memc= memcached(ptr->option.c_str, ptr->option.size);
-
- // The case that it should have parsed, but it didn't. We will inspect
- // for an error with libmemcached_check_configuration()
- if (not memc and test_true_opt)
+
+ // The case that it should have parsed, but it didn't. We will inspect for
+ // an error with libmemcached_check_configuration()
+ if (memc == NULL and test_true_opt)
{
char buffer[2048];
bool success= libmemcached_check_configuration(ptr->option.c_str, ptr->option.size, buffer, sizeof(buffer));
temp+= " with option string:";
temp+= ptr->option.c_str;
test_true_got(success, temp.c_str());
+ Error << "Failed for " << temp;
return TEST_FAILURE; // The line above should fail since memc should be null
}
test_return_t memcached_create_with_options_with_filename(memcached_st*)
{
- if (access(SUPPORT_EXAMPLE_CNF, R_OK))
- return TEST_SKIPPED;
+ test_skip(0, access(SUPPORT_EXAMPLE_CNF, R_OK));
- memcached_st *memc_ptr;
- memc_ptr= memcached(test_literal_param("--CONFIGURE-FILE=\"support/example.cnf\""));
+ memcached_st *memc_ptr= memcached(test_literal_param("--CONFIGURE-FILE=\"support/example.cnf\""));
test_true_got(memc_ptr, "memcached() failed");
memcached_free(memc_ptr);
test_return_t libmemcached_check_configuration_with_filename_test(memcached_st*)
{
- if (access(SUPPORT_EXAMPLE_CNF, R_OK))
- return TEST_SKIPPED;
+ test_skip(0, access(SUPPORT_EXAMPLE_CNF, R_OK));
- memcached_return_t rc;
char buffer[BUFSIZ];
- rc= libmemcached_check_configuration(test_literal_param("--CONFIGURE-FILE=\"support/example.cnf\""), buffer, sizeof(buffer));
- test_true_got(rc == MEMCACHED_SUCCESS, (rc == MEMCACHED_ERRNO) ? strerror(errno) : memcached_strerror(NULL, rc));
+ test_compare_hint(MEMCACHED_SUCCESS,
+ libmemcached_check_configuration(test_literal_param("--CONFIGURE-FILE=\"support/example.cnf\""), buffer, sizeof(buffer)),
+ buffer);
- rc= libmemcached_check_configuration(test_literal_param("--CONFIGURE-FILE=support/example.cnf"), buffer, sizeof(buffer));
- test_false_with(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
+ test_compare_hint(MEMCACHED_SUCCESS,
+ libmemcached_check_configuration(test_literal_param("--CONFIGURE-FILE=support/example.cnf"), buffer, sizeof(buffer)),
+ buffer);
- rc= libmemcached_check_configuration(test_literal_param("--CONFIGURE-FILE=\"bad-path/example.cnf\""), buffer, sizeof(buffer));
- test_true_got(rc == MEMCACHED_ERRNO, memcached_strerror(NULL, rc));
+ test_compare_hint(MEMCACHED_ERRNO,
+ libmemcached_check_configuration(test_literal_param("--CONFIGURE-FILE=\"bad-path/example.cnf\""), buffer, sizeof(buffer)),
+ buffer) ;
return TEST_SUCCESS;
}
test_return_t libmemcached_check_configuration_test(memcached_st*)
{
- memcached_return_t rc;
char buffer[BUFSIZ];
-
test_compare(MEMCACHED_SUCCESS,
libmemcached_check_configuration(test_literal_param("--server=localhost"), buffer, sizeof(buffer)));
- rc= libmemcached_check_configuration(test_literal_param("--dude=localhost"), buffer, sizeof(buffer));
- test_false_with(rc == MEMCACHED_SUCCESS, buffer);
- test_true(rc == MEMCACHED_PARSE_ERROR);
+ test_compare_hint(MEMCACHED_PARSE_ERROR,
+ libmemcached_check_configuration(test_literal_param("--dude=localhost"), buffer, sizeof(buffer)),
+ buffer);
return TEST_SUCCESS;
}
test_return_t memcached_create_with_options_test(memcached_st*)
{
- memcached_st *memc_ptr;
- memc_ptr= memcached(test_literal_param("--server=localhost"));
- test_true_got(memc_ptr, memcached_last_error_message(memc_ptr));
- memcached_free(memc_ptr);
+ {
+ memcached_st *memc_ptr;
+ memc_ptr= memcached(test_literal_param("--server=localhost"));
+ test_true_got(memc_ptr, memcached_last_error_message(memc_ptr));
+ memcached_free(memc_ptr);
+ }
- memc_ptr= memcached(test_literal_param("--dude=localhost"));
- test_false_with(memc_ptr, memcached_last_error_message(memc_ptr));
+ {
+ memcached_st *memc_ptr= memcached(test_literal_param("--dude=localhost"));
+ test_false_with(memc_ptr, memcached_last_error_message(memc_ptr));
+ }
return TEST_SUCCESS;
}
test_return_t test_include_keyword(memcached_st*)
{
- if (access(SUPPORT_EXAMPLE_CNF, R_OK))
- return TEST_SKIPPED;
+ test_skip(0, access(SUPPORT_EXAMPLE_CNF, R_OK));
char buffer[BUFSIZ];
test_compare(MEMCACHED_SUCCESS,
return TEST_SUCCESS;
}
-#define RANDOM_STRINGS 100
+#define RANDOM_STRINGS 1000
test_return_t random_statement_build_test(memcached_st*)
{
std::vector<scanner_string_st *> option_list;
for (scanner_variable_t *ptr= hash_strings; ptr->type != NIL; ptr++)
option_list.push_back(&ptr->option);
- bool seen_namespace= false;
+ std::vector<bool> used_list;
+ used_list.resize(option_list.size());
+
+ struct used_options_st {
+ bool has_hash;
+ bool has_namespace;
+ bool has_distribution;
+ bool has_buffer_requests;
+ bool has_udp;
+
+ used_options_st() :
+ has_hash(false),
+ has_namespace(false),
+ has_distribution(false),
+ has_buffer_requests(false),
+ has_udp(false)
+ {
+ }
+ } used_options;
+
for (uint32_t x= 0; x < RANDOM_STRINGS; x++)
{
std::string random_options;
uint32_t number_of= random() % option_list.size();
for (uint32_t options= 0; options < number_of; options++)
{
- std::string random_string= option_list[random() % option_list.size()]->c_str;
- bool is_namespace= memcmp(random_string.c_str(), test_literal_param("--NAMESPACE")) == 0;
+ size_t option_list_position= random() % option_list.size();
- if (is_namespace and seen_namespace)
+ if (used_list[option_list_position])
{
continue;
}
+ used_list[option_list_position]= true;
+
+ std::string random_string= option_list[option_list_position]->c_str;
+
+ if (random_string.compare(0, test_literal_compare_param("--HASH")) == 0)
+ {
+ if (used_options.has_hash)
+ {
+ continue;
+ }
+
+ if (used_options.has_distribution)
+ {
+ continue;
+ }
+ used_options.has_hash= true;
+ }
+
+ if (random_string.compare(0, test_literal_compare_param("--NAMESPACE")) == 0)
+ {
+ if (used_options.has_namespace)
+ {
+ continue;
+ }
+ used_options.has_namespace= true;
+ }
- if (is_namespace)
+ if (random_string.compare(0, test_literal_compare_param("--USE-UDP")) == 0)
{
- seen_namespace= true;
+ if (used_options.has_udp)
+ {
+ continue;
+ }
+ used_options.has_udp= true;
+
+ if (used_options.has_buffer_requests)
+ {
+ continue;
+ }
+ }
+
+ if (random_string.compare(0, test_literal_compare_param("--BUFFER-REQUESTS")) == 0)
+ {
+ if (used_options.has_buffer_requests)
+ {
+ continue;
+ }
+ used_options.has_buffer_requests= true;
+
+ if (used_options.has_udp)
+ {
+ continue;
+ }
+ }
+
+ if (random_string.compare(0, test_literal_compare_param("--DISTRIBUTION")) == 0)
+ {
+ if (used_options.has_distribution)
+ {
+ continue;
+ }
+
+ if (used_options.has_hash)
+ {
+ continue;
+ }
+ used_options.has_distribution= true;
}
random_options+= random_string;
continue;
}
- char buffer[BUFSIZ];
- memcached_return_t rc= libmemcached_check_configuration(random_options.c_str(), random_options.size() -1, buffer, sizeof(buffer));
+ random_options.resize(random_options.size() -1);
+ char buffer[BUFSIZ];
+ memcached_return_t rc= libmemcached_check_configuration(random_options.c_str(), random_options.size(), buffer, sizeof(buffer));
if (memcached_failed(rc))
{
Error << "libmemcached_check_configuration(" << random_options << ") : " << buffer;
#define util_literal_param(X) (X), (static_cast<size_t>((sizeof(X) - 1)))
#define util_literal_param_size(X) static_cast<size_t>(sizeof(X) - 1)
+#define util_literal_compare_param(X) (static_cast<size_t>((sizeof(X) - 1))), (X)
+
#define util_string_make_from_cstr(X) (X), ((X) ? strlen(X) : 0)
#define util_array_length(__array) sizeof(__array)/sizeof(&__array)