Created
March 7, 2014 16:42
-
-
Save denji/9414954 to your computer and use it in GitHub Desktop.
memcache-3.0.8: Force closing persistent connection
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 memcache-3.0.8/memcache.c memcache-3.0.8/memcache.c | |
index 0356359..d8a4f2d 100644 | |
--- memcache-3.0.8/memcache.c | |
+++ memcache-3.0.8/memcache.c | |
@@ -710,6 +710,8 @@ mmc_t *mmc_find_persistent(const char *host, int host_len, unsigned short port, | |
key_len = spprintf(&key, 0, "memcache:server:%s:%u:%u", host, port, udp_port); | |
+retry_lookup: | |
+ | |
if (zend_hash_find(&EG(persistent_list), key, key_len+1, (void **)&le) == FAILURE) { | |
zend_rsrc_list_entry new_le; | |
@@ -762,6 +764,13 @@ mmc_t *mmc_find_persistent(const char *host, int host_len, unsigned short port, | |
if (mmc->udp.status == MMC_STATUS_CONNECTED) { | |
mmc->udp.status = MMC_STATUS_UNKNOWN; | |
} | |
+ | |
+ if (!MMC_IS_CLEAN(mmc)) { | |
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Force closing persistent connection to %s:%d (state: %d)", host, port, mmc->state); | |
+ zend_hash_del(&EG(persistent_list), key, key_len+1); | |
+ mmc = NULL; | |
+ goto retry_lookup; | |
+ } | |
} | |
efree(key); | |
diff --git memcache-3.0.8/memcache_ascii_protocol.c memcache-3.0.8/memcache_ascii_protocol.c | |
index caf0433..a12eaf1 100644 | |
--- memcache-3.0.8/memcache_ascii_protocol.c | |
+++ memcache-3.0.8/memcache_ascii_protocol.c | |
@@ -106,6 +106,7 @@ static int mmc_request_parse_response(mmc_t *mmc, mmc_request_t *request TSRMLS_ | |
if (line_len > 0) { | |
int response = mmc_request_check_response(line, line_len); | |
+ MMC_CLEAN(mmc); | |
return request->response_handler(mmc, request, response, line, line_len - (sizeof("\r\n")-1), request->response_handler_param TSRMLS_CC); | |
} | |
diff --git memcache-3.0.8/memcache_binary_protocol.c memcache-3.0.8/memcache_binary_protocol.c | |
index bb247a1..c2614bf 100644 | |
--- memcache-3.0.8/memcache_binary_protocol.c | |
+++ memcache-3.0.8/memcache_binary_protocol.c | |
@@ -208,6 +208,7 @@ static int mmc_request_read_response(mmc_t *mmc, mmc_request_t *request TSRMLS_D | |
/* done reading? */ | |
if (request->readbuf.idx >= req->value.length) { | |
+ MMC_CLEAN(mmc); | |
request->readbuf.value.c[req->value.length] = '\0'; | |
return request->response_handler(mmc, request, req->command.error, request->readbuf.value.c, req->value.length, request->response_handler_param TSRMLS_CC); | |
} | |
diff --git memcache-3.0.8/memcache_pool.c memcache-3.0.8/memcache_pool.c | |
index 628fbc8..87ea604 100644 | |
--- memcache-3.0.8/memcache_pool.c | |
+++ memcache-3.0.8/memcache_pool.c | |
@@ -187,6 +187,7 @@ static inline int mmc_request_send(mmc_t *mmc, mmc_request_t *request TSRMLS_DC) | |
count = request->io->stream->chunk_size; | |
} | |
+ MMC_DIRTY(mmc); | |
bytes = send(request->io->fd, request->sendbuf.value.c + request->sendbuf.idx, count, MSG_NOSIGNAL); | |
if (bytes >= 0) { | |
request->sendbuf.idx += bytes; | |
@@ -275,6 +276,7 @@ static int mmc_request_read_udp(mmc_t *mmc, mmc_request_t *request TSRMLS_DC) /* | |
} | |
request->io->buffer.value.len += bytes; | |
+ MMC_CLEAN(mmc); | |
return MMC_OK; | |
} | |
/* }}} */ | |
@@ -798,6 +800,8 @@ static int mmc_server_connect(mmc_pool_t *pool, mmc_t *mmc, mmc_stream_t *io, in | |
mmc->error = NULL; | |
} | |
+ MMC_CLEAN(mmc); | |
+ | |
return MMC_OK; | |
} | |
/* }}} */ | |
diff --git memcache-3.0.8/memcache_pool.h memcache-3.0.8/memcache_pool.h | |
index 3c65602..d9788ce 100644 | |
--- memcache-3.0.8/memcache_pool.h | |
+++ memcache-3.0.8/memcache_pool.h | |
@@ -228,8 +228,19 @@ struct mmc { | |
uint16_t reqid; /* next sequential request id */ | |
char *error; /* last error message */ | |
int errnum; /* last error code */ | |
+ int state; /* connection state */ | |
}; | |
+enum { | |
+ MMC_STATE_UNKNOWN, | |
+ MMC_STATE_CLEAN, | |
+ MMC_STATE_DIRTY | |
+}; | |
+ | |
+#define MMC_IS_CLEAN(mmc) (((mmc_t *)mmc)->state == MMC_STATE_CLEAN) | |
+#define MMC_CLEAN(mmc) ((mmc_t *)mmc)->state = MMC_STATE_CLEAN | |
+#define MMC_DIRTY(mmc) ((mmc_t *)mmc)->state = MMC_STATE_DIRTY | |
+ | |
/* wire protocol */ | |
#define MMC_ASCII_PROTOCOL 1 | |
#define MMC_BINARY_PROTOCOL 2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment