[Phpfreechat-svn] SF.net SVN: phpfreechat: [1087] trunk/src
Status: Beta
Brought to you by:
kerphi
From: <ke...@us...> - 2007-08-06 14:44:56
|
Revision: 1087 http://phpfreechat.svn.sourceforge.net/phpfreechat/?rev=1087&view=rev Author: kerphi Date: 2007-08-06 07:44:57 -0700 (Mon, 06 Aug 2007) Log Message: ----------- Now msgid are requested in an atomic process. It prevents corruption problems with multithreaded access. (thanks to Gerard Pinzone) Modified Paths: -------------- trunk/src/containers/file.class.php trunk/src/containers/mysql.class.php trunk/src/pfccontainer.class.php Modified: trunk/src/containers/file.class.php =================================================================== --- trunk/src/containers/file.class.php 2007-08-06 13:47:13 UTC (rev 1086) +++ trunk/src/containers/file.class.php 2007-08-06 14:44:57 UTC (rev 1087) @@ -171,7 +171,6 @@ // create directories $dir_base = $c->container_cfg_server_dir; $dir = $dir_base.'/'.$group.'/'.$subgroup; - if (!is_dir($dir)) mkdir_r($dir); // create or replace metadata file @@ -202,22 +201,21 @@ } // If flock is working properly, this will never be reached $delay = rand(0, pow(2, ($i+1)) - 1) * 5000; // Exponential backoff - echo "try=".$i." ".$delay."\n"; - usleep($delay); + usleep($delay); } fclose($fh); } else { $leafvalue="1"; - file_put_contents($leaffilename, $leafvalue, LOCK_EX); + file_put_contents($leaffilename, $leafvalue, LOCK_EX); } $ret["value"][] = $leafvalue; $ret["timestamp"][] = filemtime($leaffilename); return $ret; - } + } function rmMeta($group, $subgroup = null, $leaf = null) { @@ -283,4 +281,4 @@ } -?> \ No newline at end of file +?> Modified: trunk/src/containers/mysql.class.php =================================================================== --- trunk/src/containers/mysql.class.php 2007-08-06 13:47:13 UTC (rev 1086) +++ trunk/src/containers/mysql.class.php 2007-08-06 14:44:57 UTC (rev 1087) @@ -267,75 +267,41 @@ function incMeta($group, $subgroup, $leaf) { $c =& pfcGlobalConfig::Instance(); - + if ($c->debug) - file_put_contents("/tmp/debug.txt", "\ngetMeta(".$group.",".$subgroup.",".$leaf.")", FILE_APPEND | LOCK_EX); + file_put_contents("/tmp/debug.txt", "\nsetMeta(".$group.",".$subgroup.",".$leaf.",".$leafvalue.")", FILE_APPEND | LOCK_EX); - $ret = array(); - $ret["timestamp"] = array(); - $ret["value"] = array(); - $server = $c->serverid; $db = $this->_connect(); - - $sql_where .= " AND `leaf`='$leaf'"; - $value = "leafvalue"; - $sql_group_by = ""; - - $sql_select="SELECT `$value`, `timestamp` FROM ".$c->container_cfg_mysql_table." WHERE `server`='$server' $sql_where $sql_group_by ORDER BY timestamp FOR UPDATE"; + $time = time(); - if ($c->debug) - file_put_contents("/tmp/debug.txt", "\ngetSQL(".$sql_select.")", FILE_APPEND | LOCK_EX); - - if ($sql_select != "") - { - $thisresult = mysql_query($sql_select, $db); - if (mysql_num_rows($thisresult)) - { - while ($regel = mysql_fetch_array($thisresult)) - { - $ret["timestamp"][] = $regel["timestamp"]; - $ret["value"][] = $regel[$value]; - } - } - } - - $leafvalue = $ret["value"][]; - - if ($leafvalue == NULL) - $leafvalue = 0; - else - $leafvalue++; - - $timestamp = time(); - - $sql_count = "SELECT COUNT(*) AS C FROM ".$c->container_cfg_mysql_table." WHERE `server`='$server' AND `group`='$group' AND `subgroup`='$subgroup' AND `leaf`='$leaf' LIMIT 1"; - $sql_insert="REPLACE INTO ".$c->container_cfg_mysql_table." (`server`, `group`, `subgroup`, `leaf`, `leafvalue`, `timestamp`) VALUES('$server', '$group', '$subgroup', '$leaf', '".addslashes($leafvalue)."', '".$timestamp."')"; - $sql_update="UPDATE ".$c->container_cfg_mysql_table." SET `leafvalue`='".addslashes($leafvalue)."', `timestamp`='".$timestamp."' WHERE `server`='$server' AND `group`='$group' AND `subgroup`='$subgroup' AND `leaf`='$leaf'"; - - $res = mysql_query($sql_count, $db); + // search for the existing leafvalue + mysql_query('LOCK TABLES phpfreechat WRITE;', $db); + $sql_select = "SELECT leafvalue FROM ".$c->container_cfg_mysql_table." WHERE `server`='$server' AND `group`='$group' AND `subgroup`='$subgroup' AND `leaf`='$leaf' LIMIT 1"; + $res = mysql_query($sql_select, $db); $row = mysql_fetch_array($res, MYSQL_ASSOC); - if( $row['C'] == 0 ) + if( !isset($row['leafvalue']) ) { if ($c->debug) file_put_contents("/tmp/debug.txt", "\nsetSQL(".$sql_insert.")", FILE_APPEND | LOCK_EX); - + $leafvalue = 1; + $sql_insert="REPLACE INTO ".$c->container_cfg_mysql_table." (`server`, `group`, `subgroup`, `leaf`, `leafvalue`, `timestamp`) VALUES('$server', '$group', '$subgroup', '$leaf', '".$leafvalue."', '".$time."')"; mysql_query($sql_insert, $db); } else { - if ($sql_update != "") - { - if ($c->debug) - file_put_contents("/tmp/debug.txt", "\nsetSQL(".$sql_update.")", FILE_APPEND | LOCK_EX); - - mysql_query($sql_update, $db); - } + if ($c->debug) + file_put_contents("/tmp/debug.txt", "\nsetSQL(".$sql_update.")", FILE_APPEND | LOCK_EX); + $leafvalue = $row['leafvalue'] + 1; + $sql_update="UPDATE ".$c->container_cfg_mysql_table." SET `leafvalue`='".$leafvalue."', `timestamp`='".$time."' WHERE `server`='$server' AND `group`='$group' AND `subgroup`='$subgroup' AND `leaf`='$leaf'"; + mysql_query($sql_update, $db); } - $ret["value"][] = $leafvalue; - $ret["timestamp"][] = $timestamp; - - return $ret; + mysql_query('UNLOCK TABLES;', $db); + + $ret["value"][] = $leafvalue; + $ret["timestamp"][] = $time; + + return $ret; } @@ -378,4 +344,4 @@ } -?> \ No newline at end of file +?> Modified: trunk/src/pfccontainer.class.php =================================================================== --- trunk/src/pfccontainer.class.php 2007-08-06 13:47:13 UTC (rev 1086) +++ trunk/src/pfccontainer.class.php 2007-08-06 14:44:57 UTC (rev 1087) @@ -696,6 +696,40 @@ } /** + * Increment a counter identified by the following path : group / subgroup / leaf + * Notice: this step must be atomic in order to avoid multithread problem (don't forget to use locking features) + * @param $group is mandatory + * @param $subgroup is mandatory + * @param $leaf is mandatory, it's the counter name + * @return array which contains two subarray 'timestamp' and 'value' (value contains the incremented numeric value) + */ + function incMeta($group, $subgroup, $leaf) + { + $ret = $this->_container->incMeta($group, $subgroup, $leaf); + + if ($this->_usememorycache) + { + // store the modifications in the cache + if (isset($this->_cache[$group]['value']) && + !in_array($subgroup, $this->_cache[$group]['value'])) + { + $this->_cache[$group]['value'][] = $subgroup; + $this->_cache[$group]['timestamp'][] = time(); + } + if (isset($this->_cache[$group]['childs'][$subgroup]['value']) && + !in_array($leaf, $this->_cache[$group]['childs'][$subgroup]['value'])) + { + $this->_cache[$group]['childs'][$subgroup]['value'][] = $leaf; + $this->_cache[$group]['childs'][$subgroup]['timestamp'][] = time(); + } + $this->_cache[$group]['childs'][$subgroup]['childs'][$leaf]['value'] = $ret['value']; + $this->_cache[$group]['childs'][$subgroup]['childs'][$leaf]['timestamp'] = array(time()); + } + + return $ret; + } + + /** * Remove a meta data or a group of metadata * @param $group if null then it will remove all the possible groups (all the created metadata) * @param $subgroup if null then it will remove the $group's childs (all the subgroup contained by $group) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |