[ci skip] Merge pull request #5170 from tianhe1986/develop_session_race_condition

Decreasing the probability of race condition in session lock
diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php
index 2556bf0..5e90539 100644
--- a/system/libraries/Session/drivers/Session_memcached_driver.php
+++ b/system/libraries/Session/drivers/Session_memcached_driver.php
@@ -310,7 +310,7 @@
 			if ( ! $this->_memcached->replace($this->_lock_key, time(), 300))
 			{
 				return ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND)
-					? $this->_memcached->set($this->_lock_key, time(), 300)
+					? $this->_memcached->add($this->_lock_key, time(), 300)
 					: FALSE;
 			}
 		}
@@ -326,7 +326,8 @@
 				continue;
 			}
 
-			if ( ! $this->_memcached->set($lock_key, time(), 300))
+			$method = ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND) ? 'add' : 'set';
+			if ( ! $this->_memcached->$method($lock_key, time(), 300))
 			{
 				log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id);
 				return FALSE;
diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php
index e220a29..a9e655a 100644
--- a/system/libraries/Session/drivers/Session_redis_driver.php
+++ b/system/libraries/Session/drivers/Session_redis_driver.php
@@ -341,7 +341,11 @@
 				continue;
 			}
 
-			if ( ! $this->_redis->setex($lock_key, 300, time()))
+			$result = ($ttl === -2)
+				? $this->_redis->set($lock_key, time(), array('nx', 'ex' => 300))
+				: $this->_redis->setex($lock_key, 300, time());
+
+			if ( ! $result)
 			{
 				log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id);
 				return FALSE;