public function countFiles(array $files, $countTests)
 {
     $chunkSize = ceil(count($files) / $this->_cores);
     $chunks = array_chunk($files, $chunkSize);
     $forks = array();
     $sockets = array();
     for ($i = 0; $i < $this->_cores; $i++) {
         if (socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets) === false) {
             echo "socket_create_pair failed. Reason: " . socket_strerror(socket_last_error());
         }
         $this->socketPairs[] = $sockets;
         $forks[] = $pid = pcntl_fork();
         if ($pid === 0) {
             parent::countFiles($chunks[$i], $countTests);
             $data = array('count' => $this->count, 'namespaces' => $this->namespaces);
             $dataString = serialize($data);
             socket_set_nonblock($sockets[0]);
             if (socket_write($sockets[0], str_pad($dataString, self::MESSAGE_LENGTH), self::MESSAGE_LENGTH) === false) {
                 throw new Exception("socket_write() failed. Reason: " . socket_strerror(socket_last_error($sockets[0])));
             }
             socket_close($sockets[0]);
             die;
         }
     }
     do {
         pcntl_wait($status);
         array_pop($forks);
     } while (count($forks) > 0);
     for ($i = 0; $i < $this->_cores; $i++) {
         $sockets = $this->socketPairs[$i];
         $childMessage = '';
         $childMessage = socket_read($sockets[1], self::MESSAGE_LENGTH);
         $data = unserialize(trim($childMessage));
         socket_close($sockets[1]);
         $this->mergeAndSumCount($data['count']);
         $this->mergeNamespaces($data['namespaces']);
         // $this->mergeDirectories($data['directories']);
     }
     // need to find some way to pass the number of directories from the child to the paent so
     // we don't have to do this again
     // same with namespaces which are also a object variable
     $count = $this->getCount($countTests);
     foreach ($files as $file) {
         $directory = dirname($file);
         if (!isset($directories[$directory])) {
             $directories[$directory] = TRUE;
         }
     }
     $count['directories'] = count($directories) - 1;
     return $count;
 }
Exemple #2
0
function async($thunk)
{
    // By creating a socket pair, we have a channel of communication
    // between PHP processes
    socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets);
    list($parent, $child) = $sockets;
    if (($pid = pcntl_fork()) == 0) {
        // We're in the child process now
        socket_close($child);
        // Call the thunk, serialize the returned value, and send it
        // through the channel we created (ie. to the parent process)
        socket_write($parent, serialize(call_user_func($thunk)));
        socket_close($parent);
        exit;
        // We're done so we can exit here
    }
    socket_close($parent);
    return array($pid, $child);
    // This can treated as a "thread handle"
}
function pleac_Communicating_Between_Related_Processes()
{
    // PHP supports fork/exec/wait but not pipe. However, it does
    // support socketpair, which can do everything pipes can as well
    // as bidirectional communication. The original recipes have been
    // modified here to use socketpair only.
    // -----------------------------
    // pipe1 - use socketpair and fork so parent can send to child
    $sockets = array();
    if (!socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets)) {
        die(socket_strerror(socket_last_error()));
    }
    list($reader, $writer) = $sockets;
    $pid = pcntl_fork();
    if ($pid == -1) {
        die('cannot fork');
    } elseif ($pid) {
        socket_close($reader);
        $line = sprintf("Parent Pid %d is sending this\n", getmypid());
        if (!socket_write($writer, $line, strlen($line))) {
            socket_close($writer);
            die(socket_strerror(socket_last_error()));
        }
        socket_close($writer);
        pcntl_waitpid($pid, $status);
    } else {
        socket_close($writer);
        $line = socket_read($reader, 1024, PHP_NORMAL_READ);
        printf("Child Pid %d just read this: `%s'\n", getmypid(), rtrim($line));
        socket_close($reader);
        // this will happen anyway
        exit(0);
    }
    // -----------------------------
    // pipe2 - use socketpair and fork so child can send to parent
    $sockets = array();
    if (!socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets)) {
        die(socket_strerror(socket_last_error()));
    }
    list($reader, $writer) = $sockets;
    $pid = pcntl_fork();
    if ($pid == -1) {
        die('cannot fork');
    } elseif ($pid) {
        socket_close($writer);
        $line = socket_read($reader, 1024, PHP_NORMAL_READ);
        printf("Parent Pid %d just read this: `%s'\n", getmypid(), rtrim($line));
        socket_close($reader);
        pcntl_waitpid($pid, $status);
    } else {
        socket_close($reader);
        $line = sprintf("Child Pid %d is sending this\n", getmypid());
        if (!socket_write($writer, $line, strlen($line))) {
            socket_close($writer);
            die(socket_strerror(socket_last_error()));
        }
        socket_close($writer);
        // this will happen anyway
        exit(0);
    }
    // -----------------------------
    // pipe3 and pipe4 demonstrate the use of perl's "forking open"
    // feature to reimplement pipe1 and pipe2. pipe5 uses two pipes
    // to simulate socketpair. Since PHP supports socketpair but not
    // pipe, and does not have a "forking open" feature, these
    // examples are skipped here.
    // -----------------------------
    // pipe6 - bidirectional communication using socketpair
    $sockets = array();
    if (!socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets)) {
        die(socket_strerror(socket_last_error()));
    }
    list($child, $parent) = $sockets;
    $pid = pcntl_fork();
    if ($pid == -1) {
        die('cannot fork');
    } elseif ($pid) {
        socket_close($parent);
        $line = sprintf("Parent Pid %d is sending this\n", getmypid());
        if (!socket_write($child, $line, strlen($line))) {
            socket_close($child);
            die(socket_strerror(socket_last_error()));
        }
        $line = socket_read($child, 1024, PHP_NORMAL_READ);
        printf("Parent Pid %d just read this: `%s'\n", getmypid(), rtrim($line));
        socket_close($child);
        pcntl_waitpid($pid, $status);
    } else {
        socket_close($child);
        $line = socket_read($parent, 1024, PHP_NORMAL_READ);
        printf("Child Pid %d just read this: `%s'\n", getmypid(), rtrim($line));
        $line = sprintf("Child Pid %d is sending this\n", getmypid());
        if (!socket_write($parent, $line, strlen($line))) {
            socket_close($parent);
            die(socket_strerror(socket_last_error()));
        }
        socket_close($parent);
        exit(0);
    }
}
Exemple #4
0
 /**
  * Creates a pair of indistinguishable sockets and stores them in an array.
  *
  * <p>Creates two connected and indistinguishable sockets. This function is commonly used in IPC (InterProcess
  * Communication).</p>
  *
  * @param int $domain   <p>The domain parameter specifies the protocol family to be used by the socket. See
  *                      <code>create()</code> for the full list.</p>
  * @param int $type     <p>The type parameter selects the type of communication to be used by the socket. See
  *                      <code>create()</code> for the full list.</p>
  * @param int $protocol <p>The protocol parameter sets the specific protocol within the specified domain to be used
  *                      when communicating on the returned socket. The proper value can be retrieved by name by using
  *                      <code>getprotobyname()</code>. If the desired protocol is TCP, or UDP the corresponding constants
  *                      <code>SOL_TCP</code>, and <code>SOL_UDP</code> can also be used. See <code>create()</code> for the full list of
  *                      supported protocols.
  *
  * @throws Exception\SocketException If the creation of the php sockets is not successful.
  *
  * @see Socket::create()
  *
  * @return Socket[] An array of Socket objects containing identical sockets.
  */
 public static function createPair($domain, $type, $protocol)
 {
     $array = [];
     $return = @socket_create_pair($domain, $type, $protocol, $array);
     if ($return === false) {
         throw new SocketException();
     }
     $sockets = self::constructFromResources($array);
     foreach ($sockets as $socket) {
         $socket->domain = $domain;
         $socket->type = $type;
         $socket->protocol = $protocol;
     }
     return $sockets;
 }
