summaryrefslogtreecommitdiffstats
path: root/system/libraries
diff options
context:
space:
mode:
authorAndrey Andreev <narf@devilix.net>2014-08-27 21:14:36 +0200
committerAndrey Andreev <narf@devilix.net>2014-08-27 21:14:36 +0200
commit93d9fa77732b2538417b934a9c23293ee465a23d (patch)
tree6f291be13151562ae28b75d540d4c77632cb1337 /system/libraries
parent85f0c558ca2f47453ce7e8ae767451f5c0045479 (diff)
feature/session (#3073): Rework locking mechanism & add Redis driver
Diffstat (limited to 'system/libraries')
-rw-r--r--system/libraries/Session/Session_driver.php64
-rw-r--r--system/libraries/Session/drivers/Session_database_driver.php104
2 files changed, 98 insertions, 70 deletions
diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php
index cc35b66d1..a3bc392ad 100644
--- a/system/libraries/Session/Session_driver.php
+++ b/system/libraries/Session/Session_driver.php
@@ -90,12 +90,19 @@ abstract class CI_Session_driver implements SessionHandlerInterface {
protected $_match_ip;
/**
- * Data dash
+ * Data fingerprint
*
* @var bool
*/
protected $_fingerprint;
+ /**
+ * Lock placeholder
+ *
+ * @var mixed
+ */
+ protected $_lock = FALSE;
+
// ------------------------------------------------------------------------
/**
@@ -202,6 +209,61 @@ abstract class CI_Session_driver implements SessionHandlerInterface {
);
}
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get lock
+ *
+ * A default locking mechanism via semaphores, if ext/sysvsem is available.
+ *
+ * Drivers will usually override this and only fallback to it if no other
+ * locking mechanism is available.
+ *
+ * @param string $session_id
+ * @return bool
+ */
+ protected function _get_lock($session_id)
+ {
+ if ( ! extension_loaded('sysvsem'))
+ {
+ $this->_lock = TRUE;
+ return TRUE;
+ }
+
+ if (($this->_lock = sem_get($session_id.($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : ''), 1, 0644)) === FALSE)
+ {
+ return FALSE;
+ }
+
+ if ( ! sem_acquire($this->_lock))
+ {
+ sem_remove($this->_lock);
+ $this->_lock = FALSE;
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Release lock
+ *
+ * @return bool
+ */
+ protected function _release_lock()
+ {
+ if (extension_loaded('sysvsem') && $this->_lock)
+ {
+ sem_release($this->_lock);
+ sem_remove($this->_lock);
+ $this->_lock = FALSE;
+ }
+
+ return TRUE;
+ }
+
}
/* End of file Session_driver.php */
diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php
index 2bdc4d0d5..032199fc1 100644
--- a/system/libraries/Session/drivers/Session_database_driver.php
+++ b/system/libraries/Session/drivers/Session_database_driver.php
@@ -52,13 +52,6 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
protected $_table;
/**
- * Session ID
- *
- * @var string
- */
- protected $_session_id;
-
- /**
* Row exists flag
*
* @var bool
@@ -70,23 +63,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
*
* @var string
*/
- protected $_lock_driver;
-
- /**
- * Lock status flag
- *
- * @var bool
- */
- protected $_lock = FALSE;
-
- /**
- * Semaphore ID
- *
- * Used for locking if the database doesn't support advisory locks
- *
- * @var resource
- */
- protected $_sem;
+ protected $_lock_driver = 'semaphore';
// ------------------------------------------------------------------------
@@ -122,10 +99,6 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
{
$this->_lock_driver = 'postgre';
}
- elseif (extension_loaded('sysvsem'))
- {
- $this->_lock_driver = 'semaphore';
- }
isset($this->_table) OR $this->_table = config_item('sess_table_name');
}
@@ -143,8 +116,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
public function read($session_id)
{
- $this->_session_id = $session_id;
- if (($this->_lock = $this->_get_lock()) !== FALSE)
+ if ($this->_get_lock() !== FALSE)
{
$this->_db
->select('data')
@@ -246,71 +218,65 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
// ------------------------------------------------------------------------
- protected function _get_lock()
+ protected function _get_lock($session_id)
{
if ($this->_lock_driver === 'mysql')
{
- $arg = $this->_session_id
- .($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : '');
- return (bool) $this->_db
- ->query("SELECT GET_LOCK('".$arg."', 10) AS ci_session_lock")
- ->row()
- ->ci_session_lock;
- }
- elseif ($this->_lock_driver === 'postgre')
- {
- $arg = "hashtext('".$this->_session_id."')"
- .($this->_match_ip ? ", hashtext('".$_SERVER['REMOTE_ADDR']."')" : '');
-
- return (bool) $this->_db->simple_query('SELECT pg_advisory_lock('.$arg.')');
- }
- elseif ($this->_lock_driver === 'semaphore')
- {
- if (($this->_sem = sem_get($arg, 1, 0644)) === FALSE)
+ $arg = $session_id.($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : '');
+ if ($this->_db->query("SELECT GET_LOCK('".$arg."', 10) AS ci_session_lock")->row()->ci_session_lock)
{
- return FALSE;
+ $this->_lock = $arg;
+ return TRUE;
}
- if ( ! sem_acquire($this->_sem))
+ return FALSE;
+ }
+ elseif ($this->_lock_driver === 'postgre')
+ {
+ $arg = "hashtext('".$session_id."')".($this->_match_ip ? ", hashtext('".$_SERVER['REMOTE_ADDR']."')" : '');
+ if ($this->_db->simple_query('SELECT pg_advisory_lock('.$arg.')'))
{
- sem_remove($this->_sem);
- return FALSE;
+ $this->_lock = $arg;
+ return TRUE;
}
- return TRUE;
+ return FALSE;
}
- return TRUE;
+ return parent::_get_lock($session_id);
}
// ------------------------------------------------------------------------
protected function _release_lock()
{
+ if ( ! $this->_lock)
+ {
+ return TRUE;
+ }
+
if ($this->_lock_driver === 'mysql')
{
- $arg = $this->_session_id
- .($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : '');
+ if ($this->_db->query("SELECT RELEASE_LOCK('".$this->_lock."') AS ci_session_lock")->row()->ci_session_lock)
+ {
+ $this->_lock = FALSE;
+ return TRUE;
+ }
- return (bool) $this->_db
- ->query("SELECT RELEASE_LOCK('".$arg."') AS ci_session_lock")
- ->row()
- ->ci_session_lock;
+ return FALSE;
}
elseif ($this->_lock_driver === 'postgre')
{
- $arg = "hashtext('".$this->_session_id."')"
- .($this->_match_ip ? ", hashtext('".$_SERVER['REMOTE_ADDR']."')" : '');
+ if ($this->_db->simple_query('SELECT pg_advisory_unlock('.$this->_lock.')'))
+ {
+ $this->_lock = FALSE;
+ return TRUE;
+ }
- return (bool) $this->_db->simple_query('SELECT pg_advisory_unlock('.$arg.')');
- }
- elseif ($this->_lock_driver === 'semaphore')
- {
- sem_release($this->_sem);
- sem_remove($this->_sem);
+ return FALSE;
}
- return TRUE;
+ return parent::_release_lock();
}
}