--- memcache_session.c 2013-04-08 05:12:54.000000000 +0300 +++ memcache_session.c 2014-07-23 11:36:42.000000000 +0300 @@ -205,23 +205,9 @@ /* }}} */ static int php_mmc_session_read_request( - mmc_pool_t *pool, zval *zkey, zval **lockparam, zval *addparam, zval **dataparam, - mmc_request_t **lockreq, mmc_request_t **addreq, mmc_request_t **datareq TSRMLS_DC) /* {{{ */ + mmc_pool_t *pool, zval *zkey, zval **dataparam, mmc_request_t **datareq TSRMLS_DC) /* {{{ */ { - mmc_request_t *lreq, *areq, *dreq; - zval lockvalue; - - /* increment request which stores the response int using value_handler_single */ - lreq = mmc_pool_request( - pool, MMC_PROTO_TCP, mmc_numeric_response_handler, lockparam[0], - mmc_pool_failover_handler_null, NULL TSRMLS_CC); - lreq->value_handler = mmc_value_handler_single; - lreq->value_handler_param = lockparam; - - /* add request which should fail if lock has been incremented */ - areq = mmc_pool_request( - pool, MMC_PROTO_TCP, mmc_stored_handler, addparam, - mmc_pool_failover_handler_null, NULL TSRMLS_CC); + mmc_request_t *dreq; /* request to fetch the session data */ dreq = mmc_pool_request_get( @@ -230,31 +216,12 @@ /* prepare key */ if (mmc_prepare_key_ex(Z_STRVAL_P(zkey), Z_STRLEN_P(zkey), dreq->key, &(dreq->key_len)) != MMC_OK) { - mmc_pool_release(pool, lreq); - mmc_pool_release(pool, areq); mmc_pool_release(pool, dreq); return MMC_REQUEST_FAILURE; } - /* append .lock to key */ - memcpy(lreq->key, dreq->key, dreq->key_len); - strcpy(lreq->key + dreq->key_len, ".lock"); - - memcpy(areq->key, dreq->key, dreq->key_len); - strcpy(areq->key + dreq->key_len, ".lock"); - - lreq->key_len = areq->key_len = dreq->key_len + sizeof(".lock")-1; - - /* value for add request */ - ZVAL_LONG(&lockvalue, 1); - - /* build requests */ - pool->protocol->mutate(lreq, zkey, lreq->key, lreq->key_len, 1, 1, 1, MEMCACHE_G(lock_timeout)); - pool->protocol->store(pool, areq, MMC_OP_ADD, areq->key, areq->key_len, 0, MEMCACHE_G(lock_timeout), 0, &lockvalue TSRMLS_CC); pool->protocol->get(dreq, MMC_OP_GET, zkey, dreq->key, dreq->key_len); - *lockreq = lreq; - *addreq = areq; *datareq = dreq; return MMC_OK; } @@ -267,19 +234,13 @@ mmc_pool_t *pool = PS_GET_MOD_DATA(); if (pool != NULL) { - zval lockresult, addresult, dataresult, zkey; - zval *lockparam[3]; + zval dataresult, zkey; zval *dataparam[3]; mmc_t *mmc; - mmc_request_t *lockrequest, *addrequest, *datarequest; + mmc_request_t *datarequest; mmc_queue_t skip_servers = {0}; unsigned int last_index = 0, prev_index = 0, timeout = 5000; - long remainingtime = MEMCACHE_G(lock_timeout) * 1000000 * 2; - - lockparam[0] = &lockresult; - lockparam[1] = NULL; - lockparam[2] = NULL; dataparam[0] = &dataresult; dataparam[1] = NULL; @@ -288,18 +249,12 @@ ZVAL_STRING(&zkey, (char *)key, 0); do { - /* first request tries to increment lock */ - ZVAL_NULL(&lockresult); - - /* second request tries to add lock, succeeds if lock doesn't exist (not relevant for binary - * protocol where increment takes a default value */ - ZVAL_NULL(&addresult); /* third request fetches the data, data is only valid if either of the lock requests succeeded */ ZVAL_NULL(&dataresult); /* create requests */ - if (php_mmc_session_read_request(pool, &zkey, lockparam, &addresult, dataparam, &lockrequest, &addrequest, &datarequest TSRMLS_CC) != MMC_OK) { + if (php_mmc_session_read_request(pool, &zkey, dataparam, &datarequest TSRMLS_CC) != MMC_OK) { break; } @@ -308,12 +263,7 @@ mmc = mmc_pool_find_next(pool, datarequest->key, datarequest->key_len, &skip_servers, &last_index TSRMLS_CC); /* schedule the requests */ - if (!mmc_server_valid(mmc TSRMLS_CC) || - mmc_pool_schedule(pool, mmc, lockrequest TSRMLS_CC) != MMC_OK || - /*pool->protocol != &mmc_binary_protocol && */mmc_pool_schedule(pool, mmc, addrequest TSRMLS_CC) != MMC_OK || - mmc_pool_schedule(pool, mmc, datarequest TSRMLS_CC) != MMC_OK) { - mmc_pool_release(pool, lockrequest); - mmc_pool_release(pool, addrequest); + if (!mmc_server_valid(mmc TSRMLS_CC) || mmc_pool_schedule(pool, mmc, datarequest TSRMLS_CC) != MMC_OK) { mmc_pool_release(pool, datarequest); mmc_queue_push(&skip_servers, mmc); continue; @@ -322,32 +272,18 @@ /* execute requests */ mmc_pool_run(pool TSRMLS_CC); - if ((Z_TYPE(lockresult) == IS_LONG && Z_LVAL(lockresult) == 1) || (Z_TYPE(addresult) == IS_BOOL && Z_BVAL(addresult))) { - if (Z_TYPE(dataresult) == IS_STRING) { + if (Z_TYPE(dataresult) == IS_STRING) { /* break if successfully locked with existing value */ mmc_queue_free(&skip_servers); *val = Z_STRVAL(dataresult); *vallen = Z_STRLEN(dataresult); return SUCCESS; - } + } /* if missing value, skip this server and try next */ - zval_dtor(&dataresult); - mmc_queue_push(&skip_servers, mmc); - } - else { - /* if missing lock, back off and retry same server */ - last_index = prev_index; - usleep(timeout); - remainingtime -= timeout; - timeout *= 2; - - /* max value to usleep() is 1 second */ - if (timeout > 1000000) { - timeout = 1000000; - } - } - } while (skip_servers.len < MEMCACHE_G(session_redundancy)-1 && skip_servers.len < pool->num_servers && remainingtime > 0); + zval_dtor(&dataresult); + mmc_queue_push(&skip_servers, mmc); + } while (skip_servers.len < MEMCACHE_G(session_redundancy) && skip_servers.len < pool->num_servers); mmc_queue_free(&skip_servers); zval_dtor(&dataresult); @@ -371,7 +307,6 @@ mmc_queue_t skip_servers = {0}; unsigned int last_index = 0; - ZVAL_NULL(&lockresult); ZVAL_NULL(&dataresult); do { @@ -385,23 +320,11 @@ break; } - /* append .lock to key */ - lockrequest = mmc_pool_request( - pool, MMC_PROTO_TCP, mmc_stored_handler, &lockresult, - mmc_pool_failover_handler_null, NULL TSRMLS_CC); - - memcpy(lockrequest->key, datarequest->key, datarequest->key_len); - strcpy(lockrequest->key + datarequest->key_len, ".lock"); - lockrequest->key_len = datarequest->key_len + sizeof(".lock")-1; - - ZVAL_LONG(&lockvalue, 0); ZVAL_STRINGL(&value, (char *)val, vallen, 0); /* assemble commands to store data and reset lock */ - if (pool->protocol->store(pool, datarequest, MMC_OP_SET, datarequest->key, datarequest->key_len, 0, INI_INT("session.gc_maxlifetime"), 0, &value TSRMLS_CC) != MMC_OK || - pool->protocol->store(pool, lockrequest, MMC_OP_SET, lockrequest->key, lockrequest->key_len, 0, MEMCACHE_G(lock_timeout), 0, &lockvalue TSRMLS_CC) != MMC_OK) { + if (pool->protocol->store(pool, datarequest, MMC_OP_SET, datarequest->key, datarequest->key_len, 0, INI_INT("session.gc_maxlifetime"), 0, &value TSRMLS_CC) != MMC_OK) { mmc_pool_release(pool, datarequest); - mmc_pool_release(pool, lockrequest); break; } @@ -410,20 +333,18 @@ mmc_queue_push(&skip_servers, mmc); if (!mmc_server_valid(mmc TSRMLS_CC) || - mmc_pool_schedule(pool, mmc, datarequest TSRMLS_CC) != MMC_OK || - mmc_pool_schedule(pool, mmc, lockrequest TSRMLS_CC) != MMC_OK) { + mmc_pool_schedule(pool, mmc, datarequest TSRMLS_CC) != MMC_OK) { mmc_pool_release(pool, datarequest); - mmc_pool_release(pool, lockrequest); continue; } - } while (skip_servers.len < MEMCACHE_G(session_redundancy)-1 && skip_servers.len < pool->num_servers); + } while (skip_servers.len < MEMCACHE_G(session_redundancy) && skip_servers.len < pool->num_servers); mmc_queue_free(&skip_servers); /* execute requests */ mmc_pool_run(pool TSRMLS_CC); - if (Z_BVAL(lockresult) && Z_BVAL(dataresult)) { + if (Z_BVAL(dataresult)) { return SUCCESS; } } @@ -465,11 +386,10 @@ zval lockresult, dataresult; mmc_t *mmc; - mmc_request_t *lockrequest, *datarequest; + mmc_request_t *datarequest; mmc_queue_t skip_servers = {0}; unsigned int last_index = 0; - ZVAL_NULL(&lockresult); ZVAL_NULL(&dataresult); do { @@ -483,38 +403,25 @@ break; } - /* append .lock to key */ - lockrequest = mmc_pool_request( - pool, MMC_PROTO_TCP, mmc_deleted_handler, &lockresult, - mmc_pool_failover_handler_null, NULL TSRMLS_CC); - - memcpy(lockrequest->key, datarequest->key, datarequest->key_len); - strcpy(lockrequest->key + datarequest->key_len, ".lock"); - lockrequest->key_len = datarequest->key_len + sizeof(".lock")-1; - /* assemble commands to store data and reset lock */ pool->protocol->delete(datarequest, datarequest->key, datarequest->key_len, 0); - pool->protocol->delete(lockrequest, lockrequest->key, lockrequest->key_len, 0); /* find next server in line */ mmc = mmc_pool_find_next(pool, datarequest->key, datarequest->key_len, &skip_servers, &last_index TSRMLS_CC); mmc_queue_push(&skip_servers, mmc); - if (!mmc_server_valid(mmc TSRMLS_CC) || - mmc_pool_schedule(pool, mmc, datarequest TSRMLS_CC) != MMC_OK || - mmc_pool_schedule(pool, mmc, lockrequest TSRMLS_CC) != MMC_OK) { + if (!mmc_server_valid(mmc TSRMLS_CC) || mmc_pool_schedule(pool, mmc, datarequest TSRMLS_CC) != MMC_OK) { mmc_pool_release(pool, datarequest); - mmc_pool_release(pool, lockrequest); continue; } - } while (skip_servers.len < MEMCACHE_G(session_redundancy)-1 && skip_servers.len < pool->num_servers); + } while (skip_servers.len < MEMCACHE_G(session_redundancy) && skip_servers.len < pool->num_servers); mmc_queue_free(&skip_servers); /* execute requests */ mmc_pool_run(pool TSRMLS_CC); - if (Z_BVAL(lockresult) && Z_BVAL(dataresult)) { + if (Z_BVAL(dataresult)) { return SUCCESS; } }