Exemple #5
0
 /**
  *
  */
 public function __construct()
 {
     $this->tty_fd = fopen("/dev/tty", "r+b");
     if (!$this->tty_fd) {
         throw new InitalizationException("Cannot open /dev/tty");
     }
     $terminalDetector = new TerminalDetector();
     $this->terminal = $terminalDetector->detect();
     socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $this->winch_sockets);
     $this->old_tty_settings = $this->getTtySettings();
     $this->setTTYSettings(array('-ignbrk', '-brkint', '-ignpar', '-parmrk', '-inpck', '-istrip', '-inlcr', '-igncr', '-icrnl', '-ixon', '-ixoff', '-iuclc', '-ixany', '-imaxbel', '-opost', '-isig', '-icanon', '-iexten', '-parenb', 'cs8', 'time', '0', 'min', '0'));
     $this->input_buffer = new ByteBuffer(128, $this->terminal);
     $this->output_buffer = new ByteBuffer(32 * 1024, $this->terminal);
     $this->output_buffer->putsFunc(TerminalFunc::T_ENTER_CA);
     $this->output_buffer->putsFunc(TerminalFunc::T_ENTER_KEYPAD);
     $this->output_buffer->putsFunc(TerminalFunc::T_HIDE_CURSOR);
     $this->sendClear();
     $this->updateTerminalSize();
     pcntl_signal(SIGWINCH, array($this, 'sigwinchhandler'));
     $this->back_buffer = new CellBuffer($this->term_width, $this->term_height, $this->foreground, $this->background);
     $this->front_buffer = new CellBuffer($this->term_width, $this->term_height, $this->foreground, $this->background);
 }
 /**
  * Execute a Closure as another process in the background while showing a
  * status update. The status update can be an indefinite spinner or a string
  * periodically sent from the background process, depending on whether the
  * provided Closure object has a $socket parameter or not. Messaging to the
  * main process is done by socket_* functions. The return value is either
  * the return value of the background process, or false if the process fork
  * failed.
  *
  * @param callable $callable Closure object
  * @return bool|int
  * @throws \Exception
  */
 public static function work(\Closure $callable)
 {
     if (!extension_loaded('pcntl')) {
         throw new \Exception('pcntl extension required');
     }
     if (!extension_loaded('sockets')) {
         throw new \Exception('sockets extension required');
     }
     $spinner = array('|', '/', '-', '\\');
     $i = 0;
     $l = count($spinner);
     $delay = 100000;
     $func = new \ReflectionFunction($callable);
     $socket = (bool) $func->getNumberOfParameters();
     if ($socket) {
         $sockets = array();
         if (socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets) === false) {
             return false;
         }
     }
     $pid = pcntl_fork();
     if ($pid > 0) {
         $done = false;
         $retval = 0;
         pcntl_signal(SIGCHLD, function () use($pid, &$done, &$retval) {
             $child_pid = pcntl_waitpid($pid, $status);
             if (pcntl_wifexited($status)) {
                 $retval = pcntl_wexitstatus($status);
             }
             $done = true;
         });
         if ($socket) {
             $text = '';
             while (!$done) {
                 $r = array($sockets[1]);
                 $w = null;
                 $e = null;
                 if ($status = socket_select($r, $w, $e, 0)) {
                     $data = socket_read($sockets[1], 4096, PHP_NORMAL_READ);
                     if ($data === false) {
                         throw new \Exception(sprintf('socket write error %s', socket_strerror(socket_last_error($sockets[1]))));
                     }
                     echo str_repeat(chr(8), strlen($text));
                     $text = rtrim($data, "\n");
                     Console::stdout($text);
                 } else {
                     pcntl_signal_dispatch();
                 }
                 usleep($delay);
             }
             echo str_repeat(chr(8), strlen($text));
             socket_close($sockets[0]);
             socket_close($sockets[1]);
         } else {
             while (!$done) {
                 pcntl_signal_dispatch();
                 echo $spinner[$i];
                 usleep($delay);
                 echo chr(8);
                 $i = $i === $l - 1 ? 0 : $i + 1;
             }
         }
         return $retval;
     } elseif ($pid === 0) {
         if ($socket) {
             call_user_func($callable, $sockets[0]);
         } else {
             call_user_func($callable);
         }
         exit;
     } else {
         // Unable to fork process.
         return false;
     }
 }
 /**
  * Creates the worker pool (forks the children)
  *
  * Please close all open resources before running this function.
  * Child processes are going to close all open resources uppon exit,
  * leaving the parent process behind with invalid resource handles.
  * @param \QXS\WorkerPool\WorkerInterface $worker the worker, that runs future tasks
  * @throws \RuntimeException
  * @throws WorkerPoolException
  * @return WorkerPool
  */
 public function create(WorkerInterface $worker)
 {
     if ($this->workerPoolSize <= 1) {
         $this->workerPoolSize = 2;
     }
     $this->parentPid = getmypid();
     $this->worker = $worker;
     if ($this->created) {
         throw new WorkerPoolException('The pool has already been created.');
     }
     $this->created = TRUE;
     // when adding signals use pcntl_signal_dispatch(); or declare ticks
     foreach ($this->signals as $signo) {
         pcntl_signal($signo, array($this, 'signalHandler'));
     }
     // no Semaphore attached? -> create one
     if (!$this->semaphore instanceof Semaphore) {
         $this->semaphore = new Semaphore();
         $this->semaphore->create(Semaphore::SEM_RAND_KEY);
     } elseif (!$this->semaphore->isCreated()) {
         $this->semaphore->create(Semaphore::SEM_RAND_KEY);
     }
     ProcessDetails::setProcessTitle($this->parentProcessTitleFormat, array('basename' => basename($_SERVER['PHP_SELF']), 'fullname' => $_SERVER['PHP_SELF'], 'class' => get_class($this)));
     for ($i = 1; $i <= $this->workerPoolSize; $i++) {
         $sockets = array();
         if (socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets) === FALSE) {
             // clean_up using posix_kill & pcntl_wait
             throw new \RuntimeException('socket_create_pair failed.');
             break;
         }
         $processId = pcntl_fork();
         if ($processId < 0) {
             // cleanup using posix_kill & pcntl_wait
             throw new \RuntimeException('pcntl_fork failed.');
             break;
         } elseif ($processId === 0) {
             // WE ARE IN THE CHILD
             $this->workerProcesses = new ProcessDetailsCollection();
             // we do not have any children
             $this->workerPoolSize = 0;
             // we do not have any children
             socket_close($sockets[1]);
             // close the parent socket
             $this->runWorkerProcess($worker, new SimpleSocket($sockets[0]), $i);
         } else {
             // WE ARE IN THE PARENT
             socket_close($sockets[0]);
             // close child socket
             // create the child
             $this->workerProcesses->addFree(new ProcessDetails($processId, new SimpleSocket($sockets[1])));
         }
     }
     return $this;
 }
