Created
August 24, 2013 23:30
-
-
Save ablyler/6331007 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/memcached-2.1.0/ChangeLog b/memcached-2.1.0/ChangeLog | |
index 9a7280d..3502e19 100644 | |
--- a/memcached-2.1.0/ChangeLog | |
+++ b/memcached-2.1.0/ChangeLog | |
@@ -41,8 +41,6 @@ Version 2.0.0b2 | |
Version 2.0.0b1 | |
--------------- | |
- * Change the return value for non-existing keys to be NULL rather than | |
- 'false', affects simple get only | |
* Add fastlz library that provides better/faster payload compression | |
* Add configure switch to enable/disable JSON serialization support | |
* Add getAllKeys() method | |
diff --git a/memcached-2.1.0/README.markdown b/memcached-2.1.0/README.markdown | |
index 7a8041e..aaad096 100644 | |
--- a/memcached-2.1.0/README.markdown | |
+++ b/memcached-2.1.0/README.markdown | |
@@ -1,3 +1,8 @@ | |
+2012 Holidays | |
+------------- | |
+Committers' wishlists, if you feel like kicking in towards a gift: | |
+ * [Andrei's](http://given.to/profile/andreiz/wishlist/1411) | |
+ | |
Description | |
----------- | |
This extension uses libmemcached library to provide API for communicating with | |
@@ -7,8 +12,15 @@ memcached is a high-performance, distributed memory object caching system, | |
generic in nature, but intended for use in speeding up dynamic web applications | |
by alleviating database load. | |
+Building | |
+-------- | |
+$ phpize | |
+$ ./configure | |
+$ make | |
+$ make test | |
+ | |
Resources | |
--------- | |
* [libmemcached](http://tangent.org/552/libmemcached.html) | |
* [memcached](http://www.danga.com/memcached/) | |
- * [igbinary](http://opensource.dynamoid.com/) | |
+ * [igbinary](https://github.com/phadej/igbinary/) | |
diff --git a/memcached-2.1.0/memcached-api.php b/memcached-2.1.0/memcached-api.php | |
index 7552295..d7085c4 100644 | |
--- a/memcached-2.1.0/memcached-api.php | |
+++ b/memcached-2.1.0/memcached-api.php | |
@@ -53,6 +53,8 @@ class Memcached { | |
const OPT_RETRY_TIMEOUT; | |
+ const OPT_DEAD_TIMEOUT; | |
+ | |
const OPT_SND_TIMEOUT; | |
const OPT_RCV_TIMEOUT; | |
@@ -257,6 +259,14 @@ class Memcached { | |
public function getServerByKey( $server_key ) {} | |
+ public function getLastErrorMessage( ) {} | |
+ | |
+ public function getLastErrorCode( ) {} | |
+ | |
+ public function getLastErrorErrno( ) {} | |
+ | |
+ public function getLastDisconnectedServer( ) {} | |
+ | |
public function flush( $delay = 0 ) {} | |
public function getStats( ) {} | |
@@ -271,6 +281,8 @@ class Memcached { | |
public function isPristine( ) {} | |
+ public function setSaslAuthData( $username, $password ) {} | |
+ | |
} | |
class MemcachedException extends Exception { | |
diff --git a/memcached-2.1.0/memcached.ini b/memcached-2.1.0/memcached.ini | |
index cc11b25..7c16dde 100644 | |
--- a/memcached-2.1.0/memcached.ini | |
+++ b/memcached-2.1.0/memcached.ini | |
@@ -17,9 +17,38 @@ memcached.sess_lock_wait = 150000 | |
; the default value is "memc.sess.key." | |
memcached.sess_prefix = "memc.sess.key." | |
+; memcached session consistent hash mode | |
+; if set to On, consistent hashing (libketama) is used | |
+; for session handling. | |
+; When consistent hashing is used, one can add or remove cache | |
+; node(s) without messing up too much with existing keys | |
+; default is Off | |
+memcached.sess_consistent_hash = Off | |
+ | |
+; Allow failed memcached server to automatically be removed | |
+memcached.sess_remove_failed = 1 | |
+ | |
+; Write data to a number of additional memcached servers | |
+; This is "poor man's HA" as libmemcached calls it. | |
+; If this value is positive and sess_remove_failed is enabled | |
+; when a memcached server fails the session will continue to be available | |
+; from a replica. However, if the failed memcache server | |
+; becomes available again it will read the session from there | |
+; which could have old data or no data at all | |
+memcached.sess_number_of_replicas = 0 | |
+ | |
; memcached session binary mode | |
+; libmemcached replicas only work if binary mode is enabled | |
memcached.sess_binary = Off | |
+; memcached session replica read randomize | |
+memcached.sess_randomize_replica_read = Off | |
+ | |
+; memcached connect timeout value | |
+; In non-blocking mode this changes the value of the timeout | |
+; during socket connection in milliseconds. Specifying -1 means an infinite timeout. | |
+memcached.sess_connect_timeout = 1000 | |
+ | |
; Set the compression type | |
; valid values are: fastlz, zlib | |
; the default is fastlz | |
@@ -55,3 +84,7 @@ memcached.compression_threshold = 2000 | |
; The default is igbinary if available and php otherwise. | |
memcached.serializer = "igbinary" | |
+; Use SASL authentication for connections | |
+; valid values: On, Off | |
+; the default is Off | |
+memcached.use_sasl = Off | |
diff --git a/memcached-2.1.0/php_memcached.c b/memcached-2.1.0/php_memcached.c | |
index 90ea8ab..2023e10 100644 | |
--- a/memcached-2.1.0/php_memcached.c | |
+++ b/memcached-2.1.0/php_memcached.c | |
@@ -89,6 +89,10 @@ typedef unsigned long int uint32_t; | |
# include "ext/igbinary/igbinary.h" | |
#endif | |
+#if !defined(LIBMEMCACHED_VERSION_HEX) || LIBMEMCACHED_VERSION_HEX < 0x01000002 | |
+#error "Too old libmemcached version" | |
+#endif | |
+ | |
/* | |
* This is needed because PHP 5.3.[01] does not install JSON_parser.h by default. This | |
* constant will move into php_json.h in the future anyway. | |
@@ -264,7 +268,7 @@ static PHP_INI_MH(OnUpdateSerializer) | |
MEMC_G(serializer) = SERIALIZER_DEFAULT; | |
} else if (!strcmp(new_value, "php")) { | |
MEMC_G(serializer) = SERIALIZER_PHP; | |
-#ifdef HAVE_MEMCACHE_IGBINARY | |
+#ifdef HAVE_MEMCACHED_IGBINARY | |
} else if (!strcmp(new_value, "igbinary")) { | |
MEMC_G(serializer) = SERIALIZER_IGBINARY; | |
#endif // IGBINARY | |
@@ -285,9 +289,15 @@ static PHP_INI_MH(OnUpdateSerializer) | |
PHP_INI_BEGIN() | |
#ifdef HAVE_MEMCACHED_SESSION | |
STD_PHP_INI_ENTRY("memcached.sess_locking", "1", PHP_INI_ALL, OnUpdateBool, sess_locking_enabled, zend_php_memcached_globals, php_memcached_globals) | |
+ STD_PHP_INI_ENTRY("memcached.sess_consistent_hash", "0", PHP_INI_ALL, OnUpdateBool, sess_consistent_hash_enabled, zend_php_memcached_globals, php_memcached_globals) | |
STD_PHP_INI_ENTRY("memcached.sess_binary", "0", PHP_INI_ALL, OnUpdateBool, sess_binary_enabled, zend_php_memcached_globals, php_memcached_globals) | |
STD_PHP_INI_ENTRY("memcached.sess_lock_wait", "150000", PHP_INI_ALL, OnUpdateLongGEZero,sess_lock_wait, zend_php_memcached_globals, php_memcached_globals) | |
STD_PHP_INI_ENTRY("memcached.sess_prefix", "memc.sess.key.", PHP_INI_ALL, OnUpdateString, sess_prefix, zend_php_memcached_globals, php_memcached_globals) | |
+ | |
+ STD_PHP_INI_ENTRY("memcached.sess_number_of_replicas", "0", PHP_INI_ALL, OnUpdateLongGEZero, sess_number_of_replicas, zend_php_memcached_globals, php_memcached_globals) | |
+ STD_PHP_INI_ENTRY("memcached.sess_randomize_replica_read", "0", PHP_INI_ALL, OnUpdateBool, sess_randomize_replica_read, zend_php_memcached_globals, php_memcached_globals) | |
+ STD_PHP_INI_ENTRY("memcached.sess_remove_failed", "0", PHP_INI_ALL, OnUpdateBool, sess_remove_failed_enabled, zend_php_memcached_globals, php_memcached_globals) | |
+ STD_PHP_INI_ENTRY("memcached.sess_connect_timeout", "1000", PHP_INI_ALL, OnUpdateLong, sess_connect_timeout, zend_php_memcached_globals, php_memcached_globals) | |
#endif | |
STD_PHP_INI_ENTRY("memcached.compression_type", "fastlz", PHP_INI_ALL, OnUpdateCompressionType, compression_type, zend_php_memcached_globals, php_memcached_globals) | |
STD_PHP_INI_ENTRY("memcached.compression_factor", "1.3", PHP_INI_ALL, OnUpdateReal, compression_factor, zend_php_memcached_globals, php_memcached_globals) | |
@@ -303,7 +313,7 @@ PHP_INI_END() | |
/**************************************** | |
Forward declarations | |
****************************************/ | |
-static int php_memc_handle_error(php_memc_t *i_obj, memcached_return status TSRMLS_DC); | |
+static int php_memc_handle_error(php_memc_t *i_obj, memcached_return_t status TSRMLS_DC); | |
static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t *flags, enum memcached_serializer serializer, enum memcached_compression_type compression_type TSRMLS_DC); | |
static int php_memc_zval_from_payload(zval *value, char *payload, size_t payload_len, uint32_t flags, enum memcached_serializer serializer TSRMLS_DC); | |
static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); | |
@@ -313,11 +323,17 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke | |
static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); | |
static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); | |
static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); | |
-static memcached_return php_memc_do_cache_callback(zval *memc_obj, zend_fcall_info *fci, zend_fcall_info_cache *fcc, char *key, size_t key_len, zval *value TSRMLS_DC); | |
+static memcached_return_t php_memc_do_cache_callback(zval *memc_obj, zend_fcall_info *fci, zend_fcall_info_cache *fcc, char *key, size_t key_len, zval *value TSRMLS_DC); | |
static int php_memc_do_result_callback(zval *memc_obj, zend_fcall_info *fci, zend_fcall_info_cache *fcc, memcached_result_st *result TSRMLS_DC); | |
-static memcached_return php_memc_do_serverlist_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context); | |
-static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context); | |
-static memcached_return php_memc_do_version_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context); | |
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009 | |
+static memcached_return_t php_memc_do_serverlist_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context); | |
+static memcached_return_t php_memc_do_stats_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context); | |
+static memcached_return_t php_memc_do_version_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context); | |
+#else | |
+static memcached_return_t php_memc_do_serverlist_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context); | |
+static memcached_return_t php_memc_do_stats_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context); | |
+static memcached_return_t php_memc_do_version_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context); | |
+#endif | |
static void php_memc_destroy(struct memc_obj *m_obj, zend_bool persistent TSRMLS_DC); | |
/**************************************** | |
@@ -518,7 +534,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) | |
zend_fcall_info fci = empty_fcall_info; | |
zend_fcall_info_cache fcc = empty_fcall_info_cache; | |
memcached_result_st result; | |
- memcached_return status = MEMCACHED_SUCCESS; | |
+ memcached_return_t status = MEMCACHED_SUCCESS; | |
MEMC_METHOD_INIT_VARS; | |
if (by_key) { | |
@@ -631,7 +647,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) | |
if (payload == NULL && status == MEMCACHED_NOTFOUND && fci.size != 0) { | |
size_t dummy_length; | |
uint32_t dummy_flags; | |
- memcached_return dummy_status; | |
+ memcached_return_t dummy_status; | |
status = php_memc_do_cache_callback(getThis(), &fci, &fcc, key, key_len, | |
return_value TSRMLS_CC); | |
@@ -700,7 +716,7 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke | |
int i = 0; | |
zend_bool preserve_order; | |
memcached_result_st result; | |
- memcached_return status = MEMCACHED_SUCCESS; | |
+ memcached_return_t status = MEMCACHED_SUCCESS; | |
MEMC_METHOD_INIT_VARS; | |
if (by_key) { | |
@@ -875,7 +891,7 @@ static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ | |
zend_fcall_info fci = empty_fcall_info; | |
zend_fcall_info_cache fcc = empty_fcall_info_cache; | |
int i = 0; | |
- memcached_return status = MEMCACHED_SUCCESS; | |
+ memcached_return_t status = MEMCACHED_SUCCESS; | |
MEMC_METHOD_INIT_VARS; | |
if (by_key) { | |
@@ -994,7 +1010,7 @@ PHP_METHOD(Memcached, fetch) | |
uint32_t flags = 0; | |
uint64_t cas = 0; | |
memcached_result_st result; | |
- memcached_return status = MEMCACHED_SUCCESS; | |
+ memcached_return_t status = MEMCACHED_SUCCESS; | |
MEMC_METHOD_INIT_VARS; | |
if (zend_parse_parameters_none() == FAILURE) { | |
@@ -1051,7 +1067,7 @@ PHP_METHOD(Memcached, fetchAll) | |
uint32_t flags; | |
uint64_t cas = 0; | |
memcached_result_st result; | |
- memcached_return status = MEMCACHED_SUCCESS; | |
+ memcached_return_t status = MEMCACHED_SUCCESS; | |
MEMC_METHOD_INIT_VARS; | |
if (zend_parse_parameters_none() == FAILURE) { | |
@@ -1118,7 +1134,6 @@ PHP_METHOD(Memcached, setByKey) | |
} | |
/* }}} */ | |
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000002 | |
/* {{{ Memcached::touch(string key, [, int expiration ]) | |
Sets a new expiration for the given key */ | |
PHP_METHOD(Memcached, touch) | |
@@ -1134,7 +1149,6 @@ PHP_METHOD(Memcached, touchByKey) | |
php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_TOUCH, 1); | |
} | |
/* }}} */ | |
-#endif | |
/* {{{ Memcached::setMulti(array items [, int expiration ]) | |
@@ -1170,6 +1184,7 @@ PHP_METHOD(Memcached, setMultiByKey) | |
case MEMCACHED_SERVER_MARKED_DEAD: \ | |
if (memcached_server_count(m_obj->memc) > 0) { \ | |
retry++; \ | |
+ i_obj->rescode = 0; \ | |
goto retry; \ | |
} \ | |
break; \ | |
@@ -1191,7 +1206,7 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke | |
size_t payload_len; | |
uint32_t flags = 0; | |
uint32_t retry = 0; | |
- memcached_return status; | |
+ memcached_return_t status; | |
char tmp_key[MEMCACHED_MAX_KEY]; | |
MEMC_METHOD_INIT_VARS; | |
@@ -1337,7 +1352,7 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool | |
size_t payload_len; | |
uint32_t flags = 0; | |
uint32_t retry = 0; | |
- memcached_return status; | |
+ memcached_return_t status; | |
MEMC_METHOD_INIT_VARS; | |
if (by_key) { | |
@@ -1505,7 +1520,7 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) | |
char *payload; | |
size_t payload_len; | |
uint32_t flags = 0; | |
- memcached_return status; | |
+ memcached_return_t status; | |
MEMC_METHOD_INIT_VARS; | |
if (by_key) { | |
@@ -1610,7 +1625,7 @@ static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) | |
char *server_key = NULL; | |
int server_key_len = 0; | |
time_t expiration = 0; | |
- memcached_return status; | |
+ memcached_return_t status; | |
MEMC_METHOD_INIT_VARS; | |
if (by_key) { | |
@@ -1655,7 +1670,7 @@ static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by | |
time_t expiration = 0; | |
zval **entry; | |
- memcached_return status; | |
+ memcached_return_t status; | |
MEMC_METHOD_INIT_VARS; | |
if (by_key) { | |
@@ -1711,7 +1726,7 @@ static void php_memc_incdec_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key, | |
long offset = 1; | |
uint64_t value, initial = 0; | |
time_t expiry = 0; | |
- memcached_return status; | |
+ memcached_return_t status; | |
int n_args = ZEND_NUM_ARGS(); | |
uint32_t retry = 0; | |
@@ -1819,7 +1834,7 @@ PHP_METHOD(Memcached, addServer) | |
char *host; | |
int host_len; | |
long port, weight = 0; | |
- memcached_return status; | |
+ memcached_return_t status; | |
MEMC_METHOD_INIT_VARS; | |
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &host, &host_len, | |
@@ -1855,8 +1870,8 @@ PHP_METHOD(Memcached, addServers) | |
zval **z_host, **z_port, **z_weight = NULL; | |
uint32_t weight = 0; | |
int entry_size, i = 0; | |
- memcached_server_st *list = NULL; | |
- memcached_return status; | |
+ memcached_server_list_st list = NULL; | |
+ memcached_return_t status; | |
MEMC_METHOD_INIT_VARS; | |
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &servers) == FAILURE) { | |
@@ -1936,7 +1951,7 @@ PHP_METHOD(Memcached, addServers) | |
PHP_METHOD(Memcached, getServerList) | |
{ | |
struct callbackContext context = {0}; | |
- memcached_server_function callbacks[1]; | |
+ memcached_server_fn callbacks[1]; | |
MEMC_METHOD_INIT_VARS; | |
if (zend_parse_parameters_none() == FAILURE) { | |
@@ -1958,8 +1973,12 @@ PHP_METHOD(Memcached, getServerByKey) | |
{ | |
char *server_key; | |
int server_key_len; | |
- memcached_server_st *server; | |
- memcached_return error; | |
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009 | |
+ memcached_instance_st *server_instance; | |
+#else | |
+ memcached_server_instance_st *server_instance; | |
+#endif | |
+ memcached_return_t error; | |
MEMC_METHOD_INIT_VARS; | |
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &server_key, &server_key_len) == FAILURE) { | |
@@ -1974,16 +1993,15 @@ PHP_METHOD(Memcached, getServerByKey) | |
RETURN_FALSE; | |
} | |
- server = memcached_server_by_key(m_obj->memc, server_key, server_key_len, &error); | |
- if (server == NULL) { | |
+ server_instance = memcached_server_by_key(m_obj->memc, server_key, server_key_len, &error); | |
+ if (server_instance == NULL) { | |
php_memc_handle_error(i_obj, error TSRMLS_CC); | |
RETURN_FALSE; | |
} | |
array_init(return_value); | |
- add_assoc_string(return_value, "host", server->hostname, 1); | |
- add_assoc_long(return_value, "port", server->port); | |
- add_assoc_long(return_value, "weight", server->weight); | |
+ add_assoc_string(return_value, "host", (char*) memcached_server_name(server_instance), 1); | |
+ add_assoc_long(return_value, "port", memcached_server_port(server_instance)); | |
} | |
/* }}} */ | |
@@ -2021,14 +2039,91 @@ PHP_METHOD(Memcached, quit) | |
} | |
/* }}} */ | |
+/* {{{ Memcached::getLastErrorMessage() | |
+ Returns the last error message that occurred */ | |
+PHP_METHOD(Memcached, getLastErrorMessage) | |
+{ | |
+ MEMC_METHOD_INIT_VARS; | |
+ | |
+ if (zend_parse_parameters_none() == FAILURE) { | |
+ return; | |
+ } | |
+ | |
+ MEMC_METHOD_FETCH_OBJECT; | |
+ | |
+ RETURN_STRING(memcached_last_error_message(m_obj->memc), 1); | |
+} | |
+/* }}} */ | |
+ | |
+/* {{{ Memcached::getLastErrorCode() | |
+ Returns the last error code that occurred */ | |
+PHP_METHOD(Memcached, getLastErrorCode) | |
+{ | |
+ MEMC_METHOD_INIT_VARS; | |
+ | |
+ if (zend_parse_parameters_none() == FAILURE) { | |
+ return; | |
+ } | |
+ | |
+ MEMC_METHOD_FETCH_OBJECT; | |
+ | |
+ RETURN_LONG(memcached_last_error(m_obj->memc)); | |
+} | |
+/* }}} */ | |
+ | |
+/* {{{ Memcached::getLastErrorErrno() | |
+ Returns the last error errno that occurred */ | |
+PHP_METHOD(Memcached, getLastErrorErrno) | |
+{ | |
+ MEMC_METHOD_INIT_VARS; | |
+ | |
+ if (zend_parse_parameters_none() == FAILURE) { | |
+ return; | |
+ } | |
+ | |
+ MEMC_METHOD_FETCH_OBJECT; | |
+ | |
+ RETURN_LONG(memcached_last_error_errno(m_obj->memc)); | |
+} | |
+/* }}} */ | |
+ | |
+/* {{{ Memcached::getLastDisconnectedServer() | |
+ Returns the last disconnected server | |
+ Was added in 0.34 according to libmemcached's Changelog */ | |
+PHP_METHOD(Memcached, getLastDisconnectedServer) | |
+{ | |
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009 | |
+ memcached_instance_st *server_instance; | |
+#else | |
+ memcached_server_instance_st *server_instance; | |
+#endif | |
+ MEMC_METHOD_INIT_VARS; | |
+ | |
+ if (zend_parse_parameters_none() == FAILURE) { | |
+ return; | |
+ } | |
+ | |
+ MEMC_METHOD_FETCH_OBJECT; | |
+ | |
+ server_instance = memcached_server_get_last_disconnect(m_obj->memc); | |
+ if (server_instance == NULL) { | |
+ RETURN_FALSE; | |
+ } | |
+ | |
+ array_init(return_value); | |
+ add_assoc_string(return_value, "host", (char*) memcached_server_name(server_instance), 1); | |
+ add_assoc_long(return_value, "port", memcached_server_port(server_instance)); | |
+} | |
+/* }}} */ | |
+ | |
/* {{{ Memcached::getStats() | |
Returns statistics for the memcache servers */ | |
PHP_METHOD(Memcached, getStats) | |
{ | |
memcached_stat_st *stats; | |
- memcached_return status; | |
+ memcached_return_t status; | |
struct callbackContext context = {0}; | |
- memcached_server_function callbacks[1]; | |
+ memcached_server_fn callbacks[1]; | |
MEMC_METHOD_INIT_VARS; | |
if (zend_parse_parameters_none() == FAILURE) { | |
@@ -2067,9 +2162,9 @@ PHP_METHOD(Memcached, getStats) | |
Returns the version of each memcached server in the pool */ | |
PHP_METHOD(Memcached, getVersion) | |
{ | |
- memcached_return status = MEMCACHED_SUCCESS; | |
+ memcached_return_t status = MEMCACHED_SUCCESS; | |
struct callbackContext context = {0}; | |
- memcached_server_function callbacks[1]; | |
+ memcached_server_fn callbacks[1]; | |
MEMC_METHOD_INIT_VARS; | |
if (zend_parse_parameters_none() == FAILURE) { | |
@@ -2095,7 +2190,7 @@ PHP_METHOD(Memcached, getVersion) | |
/* {{{ Memcached::getAllKeys() | |
Returns the keys stored on all the servers */ | |
-static memcached_return php_memc_dump_func_callback(const memcached_st *ptr __attribute__((unused)), \ | |
+static memcached_return_t php_memc_dump_func_callback(const memcached_st *ptr __attribute__((unused)), \ | |
const char *key, size_t key_length, void *context) | |
{ | |
zval *ctx = (zval*) context; | |
@@ -2106,8 +2201,8 @@ static memcached_return php_memc_dump_func_callback(const memcached_st *ptr __at | |
PHP_METHOD(Memcached, getAllKeys) | |
{ | |
- memcached_return rc; | |
- memcached_dump_func callback[1]; | |
+ memcached_return_t rc; | |
+ memcached_dump_fn callback[1]; | |
MEMC_METHOD_INIT_VARS; | |
callback[0] = php_memc_dump_func_callback; | |
@@ -2127,7 +2222,7 @@ PHP_METHOD(Memcached, getAllKeys) | |
static PHP_METHOD(Memcached, flush) | |
{ | |
time_t delay = 0; | |
- memcached_return status; | |
+ memcached_return_t status; | |
MEMC_METHOD_INIT_VARS; | |
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &delay) == FAILURE) { | |
@@ -2152,7 +2247,7 @@ static PHP_METHOD(Memcached, getOption) | |
{ | |
long option; | |
uint64_t result; | |
- memcached_behavior flag; | |
+ memcached_behavior_t flag; | |
MEMC_METHOD_INIT_VARS; | |
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &option) == FAILURE) { | |
@@ -2170,16 +2265,12 @@ static PHP_METHOD(Memcached, getOption) | |
case MEMC_OPT_PREFIX_KEY: | |
{ | |
- memcached_return retval; | |
+ memcached_return_t retval; | |
char *result; | |
result = memcached_callback_get(m_obj->memc, MEMCACHED_CALLBACK_PREFIX_KEY, &retval); | |
if (retval == MEMCACHED_SUCCESS && result) { | |
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x00050000 | |
- RETURN_STRINGL(result, strlen(result) - 1, 1); | |
-#else | |
RETURN_STRING(result, 1); | |
-#endif | |
} else { | |
RETURN_EMPTY_STRING(); | |
} | |
@@ -2209,7 +2300,7 @@ static PHP_METHOD(Memcached, getOption) | |
static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRMLS_DC) | |
{ | |
- memcached_behavior flag; | |
+ memcached_behavior_t flag; | |
struct memc_obj *m_obj = i_obj->obj; | |
switch (option) { | |
@@ -2232,23 +2323,15 @@ static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRML | |
case MEMC_OPT_PREFIX_KEY: | |
{ | |
char *key; | |
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x00050000 | |
- char tmp[MEMCACHED_PREFIX_KEY_MAX_SIZE - 1]; | |
-#endif | |
convert_to_string(value); | |
if (Z_STRLEN_P(value) == 0) { | |
key = NULL; | |
} else { | |
/* | |
- work-around a bug in libmemcached prior to version 0.50 that truncates the trailing | |
+ work-around a bug in libmemcached in version 0.49 that truncates the trailing | |
character of the key prefix, to avoid the issue we pad it with a '0' | |
*/ | |
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x00050000 | |
- snprintf(tmp, sizeof(tmp), "%s0", Z_STRVAL_P(value)); | |
- key = tmp; | |
-#else | |
key = Z_STRVAL_P(value); | |
-#endif | |
} | |
if (memcached_callback_set(m_obj->memc, MEMCACHED_CALLBACK_PREFIX_KEY, key) == MEMCACHED_BAD_KEY_PROVIDED) { | |
php_error_docref(NULL TSRMLS_CC, E_WARNING, "bad key provided"); | |
@@ -2272,14 +2355,9 @@ static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRML | |
* (non-weighted) case. We have to clean up ourselves. | |
*/ | |
if (!Z_LVAL_P(value)) { | |
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX > 0x00037000 | |
(void)memcached_behavior_set_key_hash(m_obj->memc, MEMCACHED_HASH_DEFAULT); | |
(void)memcached_behavior_set_distribution_hash(m_obj->memc, MEMCACHED_HASH_DEFAULT); | |
(void)memcached_behavior_set_distribution(m_obj->memc, MEMCACHED_DISTRIBUTION_MODULA); | |
-#else | |
- m_obj->memc->hash = 0; | |
- m_obj->memc->distribution = 0; | |
-#endif | |
} | |
break; | |
@@ -2317,10 +2395,7 @@ static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRML | |
flag = (memcached_behavior) option; | |
convert_to_long(value); | |
if (flag < 0 || | |
-/* MEMCACHED_BEHAVIOR_MAX was added in somewhere around 0.36 or 0.37 */ | |
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00037000 | |
flag >= MEMCACHED_BEHAVIOR_MAX || | |
-#endif | |
memcached_behavior_set(m_obj->memc, flag, (uint64_t)Z_LVAL_P(value)) != MEMCACHED_SUCCESS) { | |
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error setting memcached option"); | |
return 0; | |
@@ -2406,6 +2481,11 @@ static PHP_METHOD(Memcached, setSaslAuthData) | |
return; | |
} | |
+ if (!MEMC_G(use_sasl)) { | |
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SASL support (memcached.use_sasl) isn't enabled in php.ini"); | |
+ RETURN_FALSE; | |
+ } | |
+ | |
MEMC_METHOD_FETCH_OBJECT; | |
if (!memcached_behavior_get(m_obj->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { | |
@@ -2456,13 +2536,13 @@ static PHP_METHOD(Memcached, getResultMessage) | |
if (i_obj->memc_errno) { | |
char *str; | |
int str_len; | |
- str_len = spprintf(&str, 0, "%s: %s", memcached_strerror(m_obj->memc, (memcached_return)i_obj->rescode), | |
+ str_len = spprintf(&str, 0, "%s: %s", memcached_strerror(m_obj->memc, (memcached_return_t)i_obj->rescode), | |
strerror(i_obj->memc_errno)); | |
RETURN_STRINGL(str, str_len, 0); | |
} | |
/* Fall through */ | |
default: | |
- RETURN_STRING(memcached_strerror(m_obj->memc, (memcached_return)i_obj->rescode), 1); | |
+ RETURN_STRING(memcached_strerror(m_obj->memc, (memcached_return_t)i_obj->rescode), 1); | |
break; | |
} | |
@@ -2573,24 +2653,33 @@ ZEND_RSRC_DTOR_FUNC(php_memc_sess_dtor) | |
/* }}} */ | |
/* {{{ internal API functions */ | |
-static memcached_return php_memc_do_serverlist_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context) | |
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009 | |
+static memcached_return_t php_memc_do_serverlist_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context) | |
+#else | |
+static memcached_return_t php_memc_do_serverlist_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context) | |
+#endif | |
{ | |
struct callbackContext* context = (struct callbackContext*) in_context; | |
zval *array; | |
MAKE_STD_ZVAL(array); | |
array_init(array); | |
- add_assoc_string(array, "host", memcached_server_name(instance), 1); | |
+ add_assoc_string(array, "host", (char*) memcached_server_name(instance), 1); | |
add_assoc_long(array, "port", memcached_server_port(instance)); | |
/* | |
* API does not allow to get at this field. | |
add_assoc_long(array, "weight", instance->weight); | |
- */ | |
+ */ | |
+ | |
add_next_index_zval(context->return_value, array); | |
return MEMCACHED_SUCCESS; | |
} | |
-static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context) | |
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009 | |
+static memcached_return_t php_memc_do_stats_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context) | |
+#else | |
+static memcached_return_t php_memc_do_stats_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context) | |
+#endif | |
{ | |
char *hostport = NULL; | |
int hostport_len; | |
@@ -2634,7 +2723,11 @@ static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, memc | |
return MEMCACHED_SUCCESS; | |
} | |
-static memcached_return php_memc_do_version_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context) | |
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009 | |
+static memcached_return_t php_memc_do_version_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context) | |
+#else | |
+static memcached_return_t php_memc_do_version_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context) | |
+#endif | |
{ | |
char *hostport = NULL; | |
char version[16]; | |
@@ -2642,17 +2735,24 @@ static memcached_return php_memc_do_version_callback(const memcached_st *ptr, me | |
struct callbackContext* context = (struct callbackContext*) in_context; | |
hostport_len = spprintf(&hostport, 0, "%s:%d", memcached_server_name(instance), memcached_server_port(instance)); | |
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009 | |
version_len = snprintf(version, sizeof(version), "%d.%d.%d", | |
memcached_server_major_version(instance), | |
memcached_server_minor_version(instance), | |
memcached_server_micro_version(instance)); | |
+#else | |
+ version_len = snprintf(version, sizeof(version), "%d.%d.%d", | |
+ instance->major_version, | |
+ instance->minor_version, | |
+ instance->micro_version); | |
+#endif | |
add_assoc_stringl_ex(context->return_value, hostport, hostport_len+1, version, version_len, 1); | |
efree(hostport); | |
return MEMCACHED_SUCCESS; | |
} | |
-static int php_memc_handle_error(php_memc_t *i_obj, memcached_return status TSRMLS_DC) | |
+static int php_memc_handle_error(php_memc_t *i_obj, memcached_return_t status TSRMLS_DC) | |
{ | |
int result = 0; | |
@@ -2674,23 +2774,13 @@ static int php_memc_handle_error(php_memc_t *i_obj, memcached_return status TSRM | |
case MEMCACHED_SOME_ERRORS: | |
i_obj->rescode = status; | |
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00049000 | |
i_obj->memc_errno = memcached_last_error_errno(i_obj->obj->memc); | |
-#else | |
- i_obj->memc_errno = i_obj->obj->memc->cached_errno; /* Hnngghgh! */ | |
- | |
-#endif | |
result = 0; | |
break; | |
default: | |
i_obj->rescode = status; | |
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00049000 | |
i_obj->memc_errno = memcached_last_error_errno(i_obj->obj->memc); | |
-#else | |
- i_obj->memc_errno = i_obj->obj->memc->cached_errno; /* Hnngghgh! */ | |
- | |
-#endif | |
result = -1; | |
break; | |
} | |
@@ -3027,11 +3117,16 @@ static void php_memc_init_globals(zend_php_memcached_globals *php_memcached_glob | |
#ifdef HAVE_MEMCACHED_SESSION | |
MEMC_G(sess_locking_enabled) = 1; | |
MEMC_G(sess_binary_enabled) = 1; | |
+ MEMC_G(sess_consistent_hash_enabled) = 0; | |
+ MEMC_G(sess_number_of_replicas) = 0; | |
+ MEMC_G(sess_remove_failed_enabled) = 0; | |
MEMC_G(sess_prefix) = NULL; | |
MEMC_G(sess_lock_wait) = 0; | |
MEMC_G(sess_locked) = 0; | |
MEMC_G(sess_lock_key) = NULL; | |
MEMC_G(sess_lock_key_len) = 0; | |
+ MEMC_G(sess_randomize_replica_read) = 0; | |
+ MEMC_G(sess_connect_timeout) = 1000; | |
#endif | |
MEMC_G(serializer_name) = NULL; | |
MEMC_G(serializer) = SERIALIZER_DEFAULT; | |
@@ -3084,7 +3179,7 @@ zend_class_entry *php_memc_get_exception_base(int root TSRMLS_DC) | |
#endif | |
} | |
-static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_info *fci, | |
+static memcached_return_t php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_info *fci, | |
zend_fcall_info_cache *fcc, char *key, | |
size_t key_len, zval *value TSRMLS_DC) | |
{ | |
@@ -3096,9 +3191,9 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i | |
zval *z_expiration; | |
uint32_t flags = 0; | |
- memcached_return rc; | |
+ memcached_return_t rc; | |
php_memc_t* i_obj; | |
- memcached_return status = MEMCACHED_SUCCESS; | |
+ memcached_return_t status = MEMCACHED_SUCCESS; | |
int result; | |
MAKE_STD_ZVAL(z_key); | |
@@ -3132,7 +3227,7 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i | |
payload = php_memc_zval_to_payload(value, &payload_len, &flags, m_obj->serializer, m_obj->compression_type TSRMLS_CC); | |
if (payload == NULL) { | |
- status = (memcached_return)MEMC_RES_PAYLOAD_FAILURE; | |
+ status = (memcached_return_t)MEMC_RES_PAYLOAD_FAILURE; | |
} else { | |
rc = memcached_set(m_obj->memc, key, key_len, payload, payload_len, expiration, flags); | |
if (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED) { | |
@@ -3466,6 +3561,18 @@ ZEND_BEGIN_ARG_INFO(arginfo_getServerByKey, 0) | |
ZEND_ARG_INFO(0, server_key) | |
ZEND_END_ARG_INFO() | |
+ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorMessage, 0) | |
+ZEND_END_ARG_INFO() | |
+ | |
+ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorCode, 0) | |
+ZEND_END_ARG_INFO() | |
+ | |
+ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorErrno, 0) | |
+ZEND_END_ARG_INFO() | |
+ | |
+ZEND_BEGIN_ARG_INFO(arginfo_getLastDisconnectedServer, 0) | |
+ZEND_END_ARG_INFO() | |
+ | |
ZEND_BEGIN_ARG_INFO(arginfo_getOption, 0) | |
ZEND_ARG_INFO(0, option) | |
ZEND_END_ARG_INFO() | |
@@ -3519,10 +3626,8 @@ static zend_function_entry memcached_class_methods[] = { | |
MEMC_ME(set, arginfo_set) | |
MEMC_ME(setByKey, arginfo_setByKey) | |
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000002 | |
MEMC_ME(touch, arginfo_touch) | |
MEMC_ME(touchByKey, arginfo_touchByKey) | |
-#endif | |
MEMC_ME(setMulti, arginfo_setMulti) | |
MEMC_ME(setMultiByKey, arginfo_setMultiByKey) | |
@@ -3553,6 +3658,11 @@ static zend_function_entry memcached_class_methods[] = { | |
MEMC_ME(resetServerList, arginfo_resetServerList) | |
MEMC_ME(quit, arginfo_quit) | |
+ MEMC_ME(getLastErrorMessage, arginfo_getLastErrorMessage) | |
+ MEMC_ME(getLastErrorCode, arginfo_getLastErrorCode) | |
+ MEMC_ME(getLastErrorErrno, arginfo_getLastErrorErrno) | |
+ MEMC_ME(getLastDisconnectedServer, arginfo_getLastDisconnectedServer) | |
+ | |
MEMC_ME(getStats, arginfo_getStats) | |
MEMC_ME(getVersion, arginfo_getVersion) | |
MEMC_ME(getAllKeys, arginfo_getAllKeys) | |
@@ -3677,9 +3787,7 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_DISTRIBUTION, MEMCACHED_BEHAVIOR_DISTRIBUTION); | |
REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_MODULA, MEMCACHED_DISTRIBUTION_MODULA); | |
REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_CONSISTENT, MEMCACHED_DISTRIBUTION_CONSISTENT); | |
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00049000 | |
REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_VIRTUAL_BUCKET, MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET); | |
-#endif | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_LIBKETAMA_COMPATIBLE, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED); | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_LIBKETAMA_HASH, MEMCACHED_BEHAVIOR_KETAMA_HASH); | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_TCP_KEEPALIVE, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE); | |
@@ -3691,6 +3799,9 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_SOCKET_RECV_SIZE, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE); | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_CONNECT_TIMEOUT, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT); | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_RETRY_TIMEOUT, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT); | |
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000003 | |
+ REGISTER_MEMC_CLASS_CONST_LONG(OPT_DEAD_TIMEOUT, MEMCACHED_BEHAVIOR_DEAD_TIMEOUT); | |
+#endif | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_SEND_TIMEOUT, MEMCACHED_BEHAVIOR_SND_TIMEOUT); | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_RECV_TIMEOUT, MEMCACHED_BEHAVIOR_RCV_TIMEOUT); | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_POLL_TIMEOUT, MEMCACHED_BEHAVIOR_POLL_TIMEOUT); | |
@@ -3702,13 +3813,9 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_SORT_HOSTS, MEMCACHED_BEHAVIOR_SORT_HOSTS); | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_VERIFY_KEY, MEMCACHED_BEHAVIOR_VERIFY_KEY); | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_USE_UDP, MEMCACHED_BEHAVIOR_USE_UDP); | |
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00037000 | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_NUMBER_OF_REPLICAS, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS); | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_RANDOMIZE_REPLICA_READ, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ); | |
-#endif | |
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00049000 | |
REGISTER_MEMC_CLASS_CONST_LONG(OPT_REMOVE_FAILED_SERVERS, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS); | |
-#endif | |
/* | |
* libmemcached result codes | |
@@ -3870,6 +3977,12 @@ PHP_MINFO_FUNCTION(memcached) | |
php_info_print_table_row(2, "Version", PHP_MEMCACHED_VERSION); | |
php_info_print_table_row(2, "libmemcached version", memcached_lib_version()); | |
+#if HAVE_MEMCACHED_SASL | |
+ php_info_print_table_row(2, "SASL support", "yes"); | |
+#else | |
+ php_info_print_table_row(2, "SASL support", "no"); | |
+#endif | |
+ | |
#ifdef HAVE_MEMCACHED_SESSION | |
php_info_print_table_row(2, "Session support", "yes"); | |
#else | |
diff --git a/memcached-2.1.0/php_memcached.h b/memcached-2.1.0/php_memcached.h | |
index 564b7a5..61e9c69 100644 | |
--- a/memcached-2.1.0/php_memcached.h | |
+++ b/memcached-2.1.0/php_memcached.h | |
@@ -66,6 +66,13 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached) | |
zend_bool sess_locked; | |
char* sess_lock_key; | |
int sess_lock_key_len; | |
+ | |
+ int sess_number_of_replicas; | |
+ zend_bool sess_randomize_replica_read; | |
+ zend_bool sess_remove_failed_enabled; | |
+ long sess_connect_timeout; | |
+ zend_bool sess_consistent_hash_enabled; | |
+ zend_bool sess_binary_enabled; | |
#endif | |
char *serializer_name; | |
enum memcached_serializer serializer; | |
@@ -78,7 +85,6 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached) | |
#if HAVE_MEMCACHED_SASL | |
bool use_sasl; | |
#endif | |
- zend_bool sess_binary_enabled; | |
ZEND_END_MODULE_GLOBALS(php_memcached) | |
PHP_MEMCACHED_API zend_class_entry *php_memc_get_ce(void); | |
diff --git a/memcached-2.1.0/php_memcached_session.c b/memcached-2.1.0/php_memcached_session.c | |
index 0dca515..952b744 100644 | |
--- a/memcached-2.1.0/php_memcached_session.c | |
+++ b/memcached-2.1.0/php_memcached_session.c | |
@@ -48,6 +48,7 @@ static int php_memc_sess_lock(memcached_st *memc, const char *key TSRMLS_DC) | |
char *lock_key = NULL; | |
int lock_key_len = 0; | |
unsigned long attempts; | |
+ long write_retry_attempts = 0; | |
long lock_maxwait; | |
long lock_wait = MEMC_G(sess_lock_wait); | |
time_t expiration; | |
@@ -64,6 +65,11 @@ static int php_memc_sess_lock(memcached_st *memc, const char *key TSRMLS_DC) | |
expiration = time(NULL) + lock_maxwait + 1; | |
attempts = (unsigned long)((1000000.0 / lock_wait) * lock_maxwait); | |
+ /* Set the number of write retry attempts to the number of replicas times the number of attempts to remove a server */ | |
+ if (MEMC_G(sess_remove_failed_enabled)) { | |
+ write_retry_attempts = MEMC_G(sess_number_of_replicas) * ( memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT) + 1); | |
+ } | |
+ | |
lock_key_len = spprintf(&lock_key, 0, "lock.%s", key); | |
do { | |
status = memcached_add(memc, lock_key, lock_key_len, "1", sizeof("1")-1, expiration, 0); | |
@@ -73,6 +79,11 @@ static int php_memc_sess_lock(memcached_st *memc, const char *key TSRMLS_DC) | |
MEMC_G(sess_lock_key_len) = lock_key_len; | |
return 0; | |
} else if (status != MEMCACHED_NOTSTORED && status != MEMCACHED_DATA_EXISTS) { | |
+ if (write_retry_attempts > 0) { | |
+ write_retry_attempts--; | |
+ continue; | |
+ } | |
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Write of lock failed"); | |
break; | |
} | |
@@ -139,10 +150,22 @@ error: | |
if (servers) { | |
memc_sess->memc_sess = memcached_create(NULL); | |
if (memc_sess->memc_sess) { | |
+ if (MEMC_G(sess_consistent_hash_enabled)) { | |
+ if (memcached_behavior_set(memc_sess->memc_sess, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, (uint64_t) 1) == MEMCACHED_FAILURE) { | |
+ PS_SET_MOD_DATA(NULL); | |
+ if (plist_key) { | |
+ efree(plist_key); | |
+ } | |
+ memcached_free(memc_sess->memc_sess); | |
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to enable memcached consistent hashing"); | |
+ return FAILURE; | |
+ } | |
+ } | |
+ | |
status = memcached_server_push(memc_sess->memc_sess, servers); | |
memcached_server_list_free(servers); | |
- if (memcached_callback_set(memc_sess->memc_sess, MEMCACHED_CALLBACK_PREFIX_KEY, MEMC_G(sess_prefix)) != MEMCACHED_SUCCESS) { | |
+ if (MEMC_G(sess_prefix) && MEMC_G(sess_prefix)[0] != 0 && memcached_callback_set(memc_sess->memc_sess, MEMCACHED_CALLBACK_PREFIX_KEY, MEMC_G(sess_prefix)) != MEMCACHED_SUCCESS) { | |
PS_SET_MOD_DATA(NULL); | |
if (plist_key) { | |
efree(plist_key); | |
@@ -195,6 +218,29 @@ success: | |
} | |
} | |
+ if (MEMC_G(sess_number_of_replicas) > 0) { | |
+ if (memcached_behavior_set(memc_sess->memc_sess, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, (uint64_t) MEMC_G(sess_number_of_replicas)) == MEMCACHED_FAILURE) { | |
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to set memcached session number of replicas"); | |
+ return FAILURE; | |
+ } | |
+ if (memcached_behavior_set(memc_sess->memc_sess, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, (uint64_t) MEMC_G(sess_randomize_replica_read)) == MEMCACHED_FAILURE) { | |
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to set memcached session randomize replica read"); | |
+ } | |
+ } | |
+ | |
+ if (memcached_behavior_set(memc_sess->memc_sess, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, (uint64_t) MEMC_G(sess_connect_timeout)) == MEMCACHED_FAILURE) { | |
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to set memcached connection timeout"); | |
+ return FAILURE; | |
+ } | |
+ | |
+ /* Allow libmemcached remove failed servers */ | |
+ if (MEMC_G(sess_remove_failed_enabled)) { | |
+ if (memcached_behavior_set(memc_sess->memc_sess, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, (uint64_t) 1) == MEMCACHED_FAILURE) { | |
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to set: remove failed servers"); | |
+ return FAILURE; | |
+ } | |
+ } | |
+ | |
return SUCCESS; | |
} | |
} | |
@@ -243,6 +289,7 @@ PS_READ_FUNC(memcached) | |
if (MEMC_G(sess_locking_enabled)) { | |
if (php_memc_sess_lock(memc_sess->memc_sess, key TSRMLS_CC) < 0) { | |
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to clear session lock record"); | |
return FAILURE; | |
} | |
} | |
@@ -263,6 +310,7 @@ PS_WRITE_FUNC(memcached) | |
{ | |
int key_len = strlen(key); | |
time_t expiration = 0; | |
+ long write_try_attempts = 1; | |
memcached_return status; | |
memcached_sess *memc_sess = PS_GET_MOD_DATA(); | |
size_t key_length; | |
@@ -277,13 +325,22 @@ PS_WRITE_FUNC(memcached) | |
if (PS(gc_maxlifetime) > 0) { | |
expiration = PS(gc_maxlifetime); | |
} | |
- status = memcached_set(memc_sess->memc_sess, key, key_len, val, vallen, expiration, 0); | |
- if (status == MEMCACHED_SUCCESS) { | |
- return SUCCESS; | |
- } else { | |
- return FAILURE; | |
+ /* Set the number of write retry attempts to the number of replicas times the number of attempts to remove a server plus the initial write */ | |
+ if (MEMC_G(sess_remove_failed_enabled)) { | |
+ write_try_attempts = 1 + MEMC_G(sess_number_of_replicas) * ( memcached_behavior_get(memc_sess->memc_sess, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT) + 1); | |
} | |
+ | |
+ do { | |
+ status = memcached_set(memc_sess->memc_sess, key, key_len, val, vallen, expiration, 0); | |
+ if (status == MEMCACHED_SUCCESS) { | |
+ return SUCCESS; | |
+ } else { | |
+ write_try_attempts--; | |
+ } | |
+ } while (write_try_attempts > 0); | |
+ | |
+ return FAILURE; | |
} | |
PS_DESTROY_FUNC(memcached) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment