return false;
}
+/// session locking
+ public function get_session_lock($name, $timeout) {
+ // TODO: make this abstract
+ return true;
+ }
+
+ public function release_session_lock($name) {
+ // TODO: make this abstract
+ return true;
+ }
+
/// performance and logging
/**
* Returns number of reads done by this database
/// TODO: Decide if this method should go to DDL instead of being here
public function create_database($dbhost, $dbuser, $dbpass, $dbname) {
ob_start();
- $conn= new mysqli($dbhost, $dbuser, $dbpass); /// Connect without db
+ $conn = new mysqli($dbhost, $dbuser, $dbpass); /// Connect without db
$dberr = ob_get_contents();
ob_end_clean();
$errorno = @$conn->connect_errno;
return $positivematch ? 'REGEXP' : 'NOT REGEXP';
}
+/// session locking
+ public function get_session_lock($name, $timeout) {
+ $fullname = $this->dbname.'-'.$this->prefix.'-'.$name;
+ $sql = "SELECT GET_LOCK(?,?)";
+ $params = array($fullname, $timeout);
+ $rawsql = $this->emulate_bound_params($sql, $params);
+
+ $this->query_start($sql, $params, SQL_QUERY_AUX);
+ $result = $this->mysqli->query($rawsql);
+ $this->query_end($result);
+
+ if ($result) {
+ $arr = $result->fetch_assoc();
+ $result->close();
+
+ if (reset($arr) == 1) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function release_session_lock($name) {
+ $fullname = $this->dbname.'-'.$this->prefix.'-'.$name;
+ $sql = "SELECT RELEASE_LOCK(?)";
+ $params = array($fullname);
+ $rawsql = $this->emulate_bound_params($sql, $params);
+
+ $this->query_start($sql, $params, SQL_QUERY_AUX);
+ $result = $this->mysqli->query($rawsql);
+ $this->query_end($result);
+
+ if ($result) {
+ $arr = $result->fetch_assoc();
+ $result->close();
+
+ if (reset($arr) == 1) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/// transactions
/**
* on DBs that support it, switch to transaction mode and begin a transaction
public function handler_read($sid) {
global $CFG;
- // TODO: implement normal locking (and later speculative locking)
// TODO: implement timeout + auth plugin hook (see gc)
if ($this->record and $this->record->sid != $sid) {
return '';
}
+ // lock session
+ while (!$this->database->get_session_lock($sid, 10)) {
+ sleep(1);
+ }
+
try {
if (!$record = $this->database->get_record('sessions', array('sid'=>$sid))) {
$record = new object();
return true;
}
+ $this->database->release_session_lock($this->record->sid);
+
$this->record->sid = $sid; // it might be regenerated
$this->record->sessdata = base64_encode($session_data); // there might be some binary mess :-(
$this->record->sessdatahash = md5($this->record->sessdata);
return true;
}
+ $this->database->release_session_lock($this->record->sid);
+
try {
$this->database->delete_records('sessions', array('sid'=>$this->record->sid));
} catch (dml_exception $ex) {
$select = "timemodified + :maxlifetime < :now";
$params = array('now'=>time(), 'maxlifetime'=>$maxlifetime);
- // TODO: add auth plugin hook that would allow extennding of max lifetime
+ // TODO: add auth plugin hook that would allow extending of max lifetime
try {
$this->database->delete_records_select('sessions', $select, $params);