Exemple #8
0
 /**
  * Creates a pair of sockets
  *
  */
 public static function create_pair($domain, $type, $protocol)
 {
     $created = @socket_create_pair($domain, $type, $protocol, $fd);
     if ($created === false) {
         throw new Socket_Exception("Failed to create socket pair", socket_last_error());
     }
     $ret = array(new self($fd[0]), new self($fd[1]));
     return $ret;
 }
Exemple #9
0
function index($aResult, $sDatabaseDSN)
{
    $oDB =& DB::connect($sDatabaseDSN . '?new_link=true', array('persistent' => false));
    if (PEAR::IsError($oDB)) {
        echo $oDB->getMessage() . "\n";
        exit;
    }
    $oDB->setFetchMode(DB_FETCHMODE_ASSOC);
    $oDB->query("SET DateStyle TO 'sql,european'");
    $oDB->query("SET client_encoding TO 'utf-8'");
    if (!isset($aResult['index-estrate']) || $aResult['index-estrate'] < 1) {
        $aResult['index-estrate'] = 30;
    }
    if (getBlockingProcesses() > $aResult['max-blocking']) {
        echo "Too many blocking processes for index\n";
        exit;
    }
    if ($aResult['index-instances'] > 1) {
        $aInstances = array();
        for ($iInstance = 0; $iInstance < $aResult['index-instances']; $iInstance++) {
            $aInstances[$iInstance] = array('iPID' => null, 'hSocket' => null, 'bBusy' => false);
            socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $aSockets);
            $iPID = pcntl_fork();
            if ($iPID == -1) {
                die('Could not fork Process');
            }
            if (!$iPID) {
                // THIS IS THE CHILD PROCESS
                // Reconnect to database - reusing the same connection is not a good idea!
                $oDBChild =& DB::connect($sDatabaseDSN . '?new_link=true', array('persistent' => false));
                if (PEAR::IsError($oDBChild)) {
                    echo $oDBChild->getMessage() . "\n";
                    exit;
                }
                $oDBChild->setFetchMode(DB_FETCHMODE_ASSOC);
                $oDBChild->query("SET DateStyle TO 'sql,european'");
                $oDBChild->query("SET client_encoding TO 'utf-8'");
                socket_close($aSockets[1]);
                $hSocket = $aSockets[0];
                while ($sRead = socket_read($hSocket, 1000, PHP_BINARY_READ)) {
                    if ($sRead == 'EXIT') {
                        break;
                    }
                    $aSector = unserialize($sRead);
                    echo " - {$iInstance} processing " . $aSector['geometry_index'] . "\n";
                    indexSector($oDBChild, $aSector, $aResult['max-blocking'], $aResult['max-load']);
                    socket_write($hSocket, 'DONE');
                    echo " - {$iInstance} finished " . $aSector['geometry_index'] . "\n";
                }
                socket_close($hSocket);
                exit;
                // THIS IS THE END OF THE CHILD PROCESS
            }
            $aInstances[$iInstance]['iPID'] = $iPID;
            socket_close($aSockets[0]);
            socket_set_nonblock($aSockets[1]);
            $aInstances[$iInstance]['hSocket'] = $aSockets[1];
        }
    }
    // Re-index the new items
    if (!isset($aResult['index-rank']) || !$aResult['index-rank']) {
        $aResult['index-rank'] = 0;
    }
    for ($i = $aResult['index-rank']; $i <= 30; $i++) {
        echo "Rank: {$i}";
        $iStartTime = date('U');
        flush();
        $sSQL = 'select geometry_index(geometry,indexed,name),count(*) from placex where rank_search = ' . $i . ' and indexed = false and name is not null group by geometry_index(geometry,indexed,name)';
        $sSQL .= ' order by count desc';
        $aAllSectors = $oDB->getAll($sSQL);
        if (PEAR::isError($aAllSectors)) {
            var_dump($aAllSectors);
            exit;
        }
        $iTotalNum = 0;
        foreach ($aAllSectors as $aSector) {
            $iTotalNum += $aSector['count'];
        }
        $iTotalLeft = $iTotalNum;
        echo ", total to do: {$iTotalNum} \n";
        flush();
        $fRankStartTime = time();
        $iTotalDone = 0;
        $fRate = $aResult['index-estrate'];
        foreach ($aAllSectors as $aSector) {
            $aSector['rank'] = $i;
            if ($aSector['rank'] == 21 && $aSector['geometry_index'] == 617467) {
                echo "Skipping sector 617467 @ 21 due to issue\n";
                continue;
            }
            while (getBlockingProcesses() > $aResult['max-blocking'] || getLoadAverage() > $aResult['max-load']) {
                echo "System busy, pausing indexing...\n";
                sleep(60);
            }
            $iEstSeconds = (int) ($iTotalLeft / $fRate);
            $iEstDays = floor($iEstSeconds / (60 * 60 * 24));
            $iEstSeconds -= $iEstDays * (60 * 60 * 24);
            $iEstHours = floor($iEstSeconds / (60 * 60));
            $iEstSeconds -= $iEstHours * (60 * 60);
            $iEstMinutes = floor($iEstSeconds / 60);
            $iEstSeconds -= $iEstMinutes * 60;
            $iNum = $aSector['count'];
            $sRate = round($fRate, 1);
            echo $aSector['geometry_index'] . ": {$iNum}, {$iTotalLeft} left.  Est. time remaining (rank {$i}) d:{$iEstDays} h:{$iEstHours} m:{$iEstMinutes} s:{$iEstSeconds} @ {$sRate} per second\n";
            flush();
            if ($aResult['index-instances'] > 1) {
                // Wait for a non-busy socket
                while (true) {
                    for ($iInstance = 0; $iInstance < $aResult['index-instances']; $iInstance++) {
                        if (!$aInstances[$iInstance]['bBusy']) {
                            break 2;
                        }
                        $sRead = socket_read($aInstances[$iInstance]['hSocket'], 10, PHP_BINARY_READ);
                        if ($sRead == 'DONE') {
                            $aInstances[$iInstance]['bBusy'] = false;
                            $iTotalDone += $iNum;
                            $iTotalLeft -= $iNum;
                            break 2;
                        }
                    }
                    usleep(1000);
                }
                echo "Dispatch to {$iInstance} (" . $aInstances[$iInstance]['iPID'] . ")\n";
                socket_write($aInstances[$iInstance]['hSocket'], serialize($aSector));
                $aInstances[$iInstance]['bBusy'] = true;
            } else {
                indexSector($oDB, $aSector, $aResult['max-blocking'], $aResult['max-load']);
                $iTotalDone += $iNum;
                $iTotalLeft -= $iNum;
            }
            $fDuration = time() - $fRankStartTime;
            if ($fDuration) {
                $fRate = $iTotalDone / $fDuration;
            } else {
                $fRate = $aResult['index-estrate'];
            }
        }
        if ($aResult['index-instances'] > 1) {
            // Wait for a non-busy socket
            $bPending = true;
            while ($bPending) {
                $bPending = false;
                for ($iInstance = 0; $iInstance < $aResult['index-instances']; $iInstance++) {
                    if ($aInstances[$iInstance]['bBusy']) {
                        if (socket_read($aInstances[$iInstance]['hSocket'], 10, PHP_BINARY_READ) == 'DONE') {
                            $aInstances[$iInstance]['bBusy'] = false;
                        } else {
                            $bPending = true;
                        }
                    }
                }
                if ($bPending) {
                    usleep(1000000);
                }
            }
        }
        $iDuration = date('U') - $iStartTime;
        if ($iDuration && $iTotalNum) {
            echo "Finished Rank: {$i} in {$iDuration} @ " . $iTotalNum / $iDuration . " per second\n";
        }
    }
    if ($aResult['index-instances'] > 1) {
        for ($iInstance = 0; $iInstance < $aResult['index-instances']; $iInstance++) {
            socket_write($aInstances[$iInstance]['hSocket'], 'EXIT');
            socket_close($aInstances[$iInstance]['hSocket']);
        }
    }
}
Exemple #10
0
 /**
  * Creates a pair of indistinguishable sockets and stores them in an array
  *
  * @param int    $domain   The protocol family to be used by the socket
  * @param int    $type     The type of communication to be used by the socket
  * @param int    $protocol The specific protocol within the specified domain
  * @param array  $fd       Reference to an array in which the two socket resources will be inserted
  */
 public final function socketCreatePair($domain, $type, $protocol, array &$fd)
 {
     return socket_create_pair($domain, $type, $protocol, $fd);
 }
 function executeFork()
 {
     $this->output("Spawning {$this->procCount} child processes.\n");
     $this->children = array();
     for ($fork = 0; $fork < $this->procCount; $fork++) {
         $ok = socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $fd);
         if (!$ok) {
             throw new Exception("Could not create UNIX socket");
         }
         $pid = pcntl_fork();
         if ($pid == 0) {
             $this->isChild = true;
             foreach ($this->sockets as $old) {
                 socket_close($old);
             }
             socket_close($fd[0]);
             break;
         } else {
             if ($pid == -1) {
                 throw new Exception("Could not fork");
             }
             socket_close($fd[1]);
             $this->children[] = $pid;
             $this->sockets[] = $fd[0];
         }
     }
     if ($this->isChild) {
         $this->childNumber = $fork;
         $this->channel = $fd[1];
         $this->executeWorker();
         socket_close($this->channel);
     } else {
         $this->executeParent();
     }
 }
