6 changed files with 111 additions and 148 deletions
-
1TODO
-
52ajax+json_home/ajax.php
-
2ajax+json_home/test1.html
-
4libs/errException.php
-
58libs/mutualExclusion.php
-
90pvtest.php
@ -0,0 +1,58 @@ |
|||
<?php |
|||
|
|||
require_once dirname(__FILE__) . '/../config.php'; |
|||
require_once LIBDIR . 'errException.php'; |
|||
|
|||
|
|||
function acquireLock ($lockFile, $csId) |
|||
{ |
|||
$fName = $lockFile . $csId . '.lck'; |
|||
$lock = NULL; |
|||
|
|||
setErrExceptionMapping (); |
|||
|
|||
$lockHandle = fopen ($fName, 'w'); |
|||
|
|||
// if available use semaphores for mutual exclusion because flock
|
|||
// doesn't work reliably in threaded environments.
|
|||
if (function_exists ('sem_get')) |
|||
{ |
|||
$lock = sem_get (ftok ($fName, $csId), 1, 0644, TRUE); |
|||
|
|||
$state = sem_acquire ($lock); |
|||
while ($state === FALSE) |
|||
$state = sem_acquire ($lock); |
|||
} |
|||
else |
|||
{ |
|||
$state = flock ($lock, LOCK_EX); |
|||
while ($state === FALSE) |
|||
$state = flock ($lock, LOCK_EX); |
|||
} |
|||
|
|||
// Here one could write informations in the lockfile...time, pid, etc.
|
|||
fwrite ($lockHandle, session_id () . '::' . time ()); |
|||
fflush ($lockHandle); |
|||
|
|||
resetErrExceptionMapping (); |
|||
|
|||
$userAbort = ignore_user_abort(TRUE); |
|||
return array ($lockHandle, $lock, $userAbort); |
|||
} |
|||
|
|||
function releaseLock ($lock) |
|||
{ |
|||
setErrExceptionMapping (); |
|||
|
|||
if ($lock[1] !== NULL) |
|||
sem_release ($lock[1]); |
|||
|
|||
ftruncate ($lock[0], 0); |
|||
fclose ($lock[0]); |
|||
|
|||
resetErrExceptionMapping (); |
|||
|
|||
ignore_user_abort($lock[2]); |
|||
} |
|||
|
|||
?>
|
|||
@ -1,93 +1,15 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* Zunächst mal den Gedanken skizziert |
|||
* Da es kein wirklich zuverlässiges Locking fuer kritische Bereiche |
|||
* in php gibt. Semaphore existiren nur unter Unix und flock arbeitet nicht |
|||
* wenn der webserver threaded ist und keine separaten prozesse pro |
|||
* request erzeugt habe ich folgenden Gedankengang...nicht 100% Atomar, aber |
|||
* möglicherweise das beste was man bekommen kann. |
|||
* |
|||
* ACQUIRE |
|||
* ======= |
|||
* | |
|||
* - leere Datei erzeugen (tmp) |
|||
* - link (tmp) nach (lock) |
|||
* | |
|||
* |----------------------------- |
|||
* OK | | Fehler | |
|||
* | | | |
|||
* | | - lese (lock): sollte blockieren solange diese leer ist |
|||
* | | - unlink (lock) |
|||
* | | - link (tmp) nach (lock) |
|||
* | Fehler | | |
|||
* | ---------------| |
|||
* | | OK |
|||
* | | |
|||
* |----------------------------- |
|||
* | |
|||
* - (tmp) loeschen |
|||
* | |
|||
* (ENDE) |
|||
* |
|||
* RELEASE |
|||
* ======= |
|||
* | |
|||
* - schreibe nach (lock) |
|||
* | |
|||
* (ENDE) |
|||
* |
|||
* Da link angeblick atomar ist muesste das zumindest zuverlaessig Sperren... |
|||
* Zusaettzlich sollte man vielleicht noch ein Priorisierung irgendwo |
|||
* festhalten, um zu verhindern das ein Prozess ewig wartet, weil er immer |
|||
* Pech bei der zuweisung von CPU Zeit hat. |
|||
* |
|||
* So ein Pech, read blockiert natuerlich nicht bei regulären Dateien, da |
|||
* ja EOF erreich wird....da muss ich mir was anderes ausdenken.... |
|||
* OK, unter UNIX kann ich exec mkfifo machen um eine named pipe zu generieren. |
|||
* Fuer windows muss was anderes oder busy waiting (iiieeh) rein.... |
|||
* |
|||
* !!! Zur info, schon der read open auf eine FIFO blocked wenn kein Writer |
|||
* existiert. Das war auch ein aspekt den man berücksichtigen muß... !!! |
|||
*/ |
|||
require_once dirname(__FILE__) . '/config.php'; |
|||
require_once LIBDIR . 'mutualExclusion.php'; |
|||
|
|||
function acquire ($lock, $tmp) |
|||
{ |
|||
if (! file_exists ($tmp)) |
|||
exec ('mkfifo ' . $tmp); |
|||
// hier koennte irgendwas bzgl. der Priorisierung in nem else folgen...
|
|||
|
|||
if (link ($tmp, $lock) === FALSE) |
|||
{ |
|||
while (true) |
|||
{ |
|||
$handle = fopen ($lock, 'w'); |
|||
fwrite ($handel, '1'); |
|||
fclose ($handle); |
|||
if (unlink ($lock) === FALSE) continue; |
|||
if (link ($tmp, $lock) === FALSE) continue; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
unlink ($tmp); |
|||
} |
|||
|
|||
function release ($lock) |
|||
{ |
|||
$handle = fopen ($lock, 'r'); |
|||
stream_set_blocking ($handle, 0); |
|||
if (fread ($handle, 1) === 0) |
|||
unlink ($lock); |
|||
fclose ($handle); |
|||
} |
|||
|
|||
|
|||
acquire ('lock', 'tmp'); |
|||
//session_start ();
|
|||
$lock = acquireLock ('lock/lock', '1'); |
|||
|
|||
echo "Lock bekommen\n"; |
|||
sleep (30); |
|||
sleep (2); |
|||
|
|||
release ('lock'); |
|||
releaseLock ($lock); |
|||
|
|||
?>
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue