Skip to content

Instantly share code, notes, and snippets.

@tony2001
Created February 6, 2013 12:51
Show Gist options
  • Save tony2001/4722331 to your computer and use it in GitHub Desktop.
Save tony2001/4722331 to your computer and use it in GitHub Desktop.
Index: memcache_pool.h
===================================================================
--- memcache_pool.h (revision 328353)
+++ memcache_pool.h (working copy)
@@ -228,8 +228,19 @@
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
Index: memcache.c
===================================================================
--- memcache.c (revision 328353)
+++ memcache.c (working copy)
@@ -710,6 +710,8 @@
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 @@
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);
Index: memcache_binary_protocol.c
===================================================================
--- memcache_binary_protocol.c (revision 328353)
+++ memcache_binary_protocol.c (working copy)
@@ -208,6 +208,7 @@
/* 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);
}
Index: memcache_pool.c
===================================================================
--- memcache_pool.c (revision 328353)
+++ memcache_pool.c (working copy)
@@ -187,6 +187,7 @@
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 @@
}
request->io->buffer.value.len += bytes;
+ MMC_CLEAN(mmc);
return MMC_OK;
}
/* }}} */
@@ -800,6 +802,8 @@
mmc->error = NULL;
}
+ MMC_CLEAN(mmc);
+
return MMC_OK;
}
/* }}} */
Index: memcache_ascii_protocol.c
===================================================================
--- memcache_ascii_protocol.c (revision 328353)
+++ memcache_ascii_protocol.c (working copy)
@@ -106,6 +106,7 @@
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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment