/** * Come here to get your number in the requests line! * * @param Position $pos position object to populate with prev position and new position * @return bool sucess of getting the position in the queue */ public function getPositionInLine(Position &$pos) { if ($this->_positionQueue->acquire()) { $pos->setup(MemoryData::getLastPosition(), MemoryData::getNewPosition()); $this->_positionQueue->release(); return true; } else { return false; } }
/** * Verifies that we get an exception if there appears to be a key * collision. */ public function testKeyCollision() { $mutex = new Mutex($this); $lockID = $mutex->getLockID(); /* Passing the key manually should cause an error, because the code will know that the first time this key was used, it was automatically derived. */ $this->assertThrows('MutexException', function () use($lockID) { new Mutex($lockID); }, null, 'Instantiating a new Mutex with a value that causes a key collision failed to raise the expected exception.'); }
public static function getInstance() { $mutex = new Mutex('Storage.php'); if ($mutex->isLocked() == false) { $mutex->getLock(); if (!self::$_instance) { self::$_instance = new self(); } $mutex->releaseLock(); } return self::$_instance; }
/** * 获得SemFd */ protected static function getSemFd() { if (!self::$semFd) { self::$semFd = \Mutex::create(); } return self::$semFd; }
/** * Constructor. * * @param string $name The mutex name. */ public function __construct($name) { assert('is_string($name)'); $this->name = $name; $path = dirname(__FILE__) . DIRECTORY_SEPARATOR; //Path to ./mutex if (is_null(self::$type)) { foreach ($this->types as $type) { $classFile = $path . $type . 'Mutex.class.php'; if (file_exists($classFile)) { require_once $classFile; $className = $type . 'Mutex'; if (class_exists($className)) { $method = array($className, 'canInstantiate'); if (is_callable($method) && call_user_func($method)) { self::$type = $type; $this->mutex = new $className($name); break; } } } } if (is_null(self::$type)) { throw new MutexException('Sorry but I can\'t create a mutex on this system, please consider installing the Semaphore extension or at least making flock() work.'); } } else { $className = self::$type . 'Mutex'; $this->mutex = new $className($name); } }
/** * Raise the counter inside the thread context. * * @return void */ public function run() { // raise the counter by 1 till 5000 for ($i = 0; $i < 5000; $i++) { \Mutex::lock($this->mutex); $this->object->counter++; \Mutex::unlock($this->mutex); } }
function getValuesFromXML() { $xml_location = $this->get('xml_location'); if (General::validateURL($xml_location) != '') { // is a URL, check cache $cache_id = md5($xml_location); $cache = new Cacheable($this->_Parent->_Parent->Database); $cachedData = $cache->check($cache_id); $creation = DateTimeObj::get('c'); if (!$cachedData || time() - $cachedData['creation'] > 5 * 60) { if (Mutex::acquire($cache_id, 6, TMP)) { $ch = new Gateway(); $ch->init(); $ch->setopt('URL', $xml_location); $ch->setopt('TIMEOUT', 6); $xml = $ch->exec(); $writeToCache = true; Mutex::release($cache_id, TMP); $xml = trim($xml); if (empty($xml) && $cachedData) { $xml = $cachedData['data']; } } elseif ($cachedData) { $xml = $cachedData['data']; } } else { $xml = $cachedData['data']; } $xml = simplexml_load_string($xml); } elseif (substr($xml_location, 0, 1) == '/') { // relative to DOCROOT $xml = simplexml_load_file(DOCROOT . $this->get('xml_location')); } else { // in extension's /xml folder $xml = simplexml_load_file(EXTENSIONS . '/xml_selectbox/xml/' . $this->get('xml_location')); } if (!$xml) { return; } $items = $xml->xpath($this->get('item_xpath')); $options = array(); foreach ($items as $item) { $option = array(); $text_xpath = $item->xpath($this->get('text_xpath')); $option['text'] = General::sanitize((string) $text_xpath[0]); if ($this->get('value_xpath') != '') { $value_xpath = $item->xpath($this->get('value_xpath')); $option['value'] = General::sanitize((string) $value_xpath[0]); } if ((string) $option['value'] == '') { $option['value'] = $option['text']; } $options[] = $option; } return $options; }
/** * Determine the nature of the environment and how we will perform the * mutex. * * @param mixed $lockParam */ public function __construct($lockParam) { if (self::$_useSysV === null) { PFXUtils::validateSettings(self::$_SETTINGS, self::$_SETTING_TESTS); if (MUTEX_DEBUG_LOG_FILE) { self::$_log = fopen(MUTEX_DEBUG_LOG_FILE, 'w'); } $osType = strtolower(substr(PHP_OS, 0, 3)); // Cygwin has the SysV functions but they don't actually work if (!function_exists('sem_acquire') || $osType == 'cyg') { self::$_useSysV = false; self::$_lockFileBase = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'mutex.{LOCK_ID}.tmp'; } else { self::$_useSysV = true; } self::$_activeResources = new SplQueue(); } if (self::$_log) { $this->_mutexID = uniqid(); $trace = debug_backtrace(); self::_log(sprintf('Mutex %s constructed in %s (%s)', $this->_mutexID, $trace[0]['file'], $trace[0]['line'])); } // If we were passed an object instance, get its class name if (is_object($lockParam)) { $lockParam = get_class($lockParam); } if (filter_var($lockParam, FILTER_VALIDATE_INT) !== false) { $lockMethod = self::LOCK_METHOD_MANUAL; $lockID = (int) $lockParam; } else { $lockMethod = self::LOCK_METHOD_AUTO; $lockID = crc32($lockParam); } if (isset(self::$_REGISTERED_KEY_LOCK_METHODS[$lockID]) && self::$_REGISTERED_KEY_LOCK_METHODS[$lockID] != $lockMethod) { throw new MutexException('The mutex lock parameter "' . $lockParam . '" conflicts ' . 'with an existing mutex.'); } self::$_REGISTERED_KEY_LOCK_METHODS[$lockID] = $lockMethod; $this->_lockID = $lockID; if (self::$_useSysV) { $this->_lockResource = sem_get($this->_lockID, 1, 0666, 1); } else { $lockFile = str_replace('{LOCK_ID}', $this->_lockID, self::$_lockFileBase); $this->_lockResource = fopen($lockFile, 'a+b'); // I'm not supporting the cleanup operation for real sempahores self::$_activeResources->enqueue($this->_lockResource); self::$_activeResources->enqueue($lockFile); } if (!$this->_lockResource) { throw new MutexException('Failed to obtain lock resource for mutex.'); } }
public function run() { if ($this->mutex) { printf("LOCK(%d): %d\n", $this->getThreadId(), Mutex::lock($this->mutex)); } if ($result = mysql_query("SHOW PROCESSLIST;", $this->mysql)) { while ($row = mysql_fetch_assoc($result)) { print_r($row); } } if ($this->mutex) { printf("UNLOCK(%d): %d\n", $this->getThreadId(), Mutex::unlock($this->mutex)); } }
public function run() { if ($this->mutex) { $locked = Mutex::lock($this->mutex); } $counter = shm_get_var($this->shmid, 1); $counter++; shm_put_var($this->shmid, 1, $counter); printf("Thread #%lu lock: %s says: %s\n", $this->getThreadId(), !empty($locked) ? "Y" : "N", $counter); //$this->lock(); //$this->unlock(); if ($this->mutex) { Mutex::unlock($this->mutex); } return true; }
public function run() { if ($this->mutex) { $locked = Mutex::lock($this->mutex); } printf("%s#%lu:<-", $locked ? "Y" : "N", $this->getThreadId()); $i = 0; while ($i++ < $this->limit) { echo "."; } printf("->\n"); if ($this->mutex) { Mutex::unlock($this->mutex); } return true; }
public function run() { /* see, first lock mutex */ printf("Running(%d) %f\n", Mutex::lock($this->lock), microtime(true)); /* print some stuff to standard output */ $stdout = fopen("php://stdout", "w"); while (++$i < rand(200, 400)) { echo "."; fflush($stdout); } echo "\n"; fflush($stdout); /* and unlock mutex, making it ready for destruction */ printf("Returning(%d) %f\n", Mutex::unlock($this->lock), microtime(true)); fflush($stdout); /* you should close resources, or not, whatever; I'm not your mother ... */ return null; }
public function write($hash, $data, $ttl = NULL) { if (!Mutex::acquire($hash, 2, TMP)) { return; } $creation = time(); $expiry = NULL; $ttl = intval($ttl); if ($ttl > 0) { $expiry = $creation + $ttl * 60; } if (!($data = $this->compressData($data))) { return false; } $this->forceExpiry($hash); $this->Database->insert(array('hash' => $hash, 'creation' => $creation, 'expiry' => $expiry, 'data' => $data), 'tbl_cache'); Mutex::release($hash, TMP); }
public function run() { if ($this->mutex) { $locked = Mutex::lock($this->mutex); } /* $this->synchronized(function($thread){ $thread->wait(); }, $this); */ $counter = intval(fgets($this->handle)); $counter++; //$this->lock(); //fseek($this->handle, 0); rewind($this->handle); fputs($this->handle, $counter); //fflush($this->handle); //$this->unlock(); printf("Thread #%lu says: %s\n", $this->getThreadId(), $counter); if ($this->mutex) { Mutex::unlock($this->mutex); } }
/** * Create a new timer instance with the passed data. * * @param \AppserverIo\Psr\EnterpriseBeans\TimerServiceInterface $timerService The timer service to create the service for * @param \DateTime $initialExpiration The date at which the first timeout should occur. * If the date is in the past, then the timeout is triggered immediately * when the timer moves to TimerState::ACTIVE * @param integer $intervalDuration The interval (in milli seconds) between consecutive timeouts for the newly created timer. * Cannot be a negative value. A value of 0 indicates a single timeout action * @param \Serializable $info Serializable info that will be made available through the newly created timers Timer::getInfo() method * @param boolean $persistent TRUE if the newly created timer has to be persistent * * @return \AppserverIo\Psr\EnterpriseBeans\TimerInterface Returns the newly created timer * * @throws \Exception */ public function createTimer(TimerServiceInterface $timerService, \DateTime $initialExpiration, $intervalDuration = 0, \Serializable $info = null, $persistent = true) { // lock the method \Mutex::lock($this->mutex); // we're not dispatched $this->dispatched = false; // initialize the data $this->info = $info; $this->persistent = $persistent; $this->timerService = $timerService; $this->intervalDuration = $intervalDuration; $this->initialExpiration = $initialExpiration->format(ScheduleExpression::DATE_FORMAT); // notify the thread $this->notify(); // wait till we've dispatched the request while ($this->dispatched === false) { usleep(100); } // unlock the method \Mutex::unlock($this->mutex); // return the created timer return $this->timer; }
/** * Constructor */ function __construct($name, $timeoutms = 5000) { if (!function_exists('shm_has_var')) { throw new BaseException("No mutex support on this platform"); } $this->_lockname = $name; // Block until lock can be acquired if (Mutex::$instance == 0) { Console::debug("Creating mutex manager"); Mutex::$resource = shm_attach(Mutex::SHM_KEY); if (!shm_has_var(Mutex::$resource, Mutex::SHM_LOCKS)) { shm_put_var(Mutex::$resource, Mutex::SHM_LOCKS, array()); } } $this->enterCriticalSection(); Console::debug("Waiting for lock %s", $this->_lockname); $t = new timer(true); while (true) { $ls = shm_get_var(Mutex::$resource, Mutex::SHM_LOCKS); if (!isset($ls[$name])) { break; } usleep(100000); if ($t->getElapsed() > $timeoutms / 1000) { $this->exitCriticalSection(); throw new MutexException("Timed out waiting for lock"); } } Console::debug("Acquiring lock %s", $this->_lockname); $ls = shm_get_var(Mutex::$resource, Mutex::SHM_LOCKS); $ls[$name] = true; shm_put_var(Mutex::$resource, Mutex::SHM_LOCKS, $ls); Mutex::$instance++; $this->_lockstate = true; $this->exitCriticalSection(); }
<?php require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . '../lib/Mutex/Mutex.class.php'; $m = new Mutex('allo'); echo $m->getMutexType(); $fiction = true; if ($fiction === false) { $x = new Mutex('allo'); $x->lock(); echo "Yay"; $x->unlock(); } $m->lock(); echo "locked"; $m->unlock(); echo "unlocked"; unset($m);
/** * Generates a lock filename using an MD5 hash of the `$id` and * `$path`. Lock files are given a .lock extension * * @param string $id * The name of the lock file to be obfuscated * @param string $path * The path the lock should be written * @return string */ private static function __generateLockFileName($id, $path = null) { // This function is called from all others, so it is a good point to initialize Mutex handling. if (!is_array(self::$lockFiles)) { self::$lockFiles = array(); register_shutdown_function(array(__CLASS__, '__shutdownCleanup')); } if (is_null($path)) { $path = sys_get_temp_dir(); } // Use realpath, because shutdown function may operate in different working directory. // So we need to be sure that path is absolute. return rtrim(realpath($path), '/') . '/' . md5($id) . '.lock'; }
public function write($key, $data, $ttl = NULL) { if (!Mutex::acquire(md5($key), 2, TMP)) { return; } $data = new CacheResult(trim($data), $key, time()); file_put_contents(CACHE . '/' . md5($key) . '.cache', self::__compress($data)); Mutex::release(md5($key), TMP); }
/** * Create a new instance with the passed data. * * @param string $className The fully qualified class name to return the instance for * @param string|null $sessionId The session-ID, necessary to inject stateful session beans (SFBs) * @param array $args Arguments to pass to the constructor of the instance * * @return object The instance itself * * @throws \Exception */ public function newInstance($className, $sessionId = null, array $args = array()) { // lock the method \Mutex::lock($this->mutex); // we're not dispatched $this->dispatched = false; // initialize the data $this->args = $args; $this->sessionId = $sessionId; $this->className = $className; // notify the thread $this->notify(); // wait till we've dispatched the request while ($this->dispatched === false) { usleep(100); } // try to load the last created instance if (isset($this->instances[$last = sizeof($this->instances) - 1])) { $instance = $this->instances[$last]; } else { throw new \Exception('Requested instance can\'t be created'); } // unlock the method \Mutex::unlock($this->mutex); // return the created instance return $instance; }
if (SYMLINK && @symlink($image_path, $cache_path)) { if (DEBUG_IMAGE) { debugLog("full-image:symlink original " . basename($image)); } clearstatcache(); } else { if (@copy($image_path, $cache_path)) { if (DEBUG_IMAGE) { debugLog("full-image:copy original " . basename($image)); } clearstatcache(); } } } else { // have to create the image $iMutex = new Mutex('i', getOption('imageProcessorConcurrency')); $iMutex->lock(); $newim = zp_imageGet($image_path); if ($rotate) { $newim = zp_rotateImage($newim, $rotate); } if ($watermark_use_image) { $watermark_image = getWatermarkPath($watermark_use_image); if (!file_exists($watermark_image)) { $watermark_image = SERVERPATH . '/' . ZENFOLDER . '/images/imageDefault.png'; } $offset_h = getOption('watermark_h_offset') / 100; $offset_w = getOption('watermark_w_offset') / 100; $watermark = zp_imageGet($watermark_image); $watermark_width = zp_imageWidth($watermark); $watermark_height = zp_imageHeight($watermark);
public function execute(array &$param_pool = null) { $result = new XMLElement($this->dsParamROOTELEMENT); // When DS is called out of the Frontend context, this will enable // {$root} and {$workspace} parameters to be evaluated if (empty($this->_env)) { $this->_env['env']['pool'] = array('root' => URL, 'workspace' => WORKSPACE); } try { require_once TOOLKIT . '/class.gateway.php'; require_once TOOLKIT . '/class.xsltprocess.php'; require_once CORE . '/class.cacheable.php'; $this->dsParamURL = $this->parseParamURL($this->dsParamURL); if (isset($this->dsParamXPATH)) { $this->dsParamXPATH = $this->__processParametersInString(stripslashes($this->dsParamXPATH), $this->_env); } // Builds a Default Stylesheet to transform the resulting XML with $stylesheet = new XMLElement('xsl:stylesheet'); $stylesheet->setAttributeArray(array('version' => '1.0', 'xmlns:xsl' => 'http://www.w3.org/1999/XSL/Transform')); $output = new XMLElement('xsl:output'); $output->setAttributeArray(array('method' => 'xml', 'version' => '1.0', 'encoding' => 'utf-8', 'indent' => 'yes', 'omit-xml-declaration' => 'yes')); $stylesheet->appendChild($output); $template = new XMLElement('xsl:template'); $template->setAttribute('match', '/'); $instruction = new XMLElement('xsl:copy-of'); // Namespaces if (isset($this->dsParamNAMESPACES) && is_array($this->dsParamNAMESPACES)) { foreach ($this->dsParamNAMESPACES as $name => $uri) { $instruction->setAttribute('xmlns' . ($name ? ":{$name}" : null), $uri); } } // XPath $instruction->setAttribute('select', $this->dsParamXPATH); $template->appendChild($instruction); $stylesheet->appendChild($template); $stylesheet->setIncludeHeader(true); $xsl = $stylesheet->generate(true); // Check for an existing Cache for this Datasource $cache_id = self::buildCacheID($this); $cache = Symphony::ExtensionManager()->getCacheProvider('remotedatasource'); $cachedData = $cache->check($cache_id); $writeToCache = null; $isCacheValid = true; $creation = DateTimeObj::get('c'); // Execute if the cache doesn't exist, or if it is old. if (!is_array($cachedData) || empty($cachedData) || time() - $cachedData['creation'] > $this->dsParamCACHE * 60) { if (Mutex::acquire($cache_id, $this->dsParamTIMEOUT, TMP)) { $ch = new Gateway(); $ch->init($this->dsParamURL); $ch->setopt('TIMEOUT', $this->dsParamTIMEOUT); // Set the approtiate Accept: headers depending on the format of the URL. if ($this->dsParamFORMAT == 'xml') { $ch->setopt('HTTPHEADER', array('Accept: text/xml, */*')); } elseif ($this->dsParamFORMAT == 'json') { $ch->setopt('HTTPHEADER', array('Accept: application/json, */*')); } elseif ($this->dsParamFORMAT == 'csv') { $ch->setopt('HTTPHEADER', array('Accept: text/csv, */*')); } self::prepareGateway($ch); $data = $ch->exec(); $info = $ch->getInfoLast(); Mutex::release($cache_id, TMP); $data = trim($data); $writeToCache = true; // Handle any response that is not a 200, or the content type does not include XML, JSON, plain or text if ((int) $info['http_code'] != 200 || !preg_match('/(xml|json|csv|plain|text)/i', $info['content_type'])) { $writeToCache = false; $result->setAttribute('valid', 'false'); // 28 is CURLE_OPERATION_TIMEOUTED if ($info['curl_error'] == 28) { $result->appendChild(new XMLElement('error', sprintf('Request timed out. %d second limit reached.', $timeout))); } else { $result->appendChild(new XMLElement('error', sprintf('Status code %d was returned. Content-type: %s', $info['http_code'], $info['content_type']))); } return $result; } else { if (strlen($data) > 0) { // Handle where there is `$data` // If it's JSON, convert it to XML if ($this->dsParamFORMAT == 'json') { try { require_once TOOLKIT . '/class.json.php'; $data = JSON::convertToXML($data); } catch (Exception $ex) { $writeToCache = false; $errors = array(array('message' => $ex->getMessage())); } } elseif ($this->dsParamFORMAT == 'csv') { try { require_once EXTENSIONS . '/remote_datasource/lib/class.csv.php'; $data = CSV::convertToXML($data); } catch (Exception $ex) { $writeToCache = false; $errors = array(array('message' => $ex->getMessage())); } } elseif ($this->dsParamFORMAT == 'txt') { $txtElement = new XMLElement('entry'); $txtElement->setValue(General::wrapInCDATA($data)); $data = $txtElement->generate(); $txtElement = null; } else { if (!General::validateXML($data, $errors, false, new XsltProcess())) { // If the XML doesn't validate.. $writeToCache = false; } } // If the `$data` is invalid, return a result explaining why if ($writeToCache === false) { $error = new XMLElement('errors'); $error->setAttribute('valid', 'false'); $error->appendChild(new XMLElement('error', __('Data returned is invalid.'))); foreach ($errors as $e) { if (strlen(trim($e['message'])) == 0) { continue; } $error->appendChild(new XMLElement('item', General::sanitize($e['message']))); } $result->appendChild($error); return $result; } } elseif (strlen($data) == 0) { // If `$data` is empty, set the `force_empty_result` to true. $this->_force_empty_result = true; } } } else { // Failed to acquire a lock $result->appendChild(new XMLElement('error', __('The %s class failed to acquire a lock.', array('<code>Mutex</code>')))); } } else { // The cache is good, use it! $data = trim($cachedData['data']); $creation = DateTimeObj::get('c', $cachedData['creation']); } // Visit the data $this->exposeData($data); // If `$writeToCache` is set to false, invalidate the old cache if it existed. if (is_array($cachedData) && !empty($cachedData) && $writeToCache === false) { $data = trim($cachedData['data']); $isCacheValid = false; $creation = DateTimeObj::get('c', $cachedData['creation']); if (empty($data)) { $this->_force_empty_result = true; } } // If `force_empty_result` is false and `$result` is an instance of // XMLElement, build the `$result`. if (!$this->_force_empty_result && is_object($result)) { $proc = new XsltProcess(); $ret = $proc->process($data, $xsl); if ($proc->isErrors()) { $result->setAttribute('valid', 'false'); $error = new XMLElement('error', __('Transformed XML is invalid.')); $result->appendChild($error); $errors = new XMLElement('errors'); foreach ($proc->getError() as $e) { if (strlen(trim($e['message'])) == 0) { continue; } $errors->appendChild(new XMLElement('item', General::sanitize($e['message']))); } $result->appendChild($errors); $result->appendChild(new XMLElement('raw-data', General::wrapInCDATA($data))); } elseif (strlen(trim($ret)) == 0) { $this->_force_empty_result = true; } else { if ($this->dsParamCACHE > 0 && $writeToCache) { $cache->write($cache_id, $data, $this->dsParamCACHE); } $result->setValue(PHP_EOL . str_repeat("\t", 2) . preg_replace('/([\\r\\n]+)/', "\$1\t", $ret)); $result->setAttribute('status', $isCacheValid === true ? 'fresh' : 'stale'); $result->setAttribute('cache-id', $cache_id); $result->setAttribute('creation', $creation); } } } catch (Exception $e) { $result->appendChild(new XMLElement('error', $e->getMessage())); } if ($this->_force_empty_result) { $result = $this->emptyXMLSet(); } $result->setAttribute('url', General::sanitize($this->dsParamURL)); return $result; }
/** * Create a calendar-based timer based on the input schedule expression. * * @param \AppserverIo\Psr\EnterpriseBeans\TimerServiceInterface $timerService The timer service to create the service for * @param \AppserverIo\Psr\EnterpriseBeans\ScheduleExpression $schedule A schedule expression describing the timeouts for this timer * @param \Serializable $info Serializable info that will be made available through the newly created timers Timer::getInfo() method * @param boolean $persistent TRUE if the newly created timer has to be persistent * @param \AppserverIo\Lang\Reflection\MethodInterface $timeoutMethod The timeout method to be invoked * * @return \AppserverIo\Psr\EnterpriseBeans\TimerInterface The newly created Timer. * @throws \AppserverIo\Psr\EnterpriseBeans\EnterpriseBeansException If this method could not complete due to a system-level failure. * @throws \Exception */ public function createTimer(TimerServiceInterface $timerService, ScheduleExpression $schedule, \Serializable $info = null, $persistent = true, MethodInterface $timeoutMethod = null) { // lock the method \Mutex::lock($this->mutex); // we're not dispatched $this->dispatched = false; // initialize the data $this->info = $info; $this->schedule = $schedule; $this->persistent = $persistent; $this->timerService = $timerService; $this->timeoutMethod = $timeoutMethod; // notify the thread $this->notify(); // wait till we've dispatched the request while ($this->dispatched === false) { usleep(100); } // unlock the method \Mutex::unlock($this->mutex); // return the created timer return $this->timer; }
/** * This function will compress data for storage in `tbl_cache`. * It is left to the user to define a unique hash for this data so that it can be * retrieved in the future. Optionally, a `$ttl` parameter can * be passed for this data. If this is omitted, it data is considered to be valid * forever. This function utilizes the Mutex class to act as a crude locking * mechanism. * * @see toolkit.Mutex * @throws DatabaseException * @param string $hash * The hash of the Cached object, as defined by the user * @param string $data * The data to be cached, this will be compressed prior to saving. * @param integer $ttl * A integer representing how long the data should be valid for in minutes. * By default this is null, meaning the data is valid forever * @param string $namespace * The namespace allows data to be grouped and saved so it can be * retrieved later. * @return boolean * If an error occurs, this function will return false otherwise true */ public function write($hash, $data, $ttl = null, $namespace = null) { if (!Mutex::acquire($hash, 2, TMP)) { return false; } $creation = time(); $expiry = null; $ttl = intval($ttl); if ($ttl > 0) { $expiry = $creation + $ttl * 60; } if (!($data = Cacheable::compressData($data))) { return false; } $this->delete($hash, $namespace); $this->Database->insert(array('hash' => $hash, 'creation' => $creation, 'expiry' => $expiry, 'data' => $data, 'namespace' => $namespace), 'tbl_cache'); Mutex::release($hash, TMP); return true; }
/** * Test object destruction when passing to a threads constructor. * * @return void */ public function testPassThroughThreadConstructor() { // set the counter to ZERO $this->object->counter = 0; // check the reference counter $this->assertSame(1, Registry::refCount($this->object)); // initialize the mutex $mutex = \Mutex::create(); // execute the thread $thread = new PassThroughConstructorThread($this->object, $mutex); $thread->start(); $thread->join(); // check the reference counter $this->assertSame(1, Registry::refCount($this->object)); }
/** * Not a test, but facilitates mutex testing. * * @group meta */ public function testMutexInSeparateProcess() { $mutex = new Mutex('Logger'); $mutex->acquire(); sleep(2); $mutex->release(); }
$cache_id = md5($this->dsParamURL . serialize($this->dsParamFILTERS) . $this->dsParamXPATH); $cache = new Cacheable($this->_Parent->Database); $cachedData = $cache->check($cache_id); $writeToCache = false; $valid = true; $result = NULL; $creation = DateTimeObj::get('c'); if (!$cachedData || time() - $cachedData['creation'] > $this->dsParamCACHE * 60) { if (Mutex::acquire($cache_id, 6, TMP)) { $ch = new Gateway(); $ch->init(); $ch->setopt('URL', $this->dsParamURL); $ch->setopt('TIMEOUT', 6); $xml = $ch->exec(); $writeToCache = true; Mutex::release($cache_id, TMP); $xml = trim($xml); if (!empty($xml)) { $valid = General::validateXML($xml, $errors, false, $proc); if (!$valid) { if ($cachedData) { $xml = $cachedData['data']; } else { $result = new XMLElement($this->dsParamROOTELEMENT); $result->setAttribute('valid', 'false'); $result->appendChild(new XMLElement('error', __('XML returned is invalid.'))); } } } else { $this->_force_empty_result = true; }
/** * Test the new instance method. * * @return void */ public function testNewInstance() { $className = 'TechDivision\\ApplicationServer\\Mock\\MockContainerThread'; $instance = $this->server->newInstance($className, array($this->server->getInitialContext(), \Mutex::create(false), $id = 1)); $this->assertInstanceOf($className, $instance); }
public function execute(array &$param_pool = null) { $result = new XMLElement($this->dsParamROOTELEMENT); $this->dsParamURL = $this->parseParamURL($this->dsParamURL); if (isset($this->dsParamXPATH)) { $this->dsParamXPATH = $this->__processParametersInString($this->dsParamXPATH, $this->_env); } $stylesheet = new XMLElement('xsl:stylesheet'); $stylesheet->setAttributeArray(array('version' => '1.0', 'xmlns:xsl' => 'http://www.w3.org/1999/XSL/Transform')); $output = new XMLElement('xsl:output'); $output->setAttributeArray(array('method' => 'xml', 'version' => '1.0', 'encoding' => 'utf-8', 'indent' => 'yes', 'omit-xml-declaration' => 'yes')); $stylesheet->appendChild($output); $template = new XMLElement('xsl:template'); $template->setAttribute('match', '/'); $instruction = new XMLElement('xsl:copy-of'); // Namespaces if (isset($this->dsParamFILTERS) && is_array($this->dsParamFILTERS)) { foreach ($this->dsParamFILTERS as $name => $uri) { $instruction->setAttribute('xmlns' . ($name ? ":{$name}" : null), $uri); } } // XPath $instruction->setAttribute('select', $this->dsParamXPATH); $template->appendChild($instruction); $stylesheet->appendChild($template); $stylesheet->setIncludeHeader(true); $xsl = $stylesheet->generate(true); $cache_id = md5($this->dsParamURL . serialize($this->dsParamFILTERS) . $this->dsParamXPATH); $cache = new Cacheable(Symphony::Database()); $cachedData = $cache->read($cache_id); $writeToCache = false; $valid = true; $creation = DateTimeObj::get('c'); $timeout = isset($this->dsParamTIMEOUT) ? (int) max(1, $this->dsParamTIMEOUT) : 6; // Execute if the cache doesn't exist, or if it is old. if (!is_array($cachedData) || empty($cachedData) || time() - $cachedData['creation'] > $this->dsParamCACHE * 60) { if (Mutex::acquire($cache_id, $timeout, TMP)) { $ch = new Gateway(); $ch->init($this->dsParamURL); $ch->setopt('TIMEOUT', $timeout); $ch->setopt('HTTPHEADER', array('Accept: text/xml, */*')); $data = $ch->exec(); $info = $ch->getInfoLast(); Mutex::release($cache_id, TMP); $data = trim($data); $writeToCache = true; // Handle any response that is not a 200, or the content type does not include XML, plain or text if ((int) $info['http_code'] !== 200 || !preg_match('/(xml|plain|text)/i', $info['content_type'])) { $writeToCache = false; $result->setAttribute('valid', 'false'); // 28 is CURLE_OPERATION_TIMEOUTED if ($info['curl_error'] == 28) { $result->appendChild(new XMLElement('error', sprintf('Request timed out. %d second limit reached.', $timeout))); } else { $result->appendChild(new XMLElement('error', sprintf('Status code %d was returned. Content-type: %s', $info['http_code'], $info['content_type']))); } return $result; // Handle where there is `$data` } elseif (strlen($data) > 0) { // If the XML doesn't validate.. if (!General::validateXML($data, $errors, false, new XsltProcess())) { $writeToCache = false; } // If the `$data` is invalid, return a result explaining why if ($writeToCache === false) { $element = new XMLElement('errors'); $result->setAttribute('valid', 'false'); $result->appendChild(new XMLElement('error', __('Data returned is invalid.'))); foreach ($errors as $e) { if (strlen(trim($e['message'])) == 0) { continue; } $element->appendChild(new XMLElement('item', General::sanitize($e['message']))); } $result->appendChild($element); return $result; } // If `$data` is empty, set the `force_empty_result` to true. } elseif (strlen($data) == 0) { $this->_force_empty_result = true; } // Failed to acquire a lock } else { $result->appendChild(new XMLElement('error', __('The %s class failed to acquire a lock, check that %s exists and is writable.', array('<code>Mutex</code>', '<code>' . TMP . '</code>')))); } // The cache is good, use it! } else { $data = trim($cachedData['data']); $creation = DateTimeObj::get('c', $cachedData['creation']); } // If `$writeToCache` is set to false, invalidate the old cache if it existed. if (is_array($cachedData) && !empty($cachedData) && $writeToCache === false) { $data = trim($cachedData['data']); $valid = false; $creation = DateTimeObj::get('c', $cachedData['creation']); if (empty($data)) { $this->_force_empty_result = true; } } // If `force_empty_result` is false and `$result` is an instance of // XMLElement, build the `$result`. if (!$this->_force_empty_result && is_object($result)) { $proc = new XsltProcess(); $ret = $proc->process($data, $xsl); if ($proc->isErrors()) { $result->setAttribute('valid', 'false'); $error = new XMLElement('error', __('Transformed XML is invalid.')); $result->appendChild($error); $element = new XMLElement('errors'); foreach ($proc->getError() as $e) { if (strlen(trim($e['message'])) == 0) { continue; } $element->appendChild(new XMLElement('item', General::sanitize($e['message']))); } $result->appendChild($element); } elseif (strlen(trim($ret)) == 0) { $this->_force_empty_result = true; } else { if ($writeToCache) { $cache->write($cache_id, $data, $this->dsParamCACHE); } $result->setValue(PHP_EOL . str_repeat("\t", 2) . preg_replace('/([\\r\\n]+)/', "\$1\t", $ret)); $result->setAttribute('status', $valid === true ? 'fresh' : 'stale'); $result->setAttribute('creation', $creation); } } return $result; }
/** * Release the mutex previously acquired * */ function Release() { global $DBCONN, $TBLPREFIX; if (!Mutex::checkDBCONN()) { return false; } $sql = "UPDATE {$TBLPREFIX}mutex SET mx_time=0, mx_thread='0' WHERE mx_name='" . $DBCONN->escapeSimple($this->name) . "' AND mx_thread='" . session_id() . "'"; $res = dbquery($sql); $this->waitCount = 0; // print "releasing mutex ".$this->name; }