Exemple #12
0
 /**
  * Parent child communcation sockets creation
  */
 private function createParentChildComm()
 {
     $this->log(self::LOG_LEVEL_NORMAL, 'Preparing inter-process communication sockets...');
     $sockets = array();
     if (!socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets)) {
         throw new Exception(socket_strerror(socket_last_error()));
     }
     list($this->readerSocket, $this->writerSocket) = $sockets;
     socket_set_nonblock($this->readerSocket);
     socket_set_nonblock($this->writerSocket);
 }
Exemple #13
0
 /**
  * Forks and creates a socket pair for communication between parent and child process
  *
  * @param resource $socket
  *
  * @return int PID if master or 0 if child
  */
 private function fork(&$socket)
 {
     $pair = [];
     if (socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $pair) === false) {
         $this->logger->error('{type}: Unable to create socket pair; ' . socket_strerror(socket_last_error($pair[0])), $this->logContext);
         exit(0);
     }
     $PID = Qless::fork();
     if ($PID !== 0) {
         // MASTER
         $this->childProcesses++;
         $socket = $pair[0];
         socket_close($pair[1]);
         socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ['sec' => 0, 'usec' => 10000]);
         // wait up to 10ms to receive data
         return $PID;
     }
     $socket = $pair[1];
     socket_close($pair[0]);
     $reserved = str_repeat('x', 20240);
     register_shutdown_function(function () use(&$reserved, $socket) {
         // shutting down
         if (null === ($error = error_get_last())) {
             return;
         }
         unset($reserved);
         $type = $error['type'];
         if (!isset(self::$ERROR_CODES[$type])) {
             return;
         }
         $this->logger->debug('Sending error to master', $this->logContext);
         $data = serialize($error);
         while (($len = socket_write($socket, $data)) > 0) {
             $data = substr($data, $len);
         }
     });
     return $PID;
 }
