swoole / library

📚 Swoole Library
https://wiki.swoole.com/#/library
Apache License 2.0
237 stars 58 forks source link

Barrier类修改 #67

Closed c-v-c-v closed 3 years ago

c-v-c-v commented 3 years ago

以下情况下不会抛出协程错误异常,正常执行

修改后的类

use Swoole\Coroutine;
use Swoole\Exception;
use Swoole\Timer;

class Barrier
{
    private $cid = -1;

    private $timer = -1;

    private static $cancel_list = [];

    public function __destruct()
    {
        if ($this->timer != -1) {
            Timer::clear($this->timer);
            if (static::$cancel_list[$this->cid]) {
                unset(static::$cancel_list[$this->cid]);
                return;
            }
        }

        if ($this->cid != -1 && $this->cid != Coroutine::getCid()) {
            Coroutine::resume($this->cid);
        }else{
            self::$cancel_list[$this->cid] = true;
        }
    }

    public static function make()
    {
        return new static();
    }

    /**
     * @throws Exception
     */
    public static function wait(Barrier &$barrier, float $timeout = -1)
    {
        if ($barrier->cid != -1) {
            throw new Exception('The barrier is waiting, cannot wait again.');
        }
        $cid = Coroutine::getCid();
        $barrier->cid = $cid;
        if ($timeout > 0 && ($timeout_ms = intval($timeout * 1000)) > 0) {
            $barrier->timer = Timer::after($timeout_ms, function () use ($cid) {
                self::$cancel_list[$cid] = true;
                Coroutine::resume($cid);
            });
        }
        $barrier = null;
        (!(self::$cancel_list[$cid] ?? false)) && Coroutine::yield();
    }
}
c-v-c-v commented 3 years ago

@sy-records ok ok

c-v-c-v commented 3 years ago

@sy-records wait方法中可以加上unset数组self::$cancel_list[$cid]

if (!isset(self::$cancel_list[$cid])) {
     Coroutine::yield();
}else {
    unset(self::$cancel_list[$cid]);
}
sy-records commented 3 years ago

嗯,这里是有点问题。。我在等review,结果合并了😂

c-v-c-v commented 3 years ago

@sy-records 好的好的,哈哈