= 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); } //============================================================================= ?>