<?php

$sockets = array();
socket_create_pair(strtoupper(substr(PHP_OS, 0, 3)) == "WIN" ? AF_INET : AF_UNIX, SOCK_STREAM, 0, $sockets);
$parent_sock = $sockets[0];
$child_sock = $sockets[1];
unset($sockets);
$pid = pcntl_fork();
if ($pid == -1) {
    console("[-] Failed to fork");
    define("THREADED", false);
} elseif ($pid) {
    //Parent
    socket_close($child_sock);
    define("THREADED", true);
    define("CHILD", false);
} else {
    //Child
    define("CHILD", true);
    socket_close($parent_sock);
    forking_runtime($child_sock);
    posix_kill(getmypid(), 9);
}
function forking_runtime($IOsock)
{
    global $sock, $buffer, $chunks;
    socket_set_nonblock($IOsock);
    $last = time();
    while ($sock) {
        buffer();
        if ($last + 10 < time()) {
Exemple #15
0
        $this->bClosed = true;
        socket_shutdown($this->sckSocket);
        socket_close($this->sckSocket);
    }
}
/*********************************************************************************
                   Main program start here
   *********************************************************************************/
/* Loading modules */
include _MODULES_PATH_ . "plugwise_usb.php";
writelog("Starting Main Program...");
foreach ($process as $processname => $module) {
    writelog("Creating IPC Socket for module {$processname} ...");
    /*  Trying to create socket pair */
    /*  Unable to create socket pair */
    if (socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $process[$processname]["socket"]) === false) {
        writelog("socket_create_pair() a échoué. Raison : " . socket_strerror(socket_last_error()));
    } else {
        writelog("opening socket pair for {$processname} : OK");
        /* Forking module*/
        $pid = pcntl_fork();
        /***********************************
           /*  Starting modules (child)
           ***********************************/
        if (!$pid) {
            switch ($module["bootstrap"]) {
                case $process[$processname]["bootstrap"]:
                    writelog("Starting module {$processname} ...");
                    include _MODULES_PATH_ . $process[$processname]["driver"];
                    writelog($process[$processname]["bootstrap"] . ": finished");
                    exit(0);
 /**
  * Returns a new socket pair to simulate a real socket implementation.
  *
  * @throws \Exception Is thrown if the socket pair can't be craeted
  * @return array The socket pair
  */
 public function getSocketPair()
 {
     // initialize the array for the socket pair
     $sockets = array();
     // on Windows we need to use AF_INET
     $domain = strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' ? AF_INET : AF_UNIX;
     // setup and return a new socket pair
     if (socket_create_pair($domain, SOCK_STREAM, 0, $sockets) === false) {
         throw new \Exception("socket_create_pair failed. Reason: " . socket_strerror(socket_last_error()));
     }
     // return the array with the socket pair
     return $sockets;
 }
 /**
  * Initialize interprocess communication by setting up a pair
  * of sockets and returning them as an array.
  *
  * @return type
  */
 private function ipc_init()
 {
     // windows needs AF_INET
     $domain = strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' ? AF_INET : AF_UNIX;
     // create a socket pair for IPC
     $sockets = array();
     if (socket_create_pair($domain, SOCK_STREAM, 0, $sockets) === false) {
         $this->log('socket_create_pair failed: ' . socket_strerror(socket_last_error()), self::LOG_LEVEL_CRIT);
         return false;
     }
     // return the sockets
     return $sockets;
 }
Exemple #18
0
 /**
  * Do something asynchronously.
  *
  * This neat little method sets up a UNIX socket for IPC, and then forks the current process.
  * The child is then able to talk to the parent, by way of a return value.
  *
  * @param callable A callback that is running in the forked instance. Anything returned will be captured by the main process.
  *
  * @return int The PID of the child process, for keeping track of your children.
  */
 function async($function)
 {
     socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets);
     // IPC
     list($parent, $child) = $sockets;
     if (($pid = pcntl_fork()) == 0) {
         // In child process now
         socket_close($child);
         socket_write($parent, serialize(call_user_func($function, $this)));
         socket_close($parent);
         exit;
     }
     socket_close($parent);
     $this->child[$pid] = $child;
     return $pid;
 }
Exemple #19
0
/*
foreach (new \DirectoryIterator(__DIR__.'/concurrent/') as $item) {
    $name = (string) $item;
    if (!$item->isFile() || $name[0] == '.' || !ends_with($name, '.php')) 
        continue;

    $tests[$testName] = require $item->getPathname(); 
}
*/
$tests = (require __DIR__ . '/concurrent-tests.php');
$parentPid = posix_getpid();
$workers = [];
$failMessages = [];
$pairs = [];
for ($id = 0; $id < $config->workerCount; $id++) {
    if (!socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $pair)) {
        die;
    }
    $childPid = pcntl_fork();
    if ($childPid) {
        socket_close($pair[1]);
        $workers[] = ['id' => $id, 'pid' => $childPid, 'socket' => $pair[0], 'socketId' => intval($pair[0])];
    } else {
        socket_close($pair[0]);
        return run_worker_process($id, $pair[1]);
    }
}
return run_parent_process($workers, $argv);
function run_parent_process($workers, $argv)
{
    global $tests;
 public function send($local, $remote)
 {
     $this->file_size = filesize($local);
     $sockets = array();
     if (socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets) === false) {
         throw new Exception("socket_create_pair failed. Reason: " . socket_strerror(socket_last_error()));
     }
     $this->parent_socket = $sockets[1];
     $this->child_socket = $sockets[0];
     socket_set_nonblock($this->parent_socket);
     socket_set_nonblock($this->child_socket);
     $this->pid = pcntl_fork();
     if ($this->pid == -1) {
         throw new Exception('Could not fork');
     } else {
         if (!$this->pid) {
             //THIS IS THE CHILD PROCESS
             $this->signalInit();
             $total_sent = 0;
             if ($in = fopen($local, 'r')) {
                 $this->attempts = 0;
                 $total_read = 0;
                 $total_written = 0;
                 $this->signalOpeningConnection($this->file_size);
                 $trans_fp = fsockopen('127.0.0.1', '4000');
                 $response = fread($trans_fp, 28);
                 if (strpos($response, '200') !== FALSE) {
                     $this->signalGotConnection();
                     fwrite($trans_fp, $remote);
                     $response = fread($trans_fp, 22);
                     if (strpos($response, '100') !== FALSE) {
                         $this->signalCreatedRemoteFile();
                         while (!feof($in) && !$this->cancelled()) {
                             $read_count = 0;
                             $cur_data = '';
                             $cur_data = fread($in, 1048576);
                             $total_read += 1048576;
                             $this->attempts = 0;
                             $res = fwrite($trans_fp, $cur_data);
                             $total_written += $res;
                             $this->signalDataWritten($total_written);
                             if ($res < strlen($cur_data)) {
                                 while ($res < strlen($cur_data) && !$this->cancelled()) {
                                     $length = strlen($cur_data) - $res;
                                     $cur_data = substr($cur_data, $res, $length);
                                     $res = fwrite($trans_fp, $cur_data);
                                     $this->signalDataWritten($total_written);
                                     $total_written += $res;
                                     $this->attempt();
                                 }
                                 $this->resetAttempts();
                             }
                             $response = fread($trans_fp, 24);
                             while (strpos($response, '100') !== FALSE && !$this->cancelled() && $total_written > 0) {
                                 $trans = str_replace('100 ', '', trim($response));
                                 $total_written -= $trans;
                                 $total_sent += $trans;
                                 if ($total_written) {
                                     $response = fread($trans_fp, 24);
                                     $this->attempt();
                                 }
                             }
                             $total_written = 0;
                             $this->resetAttempts();
                         }
                         $this->resetAttempts();
                     } else {
                         $this->signalCouldNotCreateRemoteFile();
                     }
                 } else {
                     $this->signalCouldNotGetConnection();
                 }
                 fclose($trans_fp);
             } else {
                 $this->signalNoLocalFile();
             }
             $this->signalStopped($total_sent);
         }
     }
 }
 /**
  * Run job in singlethread mode
  *
  * @param   string  Job unique identifier
  *
  * @return  array   {[pid],[name],[success],[start],[end],[result],[id]}
  */
 private function runMultithread($jobUid)
 {
     $job = $this->jobs[$jobUid];
     // get job start timestamp
     $start_timestamp = microtime(true);
     $this->logger->notice("Starting job " . $job['name'] . "(" . $job['id'] . ")");
     $name = $job['name'];
     $id = $job['id'];
     $parameters = $job['parameters'];
     $task = $job['task'];
     $task_class = $job['class'];
     $this->ipc_array[$jobUid] = array();
     // create a comm socket
     $socket = socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $this->ipc_array[$jobUid]);
     if ($socket === false) {
         $this->logger->error("No IPC communication, aborting", array("JOBUID" => $jobUid, "ERROR" => socket_strerror(socket_last_error()), "ERRID" => null));
         array_push($this->completed_processes, array(null, $name, false, $start_timestamp, microtime(true), 'No IPC communication, exiting - ' . socket_strerror(socket_last_error()), $id, null));
         return array("pid" => null, "name" => $name, "uid" => $jobUid, "timestamp" => $start_timestamp, "id" => $id);
     }
     list($reader, $writer) = $this->ipc_array[$jobUid];
     $pid = pcntl_fork();
     if ($pid == -1) {
         $this->logger->error("Could not fok job, aborting");
         array_push($this->completed_processes, array(null, $name, false, $start_timestamp, microtime(true), 'Could not fok job', $id, null));
     } elseif ($pid) {
         //PARENT will take actions on processes later
         self::adjustNiceness($pid, $this->logger);
     } else {
         socket_close($reader);
         $thetask = new $task_class($parameters, $this->logger, null, $name, $start_timestamp, true, $id);
         try {
             $result = $thetask->start();
             $return = serialize(array("success" => $result["success"], "result" => $result["result"], "timestamp" => $result["timestamp"], "worklogid" => $result["worklogid"]));
             $exit = 0;
         } catch (TaskException $te) {
             $return = serialize(array("success" => false, "result" => $te->getMessage(), "timestamp" => $te->getEndTimestamp(), "worklogid" => $te->getWorklogId()));
             $exit = 1;
         } catch (Exception $e) {
             $return = serialize(array("success" => false, "result" => $e->getMessage(), "timestamp" => microtime(true), "worklogid" => null));
             $exit = 1;
         }
         if (socket_write($writer, $return, strlen($return)) === false) {
             $this->logger->error("socket_write() failed ", array("ERROR" => socket_strerror(socket_last_error($writer))));
         }
         socket_close($writer);
         exit($exit);
     }
     return array("pid" => $pid == -1 ? null : $pid, "name" => $name, "uid" => $jobUid, "id" => $id, "timestamp" => $start_timestamp);
 }
Exemple #22
0
<?php

$msg = "Hello";
$len = strlen($msg);
$sockets = array();
socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets);
socket_write($sockets[0], $msg, $len);
$fdset = array(1 => $sockets[1]);
$write = $excep = array();
socket_select($fdset, $write, $excep, 0, 100);
print_r($fdset);
<?php

