/** * Constructs a new socket. * * @param string $address Address to make the connection on. * @param string $options Connection options * * @return void */ public function __construct($address, $options = []) { parent::__construct(); $defaults = ['port' => null, 'domain' => AF_INET, 'type' => SOCK_STREAM, 'protocol' => SOL_TCP]; $options += $defaults; $this->_address = $address; $this->_options = $options; /** * TODO * * Shorten this entire loop. */ $this->_idle = new Process(function ($processor) { if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug('Entering socket wait loop'); } $idle = $processor->get_routine()->get_idles_available(); // 30 second default wait $time = 30; $utime = 0; // Determine if another function has requested to execute in x // amount of time if (count($processor->get_routine()->get_signals()) !== 0) { // If we have signals to process only poll and continue $time = 0; } elseif (count($idle) >= 2) { $default_wait_time = time() + $this->default_wait_time; foreach ($idle as $_idle) { // if ($_idle->get_idle() instanceof Time) { // // echo $default_wait_time.PHP_EOL; // // echo $_idle->get_idle()->get_time_until().PHP_EOL; // // echo $_idle->get_idle()->get_time_until() < $default_wait_time.PHP_EOL; // // echo $_idle->get_idle()->get_time_until() > $default_wait_time.PHP_EOL; // // echo $_idle.PHP_EOL; // } // if ($_idle->get_idle() instanceof Time && ( // // $default_wait_time > $_idle->get_idle()->get_time_until())) { // // $time = round($_idle->get_idle()->convert_length( // // $_idle->get_idle()->get_time_left(), // // TIME_SECONDS // // ), 3); // // if ($time > 0 && $time < 1) { // // $utime = $time * 1000; // // $time = 0; // // } // // echo $time.PHP_EOL; // // break; // } } } // establish sockets $re = [$this->_connection->get_resource()]; $wr = $ex = []; foreach ($this->_clients as $_k => $_c) { $_resource = $_c->get_resource(); // test if socket is still connected // send disconnect if disconnect detected if ($_c->is_connected() === false) { xp_emit(new SIG_Disconnect($_c)); unset($this->_clients[$_k]); continue; } else { $re[] = $_resource; $ex[] = $_resource; } } $count = socket_select($re, $wr, $ex, $time, $utime); if ($count === false) { logger(XPSPL_LOG)->debug('Socket wait loop ended PROBLEM'); return false; } elseif ($count == 0) { if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug('Socket wait loop ended no connection changes'); } return true; } if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug('Socket wait loop ended connection changes detected'); } // Check Read if (count($re) !== 0) { foreach ($re as $_r) { if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug(sprintf('Connection Read %s', strval(intval($_r)))); } $id = intval($_r); if (!isset($this->_clients[$id])) { $client = new Client($_r); $id = intval($client->get_resource()); xp_emit(new SIG_Connect($this, $client)); $this->_clients[$id] = $client; if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug(sprintf('Added Connection %s', strval(intval($id)))); } } else { $this->_clients[$id]->_read_buffer(); xp_emit(new SIG_Read($this, $this->_clients[$id])); } } } // Check Write if (count($wr) !== 0) { foreach ($wr as $_write) { if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug(sprintf('Connection Write %s', strval($_write))); } $processor->get_routine()->add_signal(new SIG_Write($this, $this->_clients[intval($_write)])); } } // Errors if (count($ex) !== 0) { foreach ($ex as $_excep) { if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug(sprintf('Connection Exception %s', strval($_excep))); } $this->_clients[intval($_excep)]->error = socket_last_error($_excep); $this->_clients[intval($_excep)]->error_str = socket_strerror($_excep); $processor->get_routine()->add_signal(new SIG_Error($this, $this->_clients[intval($_excep)])); } } }); $this->on_disconnect(xp_priority(PHP_INT_MAX, '\\network\\system_disconnect')); // After processing read clean the buffer xp_after(new SIG_Read($this), xp_low_priority('\\network\\clean_buffer')); // Emit this has started xp_emit($this); }
<?php /** * Copyright 2010-12 Nickolas Whiting. All rights reserved. * Use of this source code is governed by the Apache 2 license * that can be found in the LICENSE file. */ require_once dirname(realpath(__FILE__)) . '/../__init__.php'; xp_import('unittest'); unittest\test(function ($test) { $process = xp_priority(100, null); $test->equal(100, $process->get_priority()); }, 'API Priority');
/** * Creates or sets a process to have a low priority. * * Processes with a low priority will be executed after those with a high * priority. * * .. note:: * * This registers the priority as *PHP_INT_MAX*. * * This is not an interruption. * * After signal interrupts will still be executed after a low priority * process. * * @param callable|process $process PHP Callable or \XPSPL\Process. * * @return object Process * * @example * * Example #1 Basic Usage * * Low priority processes always execute last. * * .. code-block:: php * * <?php * * xp_signal(XP_SIG('foo'), xp_low_priority(function(){ * echo 'bar'; * })); * * xp_signal(XP_SIG('foo'), function(){ * echo 'foo'; * }); * * xp_emit(XP_SIG('foo')); * * The above code will output. * * .. code-block:: php * * foobar */ function xp_low_priority($process) { return xp_priority(PHP_INT_MAX, $process); }
/** * Creates or sets a process to have a high priority. * * Processes with a high priority will be executed before those with * a low or default priority. * * This will register the priority as *0* as priority goes in ascending order. * * .. note:: * * Interruptions will be executed before high priority processes. * * @param callable|process $process PHP Callable or \XPSPL\Process. * * @return object Process * * @example * * Example #1 Basic Usage * * Basic usage example demonstrating high priority processes. * * .. code-block:: php * * <?php * * // Register a process on the foo signal * xp_signal(XP_SIG('foo'), function(){ * echo 'bar'; * }); * * // Register another process with high priority * xp_signal(XP_SIG('foo'), xp_high_priority(function(){ * echo 'foo'; * })); * * The above code will output. * * .. code-block:: php * * foobar */ function xp_high_priority($process) { return xp_priority(0, $process); }