= 4.3.2 !
//
// MODE_LOCK_NONE (non recommandé)
// Dans ce mode la gestion des verrous est désactivée. Les sections critiques
// ne sont pas protégées. La fiabilité des accès peut se révéler aléatoire.
//
//define("MODE_LOCK", MODE_LOCK_FLOCK);
//define("MODE_LOCK", MODE_LOCK_FOPEN_X);
define("MODE_LOCK", MODE_LOCK_NONE);
// ------------
// LOCK_TIMEOUT
// ------------
// Temps d'attente maximal (en secondes) lors d'une tentative d'accès à la
// ressource. Ce paramètre n'est PAS utilisé dans le mode FLOCK.
//
// LOCK_TIMEOUT doit être supérieur à la durée maximale d'utilisation de cette
// ressource. Mais il doit rester inférieur à la durée maximale d'exécution de
// script PHP autorisée par le serveur (en général 30 secondes).
define("LOCK_TIMEOUT", 20);
// ------------
// LOCK_CLEANUP
// ------------
// LOCK_CLEANUP doit être supérieur à la durée maximale d'utilisation de la
// ressource. Une valeur trop élevée peut provoquer le blocage de l'accès à
// la ressource (pendant la durée spécifiée), en cas d'incident sur les
// fichiers de lock (à la suite d'un plantage ou d'un reboot système).
// Ce paramètre n'est PAS utilisé dans le mode FLOCK.
define("LOCK_CLEANUP", 10); // secondes
// -----------------------------------
// Autres constantes (ne pas modifier)
// -----------------------------------
define("LOCK_DELAY2", 200); // millisecondes
define("LOCK_CLEANUP2", 2); // secondes
// -----------------------------------
//-----------------------------------------------------------------------------
// acq_verrou_exclusif ($nomFicVerrou)
//
// $nomFicVerrou: Chemin/nom du fichier verrou qui sera créé par la fonction.
//
// Retour: Identifiant du verrou en cas de succès ou FALSE en cas d'échec.
//-----------------------------------------------------------------------------
function acq_verrou_exclusif ($nomFicVerrou)
{
switch (MODE_LOCK) {
case MODE_LOCK_FLOCK:
$fv = fopen($nomFicVerrou, "a");
if ($fv !== false) {
if (! flock($fv, LOCK_EX)) {
fclose($fv);
$fv = false;
};
}
return $fv;
case MODE_LOCK_FOPEN_X:
$timeout = LOCK_TIMEOUT * 10;
while ((($idVerrou = lck_verrou_acquis($nomFicVerrou)) === false) && $timeout > 0) {
lck_attente(0.1);
$timeout--;
// echo "EXC: time=".time().", timeout=".$timeout."/
\n";
lck_nettoyage_verrou($nomFicVerrou);
}
if ($idVerrou !== false) {
while (($utl = lck_ressource_utilisee($nomFicVerrou)) && $timeout > 0) {
lck_attente(0.1);
$timeout--;
// echo "UTL: time=".time().", timeout=".$timeout."/
\n";
}
if ($utl) {
liberation_verrou($idVerrou);
$idVerrou = false;
}
}
return $idVerrou;
case MODE_LOCK_NONE:
return 1;
}
}
//-----------------------------------------------------------------------------
// acq_verrou_partage ($nomFicVerrou)
//
// $nomFicVerrou: Chemin/nom du fichier verrou
//
// Retour: Identifiant du verrou en cas de succès ou FALSE en cas d'échec.
//-----------------------------------------------------------------------------
function acq_verrou_partage ($nomFicVerrou)
{
switch (MODE_LOCK) {
case MODE_LOCK_FLOCK:
$fv = fopen($nomFicVerrou, "a");
if ($fv !== false) {
if (! flock($fv, LOCK_SH)) {
fclose($fv);
$fv = false;
};
}
return $fv;
case MODE_LOCK_FOPEN_X:
$timeout = LOCK_TIMEOUT * 10;
while ((($idVerrou = lck_verrou_acquis($nomFicVerrou)) === false) && $timeout > 0) {
lck_attente(0.1);
$timeout--;
// echo "EXC: time=".time().", timeout=".$timeout."/
\n";
lck_nettoyage_verrou($nomFicVerrou);
}
if ($idVerrou !== false) {
$maxtime = time() + $timeout / 10;
do {
$nomFicVerrou2 = $nomFicVerrou.".sh".mt_rand(0, 999999);
}
while ((($fv = fopen($nomFicVerrou2, "x")) === false) && time() < $maxtime);
if ($fv !== false) fclose($fv);
liberation_verrou($idVerrou);
if ($fv !== false) $idVerrou = array($nomFicVerrou2);
else $idVerrou = false;
}
return $idVerrou;
case MODE_LOCK_NONE:
return 1;
}
}
//-----------------------------------------------------------------------------
// liberation_verrou ($idVerrou)
//
// $idVerrou: Identifiant de verrou fourni par l'une des fonctions
// acq_verrou_partage ou acq_verrou_exclusif.
//
// Retour: TRUE en cas de succès ou FALSE en cas d'échec.
//-----------------------------------------------------------------------------
function liberation_verrou ($idVerrou)
{
if ($idVerrou !== false) {
switch (MODE_LOCK) {
case MODE_LOCK_FLOCK:
return fclose($idVerrou); // Libération implicite par fclose
case MODE_LOCK_FOPEN_X:
foreach ($idVerrou as $nomVerrou) @unlink($nomVerrou);
return true;
case MODE_LOCK_NONE:
return true;
}
}
else return false;
}
//-----------------------------------------------------------------------------
function lck_microtime_float ()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
function lck_attente ($duree) // Durée en secondes
{
$debut = lck_microtime_float();
usleep($duree * 1000000);
while (lck_microtime_float() - $debut < $duree) {}
}
function lck_verrou_acquis ($nomFicVerrou)
{
if (($fv = @fopen($nomFicVerrou, "x")) !== false) {
fclose($fv);
lck_attente(mt_rand(0, LOCK_DELAY2) / 1000); // millisecondes
if (($fv = @fopen($nomFicVerrou."1", "x")) !== false) {
fclose($fv);
return array($nomFicVerrou, $nomFicVerrou."1");
}
}
return false;
}
function lck_ressource_utilisee ($nomFicVerrou)
{
$dir = dirname($nomFicVerrou);
$name = basename($nomFicVerrou).".sh";
if ($dir == "") $dir = ".";
$curtime = time();
clearstatcache();
$result = false;
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
$nomFichier = $dir."/".$file;
if (is_file($nomFichier) && (substr($file, 0, strlen($name)) == $name) ) {
if (! lck_nettoyage_fichier($nomFichier, $curtime, LOCK_CLEANUP)) {
// echo "UTILISATION: ".$file."
\n";
$result = true;
break;
}
}
}
closedir($dh);
}
return $result;
}
function lck_nettoyage_fichier ($nomFichier, $date, $timeout)
{
if ((($mtime = @filemtime($nomFichier)) !== false) && (($date - $mtime) > $timeout)) {
// echo "*** NETTOYAGE: ".$nomFichier."
\n";
@unlink($nomFichier);
return true;
}
return false;
}
function lck_nettoyage_verrou ($nomFicVerrou)
{
$curtime = time();
clearstatcache();
lck_nettoyage_fichier($nomFicVerrou."1", $curtime, LOCK_CLEANUP2);
lck_nettoyage_fichier($nomFicVerrou, $curtime, LOCK_CLEANUP);
}
//=============================================================================
?>