$sockets = array();
$domain = AF_INET;
socket_create_pair($domain, SOCK_STREAM, 0, $sockets);
$write = null;
$except = null;
$time = -1;
var_dump(socket_select($sockets, $write, $except, $time));
 /**
  * Creates a pair of indistinguishable sockets and stores them in an array
  *
  * @param int   $domain   The domain parameter specifies the protocol
  *                        family to be used by the socket. See socket_create
  *                        for the full list.
  * @param int   $type     The type parameter selects the type of communication
  *                        to be used by the socket. See socket_create for the
  *                        full list.
  * @param int   $protocol The protocol parameter sets the specific
  *                        protocol within the specified domain to be used
  *                        when communicating on the returned socket. The proper value can be retrieved by
  *                        name by using getprotobyname. If
  *                        the desired protocol is TCP, or UDP the corresponding constants
  *                        SOL_TCP, and SOL_UDP
  *                        can also be used.
  * @param array $fd       Reference to an array in which the two socket resources will be inserted.
  *
  * @return bool
  */
 public function socketCreatePair(int $domain, int $type, int $protocol, array &$fd) : bool
 {
     return socket_create_pair($domain, $type, $protocol, $fd);
 }
 /**
  * Forks a new child
  *
  * @return   string   'i_am_child' or 'i_am_master'
  */
 private function _mp_fork()
 {
     $this->_debug("-----> " . __CLASS__ . '::' . __FUNCTION__ . '()', 9);
     // Create new socket pair first
     $r = socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $socketPair);
     if ($r === false) {
         throw new A2o_AppSrv_Exception('Unable to create a new socket pair');
     }
     socket_set_nonblock($socketPair[0]);
     socket_set_nonblock($socketPair[1]);
     // Fork then
     $pid = pcntl_fork();
     if ($pid == -1) {
         throw new A2o_AppSrv_Exception('Could not fork');
     }
     if ($pid) {
         // We are a parent/master
         $workerId = $this->_mp_registerWorker($pid, $socketPair[0], $socketPair[1]);
         $this->_debug("worker with pid {$pid} registered");
         usleep(100000);
         // Check if worker is still registered and tell it it's ID
         if ($this->_mp_isWorkerRegistered($workerId)) {
             $this->_ipc_tellWorker_workerId($workerId);
         } else {
             $this->___parent->__log("Worker id={$workerId} died unexpectedly");
         }
         return 'i_am_master';
     } else {
         // We are the child/worker
         //Assign the temporary variables
         $this->__tmp_listenStream = $this->_listenStream;
         $this->__tmp_masterSocket_read = $socketPair[0];
         $this->__tmp_masterSocket_write = $socketPair[1];
         return 'i_am_child';
     }
 }
 /**
  *
  * @param int $i
  * @throws \RuntimeException
  */
 private function createWorker($i)
 {
     $sockets = array();
     if (socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets) === FALSE) {
         // clean_up using posix_kill & pcntl_wait
         throw new \RuntimeException('socket_create_pair failed.');
         return;
     }
     $processId = pcntl_fork();
     if ($processId < 0) {
         // cleanup using posix_kill & pcntl_wait
         throw new \RuntimeException('pcntl_fork failed.');
         return;
     } elseif ($processId === 0) {
         // WE ARE IN THE CHILD
         $this->workerProcesses = new ProcessDetailsCollection();
         // we do not have any children
         $this->workerPoolSize = 0;
         // we do not have any children
         socket_close($sockets[1]);
         // close the parent socket
         $this->runWorkerProcess($this->worker, new SimpleSocket($sockets[0]), $i);
     } else {
         // WE ARE IN THE PARENT
         socket_close($sockets[0]);
         // close child socket
         // create the child
         $this->workerProcesses->addFree(new ProcessDetails($processId, new SimpleSocket($sockets[1])));
         /**
          * Workaround to force destroy() to be called
          * @see https://github.com/qxsch/WorkerPool/issues/4
          */
         if (!isset($this->shutdownRegistered)) {
             register_shutdown_function([$this, 'destroy']);
             $this->shutdownRegistered = true;
         }
     }
 }
