/** * Get lock * * Acquires an (emulated) lock. * * @param string $session_id Session ID * @return bool */ protected function _get_lock($session_id) { if (isset($this->_lock_key)) { return $this->_redis->setTimeout($this->_lock_key, 300); } // 30 attempts to obtain a lock, in case another request already has it $lock_key = $this->_key_prefix . $session_id . ':lock'; $attempt = 0; do { if (($ttl = $this->_redis->ttl($lock_key)) > 0) { sleep(1); continue; } if (!$this->_redis->setex($lock_key, 300, time())) { log_message('error', 'Session: Error while trying to obtain lock for ' . $this->_key_prefix . $session_id); return FALSE; } $this->_lock_key = $lock_key; break; } while (++$attempt < 30); if ($attempt === 30) { log_message('error', 'Session: Unable to obtain lock for ' . $this->_key_prefix . $session_id . ' after 30 attempts, aborting.'); return FALSE; } elseif ($ttl === -1) { log_message('debug', 'Session: Lock for ' . $this->_key_prefix . $session_id . ' had no TTL, overriding.'); } $this->_lock = TRUE; return TRUE; }
/** * Get lock * * Acquires an (emulated) lock. * * @param string $session_id Session ID * @return bool */ protected function _get_lock($session_id) { if (isset($this->_lock_key)) { return $this->_redis->setTimeout($this->_lock_key, 300); } // 30 attempts to obtain a lock, in case another request already has it $lock_key = $this->_key_prefix . $session_id . ':lock'; $attempt = 0; do { if (($ttl = $this->_redis->ttl($lock_key)) > 0) { sleep(1); continue; } if (!$this->_redis->setex($lock_key, 300, time())) { return FALSE; } $this->_lock_key = $lock_key; break; } while (++$attempt < 30); if ($attempt === 30) { return FALSE; } $this->_lock = TRUE; return TRUE; }
/** * Get lock. * * Acquires an (emulated) lock. * * @param string $session_id Session ID * * @return bool */ protected function _get_lock($session_id) { // PHP 7 reuses the SessionHandler object on regeneration, // so we need to check here if the lock key is for the // correct session ID. if ($this->_lock_key === $this->_key_prefix . $session_id . ':lock') { return $this->_redis->setTimeout($this->_lock_key, 300); } // 30 attempts to obtain a lock, in case another request already has it $lock_key = $this->_key_prefix . $session_id . ':lock'; $attempt = 0; do { if (($ttl = $this->_redis->ttl($lock_key)) > 0) { sleep(1); continue; } if (!$this->_redis->setex($lock_key, 300, time())) { log_message('error', 'Session: Error while trying to obtain lock for ' . $this->_key_prefix . $session_id); return false; } $this->_lock_key = $lock_key; break; } while (++$attempt < 30); if ($attempt === 30) { log_message('error', 'Session: Unable to obtain lock for ' . $this->_key_prefix . $session_id . ' after 30 attempts, aborting.'); return false; } elseif ($ttl === -1) { log_message('debug', 'Session: Lock for ' . $this->_key_prefix . $session_id . ' had no TTL, overriding.'); } $this->_lock = true; return true; }
/** * Write * * Writes (create / update) session data * * @param string $session_id Session ID * @param string $session_data Serialized session data * @return bool */ public function write($session_id, $session_data) { if (!isset($this->_redis)) { return $this->_fail(); } elseif ($session_id !== $this->_session_id) { if (!$this->_release_lock() or !$this->_get_lock($session_id)) { return $this->_fail(); } $this->_key_exists = FALSE; $this->_session_id = $session_id; } if (isset($this->_lock_key)) { $this->_redis->setTimeout($this->_lock_key, 300); if ($this->_fingerprint !== ($fingerprint = md5($session_data)) or $this->_key_exists === FALSE) { if ($this->_redis->set($this->_key_prefix . $session_id, $session_data, $this->_config['expiration'])) { $this->_fingerprint = $fingerprint; $this->_key_exists = TRUE; return $this->_success; } return $this->_fail(); } return $this->_redis->setTimeout($this->_key_prefix . $session_id, $this->_config['expiration']) ? $this->_success : $this->_fail(); } return $this->_fail(); }
/** * Get lock * * Acquires an (emulated) lock. * * @param string $session_id Session ID * @return bool */ protected function _get_lock($session_id) { if (isset($this->_lock_key)) { return $this->_redis->setTimeout($this->_lock_key, 5); } $lock_key = $this->_key_prefix . $session_id . ':lock'; if (($ttl = $this->_redis->ttl($lock_key)) < 1) { if (!$this->_redis->setex($lock_key, 5, time())) { log_message('error', 'Session: Error while trying to obtain lock for ' . $this->_key_prefix . $session_id); return FALSE; } $this->_lock_key = $lock_key; if ($ttl === -1) { log_message('debug', 'Session: Lock for ' . $this->_key_prefix . $session_id . ' had no TTL, overriding.'); } $this->_lock = TRUE; return TRUE; } // Another process has the lock, we'll try to wait for it to free itself ... $attempt = 0; while ($attempt++ < 5) { usleep($ttl * 1000000 - 20000); if (($ttl = $this->_redis->ttl($lock_key)) > 0) { continue; } if (!$this->_redis->setex($lock_key, 5, time())) { log_message('error', 'Session: Error while trying to obtain lock for ' . $this->_key_prefix . $session_id); return FALSE; } $this->_lock_key = $lock_key; break; } if ($attempt === 5) { log_message('error', 'Session: Unable to obtain lock for ' . $this->_key_prefix . $session_id . ' after 5 attempts, aborting.'); return FALSE; } $this->_lock = TRUE; return TRUE; }
/** * Set the socket I/O timeout value in seconds plus microseconds. * * @param integer $seconds Timeout value in seconds. * @param integer $microseconds Additional value in microseconds. * * @access public * @since 1.5.0 */ function setTimeout($seconds, $microseconds = 0) { return $this->_socket->setTimeout($seconds, $microseconds); }