Exemplo n.º 1
0
 /**
  * Operations on the transferred data dispatch helper.
  * @param GPhpThreadCriticalSection $inst The instance of the critical section to work with
  * @param int $threadId The identifier of the thread whose critical section is currently dispatched.
  * @return void
  */
 private static function dataDispatch(&$inst, $threadId)
 {
     // {{{
     $msg = $pid = $name = $value = null;
     // Optimize the data receive timeout for each thread
     // based on its:
     // 2. priority
     // 1. threads count for the current critical section
     // 0. total critical sections count
     $dataReceiveTimeoutMs = 700;
     // default timeout
     $dataReceiveTimeoutReducer = 2 - $inst->dispatchPriority;
     $dataReceiveTimeoutReducer += count($inst->mastersThreadSpecificData) - 1;
     $dataReceiveTimeoutReducer += count(self::$instancesCreatedEverAArr) * 2 - 1;
     $dataReceiveTimeoutMs /= $dataReceiveTimeoutReducer;
     $dataReceiveTimeoutMs = (int) $dataReceiveTimeoutMs;
     if ($dataReceiveTimeoutMs == 0) {
         $dataReceiveTimeoutMs = 1;
     }
     // Receive some data
     if (!$inst->receive($msg, $pid, $name, $value, $dataReceiveTimeoutMs)) {
         $inst->dispatchPriority = 0;
         if ($inst->isIntercomBroken()) {
             unset($inst->threadInstanceContext[$threadId]);
         }
         // remove the thread from the dispatching list as soon as we can
         return;
     }
     switch ($msg) {
         case GPhpThreadCriticalSection::$LOCKSYN:
             $inst->dispatchPriority = 1;
             if ($inst->ownerPid !== false && $inst->ownerPid != $pid && $inst->isPidAlive($inst->ownerPid)) {
                 $inst->send(GPhpThreadCriticalSection::$LOCKNACK, null, $pid);
                 return;
             }
             if (!$inst->send(GPhpThreadCriticalSection::$LOCKACK, null, $pid)) {
                 return;
             }
             $inst->ownerPid = $pid;
             $inst->dispatchPriority = 2;
             break;
         case GPhpThreadCriticalSection::$UNLOCKSYN:
             $inst->dispatchPriority = 1;
             if ($inst->ownerPid === false) {
                 if (!$inst->send(GPhpThreadCriticalSection::$UNLOCKACK, null, $pid)) {
                     return;
                 }
             }
             $isOwnerAlive = $inst->isPidAlive($inst->ownerPid);
             if (!$isOwnerAlive || $inst->ownerPid == $pid) {
                 if (!$isOwnerAlive) {
                     $inst->ownerPid = false;
                 }
                 if (!$inst->send(GPhpThreadCriticalSection::$UNLOCKACK, null, $pid)) {
                     return;
                 }
                 $inst->dispatchPriority = 0;
                 $inst->ownerPid = false;
             } else {
                 $inst->send(GPhpThreadCriticalSection::$UNLOCKNACK, null, null);
             }
             break;
         case GPhpThreadCriticalSection::$ADDORUPDATESYN:
             $inst->dispatchPriority = 1;
             if ($inst->ownerPid !== $pid) {
                 $inst->send(GPhpThreadCriticalSection::$ADDORUPDATENACK, null, null);
                 return;
             }
             if (!$inst->send(GPhpThreadCriticalSection::$ADDORUPDATEACK, $name, null)) {
                 return;
             }
             $inst->dispatchPriority = 2;
             $inst->sharedData['rel'][$name] = $value;
             break;
         case GPhpThreadCriticalSection::$UNRELADDORUPDATESYN:
             $inst->dispatchPriority = 1;
             if (!$inst->send(GPhpThreadCriticalSection::$UNRELADDORUPDATEACK, $name, null)) {
                 return;
             }
             $inst->dispatchPriority = 2;
             $inst->sharedData['unrel'][$name] = $value;
             break;
         case GPhpThreadCriticalSection::$ERASESYN:
             $inst->dispatchPriority = 1;
             if ($inst->ownerPid !== $pid) {
                 $inst->send(GPhpThreadCriticalSection::$ERASENACK, null, null);
                 continue;
             }
             if (!$inst->send(GPhpThreadCriticalSection::$ERASEACK, $name, null)) {
                 return;
             }
             $inst->dispatchPriority = 2;
             unset($inst->sharedData['rel'][$name]);
             break;
         case GPhpThreadCriticalSection::$UNRELERASESYN:
             $inst->dispatchPriority = 1;
             if (!$inst->send(GPhpThreadCriticalSection::$ERASEACK, $name, null)) {
                 return;
             }
             $inst->dispatchPriority = 2;
             unset($inst->sharedData['unrel'][$name]);
             break;
         case GPhpThreadCriticalSection::$READSYN:
             $inst->dispatchPriority = 1;
             if ($inst->ownerPid !== $pid) {
                 $inst->send(GPhpThreadCriticalSection::$READNACK, null, null);
                 return;
             }
             $inst->send(GPhpThreadCriticalSection::$READACK, $name, isset($inst->sharedData['rel'][$name]) || array_key_exists($name, $inst->sharedData['rel']) ? $inst->sharedData['rel'][$name] : null);
             $inst->dispatchPriority = 2;
             break;
         case GPhpThreadCriticalSection::$UNRELREADSYN:
             $inst->dispatchPriority = 1;
             $inst->send(GPhpThreadCriticalSection::$UNRELREADACK, $name, isset($inst->sharedData['unrel'][$name]) || array_key_exists($name, $inst->sharedData['unrel']) ? $inst->sharedData['unrel'][$name] : null);
             $inst->dispatchPriority = 2;
             break;
         case GPhpThreadCriticalSection::$READALLSYN:
             $inst->dispatchPriority = 1;
             if ($inst->ownerPid !== $pid) {
                 $inst->send(GPhpThreadCriticalSection::$READALLNACK, null, null);
                 return;
             }
             $inst->send(GPhpThreadCriticalSection::$READALLACK, null, $inst->sharedData);
             $inst->dispatchPriority = 2;
             break;
     }
 }