Exemple #27
0
 protected function getSockets()
 {
     $domain = strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' ? AF_INET : AF_UNIX;
     socket_create_pair($domain, SOCK_STREAM, 0, $sockets);
     return $sockets;
 }
if (!socket_bind($rxsocket, "0.0.0.0", 44601)) {
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);
    die("Could not bind socket : [{$errorcode}] {$errormsg} \n");
}
echo "RX Socket bind OK \n";
do {
    $authok = false;
    //set authentication to default
    $r = socket_recvfrom($rxsocket, $buf, 512, 0, $remote_ip, $remote_port);
    // check data on socket
    if ($r > 0) {
        //wait for data to be received
        $r = 0;
        /* Setup socket pair */
        if (socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $ary) === false) {
            echo "socket_create_pair() failed. Reason: " . socket_strerror(socket_last_error());
        }
        $pid = pcntl_fork();
        // fork process on new data received into child and parent
        if ($pid == -1) {
            die('could not fork');
        } else {
            if ($pid) {
                // I am parent do not do anything and return to top $r = .....
                socket_close($ary[0]);
                if (($data = socket_read($ary[1], strlen($remote_ip), PHP_BINARY_READ)) === $remote_ip) {
                    array_push($authDevices, $data);
                    //add the ip address to the array of authenticated devices
                    // e('Unit authenticated ok ');
                }
Exemple #29
0
function get_client_server()
{
    $server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    $port = bind_random_port($server, "127.0.0.1");
    var_dump($port != 0);
    var_dump(socket_listen($server));
    $client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    var_dump(socket_connect($client, "127.0.0.1", $port));
    $s = socket_accept($server);
    return array($client, $s);
}
///////////////////////////////////////////////////////////////////////////////
$s = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
var_dump($s);
var_dump(create_listen_random_port() != 0);
var_dump(socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $fds));
var_dump(count($fds));
var_dump(socket_get_option($s, SOL_SOCKET, SO_TYPE), SOCK_STREAM);
list($client, $s) = get_client_server();
var_dump(socket_write($client, "hello world"));
// this could fail with shorter returns, but it never does...
var_dump(socket_read($s, 100));
list($client, $s) = get_client_server();
$reads = array($s);
var_dump(socket_select($reads, $ignore1, $ignore2, 1, 0));
var_dump(socket_write($client, "next select will be 1"));
$reads = array($s);
var_dump(socket_select($reads, $ignore1, $ignore2, 1, 0));
list($client, $s) = get_client_server();
$text = "send/recv";
var_dump(socket_send($client, $text, 4, 0));
    usleep(100000);
    $npid = pcntl_fork();
    if ($npid == -1) {
        errexit("unable to pcntl_fork()");
    } else {
        if ($npid) {
            techo("running in background");
            exit(0);
        }
    }
}
if ($nb_loggers = $conf["global"]["loggerprocess"][0]) {
    // Prepare and spawn logger processes if specified
    techo("spawning loggers");
    $sck_pair = array();
    socket_create_pair(AF_UNIX, SOCK_DGRAM, 0, $sck_pair);
    $children_logsck =& $sck_pair[0];
    $loggers_sck =& $sck_pair[1];
    socket_set_nonblock($loggers_sck);
    spawn_loggers($nb_loggers);
} else {
    // Be sure not to ask anything to loggers
    $conf["global"]["hostnamelookupsby"][0] = "server";
}
if ($posix_av && $conf["global"]["pidfile"][0]) {
    $pidfile = $conf["global"]["pidfile"][0];
    if ($f = fopen($pidfile, "w")) {
        fputs($f, (string) posix_getpid() . "\n");
        fclose($f);
    } else {
        techo("WARN: unable to open pid file '" . $pidfile . "'", NW_EL_WARNING);