Acquire the mutex

@param bool $wait
@return  boolean
161733
public function lock(bool $wait = true): bool
    {
        if ($this->fp === null) {
            $this->fp = fopen($this->file, 'r');
        }

        return flock($this->fp, $wait ? LOCK_EX : LOCK_EX | LOCK_NB);
    }
943930
protected function waitPid()
    {
        start:
        $pid = \pcntl_waitpid(-1, $status, WNOHANG);
        if ($pid > 0) {
            foreach ($this->collections as $col) {
                foreach ($col->threads as $k => $t) {
                    if ($t->pid === $pid) {
                        $t->setTerminated();
                        unset($col->threads[$k]);
                        goto start;
                    }
                }
            }
        }

        return false;
    }
598384
protected function setMutex()
    {
        if (Eye::laravelVersionIs('<', '5.4.0')) {
            return touch($this->mutexPath());
        } elseif (Eye::laravelVersionIs('<', '5.4.17')) {
            return $this->cache->add($this->mutexName(), true, 1440);
        }

        return $this->mutex->create($this);
    }
1298419
public function lock($blocking = false)
    {
        if ($this->handle) {
            return true;
        }

        $error = null;

        // Silence error reporting
        set_error_handler(function ($errno, $msg) use (&$error) {
            $error = $msg;
        });

        if (!$this->handle = fopen($this->file, 'r')) {
            if ($this->handle = fopen($this->file, 'x')) {
                chmod($this->file, 0444);
            } elseif (!$this->handle = fopen($this->file, 'r')) {
                usleep(100); // Give some time for chmod() to complete
                $this->handle = fopen($this->file, 'r');
            }
        }
        restore_error_handler();

        if (!$this->handle) {
            throw new IOException($error, 0, null, $this->file);
        }

        // On Windows, even if PHP doc says the contrary, LOCK_NB works, see
        // https://bugs.php.net/54129
        if (!flock($this->handle, LOCK_EX | ($blocking ? 0 : LOCK_NB))) {
            fclose($this->handle);
            $this->handle = null;

            return false;
        }

        return true;
    }
619730
protected function acquireLock($maxWaitSeconds = 5, $lockHandle = null)
    {
        $lockFile = $this->getLockFilename($lockHandle);
        if (isset($this->lockHandles[$lockFile])) {
            $result = true;
        } else {
            $startTime = time();
            $result = false;
            $fd = null;
            while ($result === false) {
                $fd = @fopen($lockFile, 'w');
                if ($fd !== false) {
                    if (@flock($fd, LOCK_EX | LOCK_NB) === true) {
                        $result = true;
                        break;
                    } else {
                        @fclose($fd);
                    }
                }
                $elapsedTime = time() - $startTime;
                if ($elapsedTime >= $maxWaitSeconds) {
                    break;
                }
                sleep(1);
            }
            if ($result === true) {
                $this->lockHandles[$lockFile] = $fd;
            }
        }

        return $result;
    }
369643
public function restart($wait = true)
    {
        return $this->forge->restartDaemon($this->serverId, $this->id, $wait);
    }
691336
public function wait($timeout = -1)
    {
        $forever = ($timeout < 0);

        while ($this->isAlive()) {
            $this->read();

            if (!$forever && (microtime(true) - $this->start > $timeout)) {
                $this->kill(SIGKILL);
                break;
            }

            usleep(5000);
        }

        $this->cleanup();
    }
978043
private Boolean acquireLock(final BooleanMutex mutex) {
        try {
            do {
                if (id == null) {// 构建当前lock的唯一标识
                    long sessionId = getSessionId();
                    String prefix = "x-" + sessionId + "-";
                    // 如果第一次，则创建一个节点
                    String path = zookeeper.create(root + "/" + prefix, data, CreateMode.EPHEMERAL_SEQUENTIAL);
                    int index = path.lastIndexOf("/");
                    id = StringUtils.substring(path, index + 1);
                    idName = new LockNode(id);
                }

                if (id != null) {
                    List<String> names = zookeeper.getChildren(root);
                    if (names.isEmpty()) {
                        logger.warn("lock lost with scene:empty list, id[] and node[]", id, idName);
                        unlock();// 异常情况，退出后重新创建一个
                    } else {
                        // 对节点进行排序
                        SortedSet<LockNode> sortedNames = new TreeSet<LockNode>();
                        for (String name : names) {
                            sortedNames.add(new LockNode(name));
                        }

                        if (sortedNames.contains(idName) == false) {
                            logger.warn("lock lost with scene:not contains ,id[] and node[]", id, idName);
                            unlock();// 异常情况，退出后重新创建一个
                            continue;
                        }

                        // 将第一个节点做为ownerId
                        ownerId = sortedNames.first().getName();
                        if (mutex != null && isOwner()) {
                            mutex.set(true);// 直接更新状态，返回
                            return true;
                        } else if (mutex == null) {
                            return isOwner();
                        }

                        SortedSet<LockNode> lessThanMe = sortedNames.headSet(idName);
                        if (!lessThanMe.isEmpty()) {
                            // 关注一下排队在自己之前的最近的一个节点
                            LockNode lastChildName = lessThanMe.last();
                            lastChildId = lastChildName.getName();
                            // 异步watcher处理
                            IZkConnection connection = zookeeper.getConnection();
                            // zkclient包装的是一个持久化的zk，分布式lock只需要一次性的watcher，需要调用原始的zk链接进行操作
                            ZooKeeper orginZk = ((ZooKeeperx) connection).getZookeeper();
                            Stat stat = orginZk.exists(root + "/" + lastChildId, new AsyncWatcher() {

                                public void asyncProcess(WatchedEvent event) {
                                    if (!mutex.state()) { // 避免重复获取lock
                                        acquireLock(mutex);
                                    } else {
                                        logger.warn("locked successful.");
                                    }
                                }

                            });

                            if (stat == null) {
                                acquireLock(mutex);// 如果节点不存在，需要自己重新触发一下，watcher不会被挂上去
                            }
                        } else {
                            if (isOwner()) {
                                mutex.set(true);
                            } else {
                                logger.warn("lock lost with scene:no less ,id[] and node[]", id, idName);
                                unlock();// 可能自己的节点已超时挂了，所以id和ownerId不相同
                            }
                        }
                    }
                }
            } while (id == null);
        } catch (KeeperException e) {
            exception = e;
            if (mutex != null) {
                mutex.set(true);
            }
        } catch (InterruptedException e) {
            interrupt = e;
            if (mutex != null) {
                mutex.set(true);
            }
        } catch (Throwable e) {
            other = e;
            if (mutex != null) {
                mutex.set(true);
            }
        }

        if (isOwner() && mutex != null) {
            mutex.set(true);
        }
        return Boolean.FALSE;
    }
