[ci skip] Fix Memcached session lock handling and error checking around replace() usage
diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php
index d017dfb..e924644 100644
--- a/system/libraries/Session/drivers/Session_memcached_driver.php
+++ b/system/libraries/Session/drivers/Session_memcached_driver.php
@@ -204,10 +204,16 @@
 
 		if (isset($this->_lock_key))
 		{
+			$key = $this->_key_prefix.$session_id;
+
 			$this->_memcached->replace($this->_lock_key, time(), 300);
 			if ($this->_fingerprint !== ($fingerprint = md5($session_data)))
 			{
-				if ($this->_memcached->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration']))
+
+				if (
+					$this->_memcached->replace($key, $session_data, $this->_config['expiration'])
+					OR ($this->_memcached->getResultCode() === Memcached::RES_NOTSTORED && $this->_memcached->set($key, $session_data, $this->_config['expiration']))
+				)
 				{
 					$this->_fingerprint = $fingerprint;
 					return $this->_success;
@@ -305,9 +311,12 @@
 		// correct session ID.
 		if ($this->_lock_key === $this->_key_prefix.$session_id.':lock')
 		{
-			return ($this->_memcached->replace($this->_lock_key, time(), 300))
-				? $this->_success
-				: $this->_failure;
+			if ( ! $this->_memcached->replace($this->_lock_key, time(), 300))
+			{
+				return ($this->_memcached->getResultCode() === Memcached::RES_NOTSTORED)
+					? $this->_memcached->set($this->_lock_key, time(), 300)
+					: FALSE;
+			}
 		}
 
 		// 30 attempts to obtain a lock, in case another request already has it
@@ -324,7 +333,7 @@
 			if ( ! $this->_memcached->set($lock_key, time(), 300))
 			{
 				log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id);
-				return $this->_failure;
+				return FALSE;
 			}
 
 			$this->_lock_key = $lock_key;
@@ -335,11 +344,11 @@
 		if ($attempt === 30)
 		{
 			log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 30 attempts, aborting.');
-			return $this->_failure;
+			return FALSE;
 		}
 
 		$this->_lock = TRUE;
-		return $this->_success;
+		return TRUE;
 	}
 
 	// ------------------------------------------------------------------------
@@ -367,5 +376,4 @@
 
 		return TRUE;
 	}
-
-}
+}
\ No newline at end of file