static int php_memc_sess_lock(memcached_st *memc, const char *key) { char *lock_key = NULL; int lock_key_len = 0; unsigned long attempts; long write_retry_attempts = 0; long lock_maxwait = MEMC_G(sess_lock_max_wait); long lock_wait = MEMC_G(sess_lock_wait); long lock_expire = MEMC_G(sess_lock_expire); time_t expiration; memcached_return status; /* set max timeout for session_start = max_execution_time. (c) Andrei Darashenka, Richter & Poweleit GmbH */ if (lock_maxwait <= 0) { lock_maxwait = zend_ini_long(ZEND_STRS("max_execution_time"), 0); if (lock_maxwait <= 0) { lock_maxwait = MEMC_SESS_LOCK_EXPIRATION; } } if (lock_wait == 0) { lock_wait = MEMC_SESS_DEFAULT_LOCK_WAIT; } if (lock_expire <= 0) { lock_expire = lock_maxwait; } expiration = lock_expire + 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); if (status == MEMCACHED_SUCCESS) { MEMC_G(sess_locked) = 1; MEMC_G(sess_lock_key) = lock_key; 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, E_WARNING, "Write of lock failed"); break; } if (lock_wait > 0) { usleep(lock_wait); } } while(--attempts > 0); efree(lock_key); return -1; }
static time_t s_lock_expiration() { if (MEMC_SESS_INI(lock_expiration) > 0) { return s_adjust_expiration(MEMC_SESS_INI(lock_expiration)); } else { zend_long max_execution_time = zend_ini_long(ZEND_STRL("max_execution_time"), 0); if (max_execution_time > 0) { return s_adjust_expiration(max_execution_time); } } return 0; }
ps_module ps_mod_memcached = { PS_MOD(memcached) }; static int php_memc_sess_lock(memcached_st *memc, const char *key TSRMLS_DC) { char *lock_key = NULL; int lock_key_len = 0; long attempts; long lock_maxwait; long lock_wait = MEMC_G(sess_lock_wait); time_t expiration; memcached_return status; /* set max timeout for session_start = max_execution_time. (c) Andrei Darashenka, Richter & Poweleit GmbH */ lock_maxwait = zend_ini_long(ZEND_STRS("max_execution_time"), 0); if (lock_maxwait <= 0) { lock_maxwait = MEMC_SESS_LOCK_EXPIRATION; } if (lock_wait == 0) { lock_wait = MEMC_SESS_DEFAULT_LOCK_WAIT; } expiration = time(NULL) + lock_maxwait + 1; attempts = lock_maxwait * 1000000 / lock_wait; 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); if (status == MEMCACHED_SUCCESS) { MEMC_G(sess_locked) = 1; MEMC_G(sess_lock_key) = lock_key;