1203115
public function implicitWait($timeout)
    {
        $timeoutNormalize = intval(ceil($timeout / 100));
        if ($this->cache[self::WAIT_IMPLICIT] === $timeoutNormalize) {
            return null;
        }
        $this->cache[self::WAIT_IMPLICIT] = $timeout;
        $param = ['ms' => intval($timeout)];
        $command = $this->driver->factoryCommand('timeouts/implicit_wait', WebDriver_Command::METHOD_POST, $param);
        return $this->driver->curl($command)['value'];
    }
52736
public function wait($pid = null)
    {
        if ($pid) {
            $threads = [$pid];
        } else {
            $threads = $this->threads;
        }

        $error = false;
        $status = 0;
        foreach ($threads as $pid) {
            pcntl_waitpid($pid, $status);
            if ($status > 0) {
                $error = $status;
            }
            unset($this->threads[$pid]);
        }

        if (!$this->ignoreErrors && $error) {
            $memory = shmop_open($this->memoryKey, "a", 0, 0);
            $errors = shmop_read($memory, 0, static::SHARED_MEMORY_LIMIT);
            shmop_delete($memory);
            shmop_close($memory);

            $error = "An error occurred within a thread, the return code was (" . $error . ")";
            if ($errors = trim($errors)) {
                $error .= "\n" . $errors;
            }
            throw new \Exception($error);
        }

        return $status;
    }
1327166
public static function lock($key, $timeout = 500) {
        /* @var $cache RedisCache */
        $cache = Pool::get(CacheInterface::class);
        try {
            if ($cache instanceof RedisCache) {
                $cache->open();
                $redis = $cache->redis;
                $script = "if(redis.call('setnx',  KEYS[1],ARGV[1])==1)then return redis.call('expire',KEYS[1],10) else 
            return 0 end";
                for ($i = 0; $i < $timeout / 5; $i++) {
                    $ok = $redis->eval($script, ["_RedisLocker_$key", 'lock_' . Context::id()], 1);
                    if ($ok) {
                        Pool::release($cache);
                        return true;
                    }
                    if (IS_SWOOLE) {
                        \Co::sleep(0.005);
                    } else {
                        sleep(0.005);
                    }

                }
            }
            Pool::release($cache);
        } catch (\RuntimeException $e) {
            Pool::release($cache);
            throw $e;
        } catch (\Error $e) {
            Pool::release($cache);
            throw $e;
        }
        return false;
    }
399670
public function acquire($blocking = true)
    {
        if ($this->locked) {
            throw new \RuntimeException('already lock by yourself');
        }

        if ($blocking === false) {
            if (version_compare(PHP_VERSION, '5.6.0') < 0) {
                throw new \RuntimeException('php version is at least 5.6.0 for param blocking');
            }
            if (!sem_acquire($this->lock_id, true)) {
                return false;
            }
            $this->locked = true;

            return true;
        }

        if (!sem_acquire($this->lock_id)) {
            return false;
        }
        $this->locked = true;

        return true;
    }
441520
function &_mutex()
    {
        if ( $this->Mutex !== null )
            return $this->Mutex;
        $mutex = new eZMutex( $this->filePath );
        return $mutex;
    }
798231
public function delay($delay = null)
    {
        if ($delay === null) {
            return $this->_delay;
        }
        $this->_delay = $delay;

        return $this;
    }
681306
public function activate($wait = true)
    {
        return $this->forge->activateCertificate($this->serverId, $this->siteId, $this->id, $wait);
    }
1106730
protected function waitUnlock($key) 
    {
        if ($this->isLocked($key)) {
            $count = 0;
            do {
                usleep(100);
                $count ++;
            } while ($count < 10 && $this->isLocked($key));  // 最多做10次睡眠等待解锁，超时则跳过并解锁
        
            $this->isLocked($key) && $this->unlock($key);        
        }
        
        return $this;
    }
701742
public function getWaitTime($attempt)
    {
        $waitTime = call_user_func($this->getStrategy(), $attempt);

        return $this->jitter($this->cap($waitTime));
    }