Ok, tak už to asi mám, ale není to úplně ideální občas tam mám chybu "atomicity failed" (to by mohlo nastat pokud čeká moc dlouho). Občas je tam chyba zápisu do souboru.
Celý kód
clearstatcache();
$_DEBUG_ = false;
echo "Atomicity tester.".time()."
";
die;
while ( time()<1570950820 )
{
usleep(500);
}
function atomicFuse($n, $disableDelay = false){
$start = false;
if ( !file_exists("$n.t") )
$start = mkdir("$n.t");
if ( !$disableDelay ){
if ( $start == false )
{
usleep($n*3);
echo ($n*3)."
";
}
}
return $start;
}
function test($n, $p, $_DEBUG_){
$fp = null;
$sname = "$n"; // source
$tname = "$n.txt";// target
echo "<h4>$n at ".time()."</h4>";
for ($i = 0; $i<2; $i++ ){
$start_time = microtime(true);
{
$start = atomicFuse($n);
// If n*16 used then 6 time repeat:
if (!$start) $start = atomicFuse($n);
if (!$start) $start = atomicFuse($n);
if (!$start) $start = atomicFuse($n);
if (!$start) $start = atomicFuse($n);
if (!$start) $start = atomicFuse($n, false);
if (!$start) echo "Atomicity failed. ";
if ( $start )
{
/////////////////////////////
// CHECK FILESIZE VALIDITY //
/////////////////////////////
clearstatcache(); // needed for filesize and touch
$st = stat("$sname");
$original_size = $st['size'];
if ( $_DEBUG_ )
echo "; 1) prevAccess by ".$st['mtime']." fsize ".$st['size']."; ";
$fsize = filesize($sname);
if ( $original_size <> $fsize )
die("; fsize total FAILTURE; ");
if ($fsize === 0)
echo "! The fsize is 0: stat(): ".$st['size']." ;";
///////////////////
// OPEN THE FILE //
///////////////////
$fp = fopen($sname, "r");
$s = fread($fp, $fsize );
$success = fclose($fp);
if ( $success === false )
die("; fclose failed; ");
// 10 - data načtená , $p - prohlížeč
if ( $success )
{
$result = touch("$sname",strlen($s),$p);
if ( $_DEBUG_ )
echo "; TOUCH: $result;";
}
else
die("fclose FAIL.");
if ( strlen($s)<60 )
echo "*$s LENGTH:".strlen($s)."
";
}
}
if ( $start )
{
clearstatcache();
$st = stat("$tname");
if ( $_DEBUG_ )
echo "; 2) prevAccess by ".$st['mtime']." fsize is ".$fsize."; ";
// WRITE OPERATION WITH LOC_EX
$fp = fopen($tname, "w");
if ( true ) { // acquire an exclusive lock
$success = fwrite($fp, $s);
if ( $success === false)
echo "; w FAILED;";
else
if ( $_DEBUG_ )
echo " $success B written; ";
$success = fflush($fp);// flush output before releasing the lock
if ( $success === false )
echo "; flush FAILED; ";
if ( $success === false )
echo "; release FAILED; ";
$success = fclose($fp);
if ( $success === false )
echo "; fclose FAILED; ";
clearstatcache(); // needed for filesize and touch
$fsize = filesize($tname);
if ($original_size>$fsize)
{
echo "; WRITE FAILED, restoring;";
$original_fname = "$n";
$result = copy($original_fname, $tname);
if ($result == false )
die(" TOTAL FAILTURE: copy failed.");
else
echo " RESTORED;";
}
else
{
if ($fsize === 0)
echo "! THE FILE WAS NOT WRITTEN: data length: ".strlen($s)." fsize: $fsize RESOURCE: $fp
";
if ( $success )
touch("$tname",$fsize,$p);
}
} else {
echo "Couldn't get the lock!";
}
} // start
else
echo "skipped";
$success = rmdir("$n.t"); // remove atomic fuse
if ( $success )
echo "<h4>DIR REMOVED</h4>";
else
echo "<h4>DIR NOT REMOVED</h4>";
$time_elapsed_secs = microtime(true) - $start_time;
if ( $time_elapsed_secs === 0 )
echo " FAILED ";
echo "time: $time_elapsed_secs s
";
} // for
}
switch ( $_SERVER['HTTP_USER_AGENT'] ):
// FF 1:
case "":
$p = 1; break;
// Chrome:
case "":
$p = 2; break;
// OPERA:
case "":
$p = 3; break;
endswitch;
copy("523","523.txt");
copy("948","948.txt");
copy("1371","1371.txt");
copy("1913","1913.txt");
copy("2701","2701.txt");
copy("4495","4495.txt");
copy("6758","6758.txt");
test("523",$p,$_DEBUG_);
test("948",$p,$_DEBUG_);
test("1371",$p,$_DEBUG_);
test("1913",$p,$_DEBUG_);
test("2701",$p,$_DEBUG_);
test("4495",$p,$_DEBUG_);
test("6758",$p,$_DEBUG_);
die;