Open source PHP extension for Async IO, Coroutines and Fibers

Swoole Logo

lib-openswoole ext-openswoole test-linux Coverity Scan Build Status codecov

Swoole is an event-driven asynchronous & coroutine-based concurrency networking communication engine with high performance written in C++ for PHP.

Open Swoole since release version v4.7.1.

Event-based

The network layer in Swoole is event-based and takes full advantage of the underlying epoll/kqueue implementation, making it really easy to serve millions of requests.

Swoole 4.x uses a brand new engine kernel and now it has a full-time developer team, so we are entering an unprecedented period in PHP history which offers a unique possibility for rapid evolution in performance.

Coroutine

Swoole 4.x or later supports the built-in coroutine with high availability, and you can use fully synchronized code to implement asynchronous performance. PHP code without any additional keywords, the underlying automatic coroutine-scheduling.

Developers can understand coroutines as ultra-lightweight threads, and you can easily create thousands of coroutines in a single process.

MySQL

Concurrency 10K requests to read data from MySQL takes only 0.2s!

$s = microtime(true);
Co\run(function() {
    for ($c = 100; $c--;) {
        go(function () {
            $mysql = new Swoole\Coroutine\MySQL;
            $mysql->connect([
                'host' => '127.0.0.1',
                'user' => 'root',
                'password' => 'root',
                'database' => 'test'
            ]);
            $statement = $mysql->prepare('SELECT * FROM `user`');
            for ($n = 100; $n--;) {
                $result = $statement->execute();
                assert(count($result) > 0);
            }
        });
    }
});
echo 'use ' . (microtime(true) - $s) . ' s';

Mixed server

You can create multiple services on the single event loop: TCP, HTTP, Websocket and HTTP2, and easily handle thousands of requests.

function tcp_pack(string $data): string
{
    return pack('N', strlen($data)) . $data;
}
function tcp_unpack(string $data): string
{
    return substr($data, 4, unpack('N', substr($data, 0, 4))[1]);
}
$tcp_options = [
    'open_length_check' => true,
    'package_length_type' => 'N',
    'package_length_offset' => 0,
    'package_body_offset' => 4
];
$server = new Swoole\WebSocket\Server('127.0.0.1', 9501, SWOOLE_BASE);
$server->set(['open_http2_protocol' => true]);
// http && http2
$server->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) {
    $response->end('Hello ' . $request->rawcontent());
});
// websocket
$server->on('message', function (Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame) {
    $server->push($frame->fd, 'Hello ' . $frame->data);
});
// tcp
$tcp_server = $server->listen('127.0.0.1', 9502, SWOOLE_TCP);
$tcp_server->set($tcp_options);
$tcp_server->on('receive', function (Swoole\Server $server, int $fd, int $reactor_id, string $data) {
    $server->send($fd, tcp_pack('Hello ' . tcp_unpack($data)));
});
$server->start();

Coroutine clients

Whether you DNS query or send requests or receive responses, all of these are scheduled by coroutine automatically.

go(function () {
    // http
    $http_client = new Swoole\Coroutine\Http\Client('127.0.0.1', 9501);
    assert($http_client->post('/', 'Swoole Http'));
    var_dump($http_client->body);
    // websocket
    $http_client->upgrade('/');
    $http_client->push('Swoole Websocket');
    var_dump($http_client->recv()->data);
});
go(function () {
    // http2
    $http2_client = new Swoole\Coroutine\Http2\Client('localhost', 9501);
    $http2_client->connect();
    $http2_request = new Swoole\Http2\Request;
    $http2_request->method = 'POST';
    $http2_request->data = 'Swoole Http2';
    $http2_client->send($http2_request);
    $http2_response = $http2_client->recv();
    var_dump($http2_response->data);
});
go(function () use ($tcp_options) {
    // tcp
    $tcp_client = new Swoole\Coroutine\Client(SWOOLE_TCP);
    $tcp_client->set($tcp_options);
    $tcp_client->connect('127.0.0.1', 9502);
    $tcp_client->send(tcp_pack('Swoole Tcp'));
    var_dump(tcp_unpack($tcp_client->recv()));
});

Channel

Channel is the only way for exchanging data between coroutines, the development combination of the Coroutine + Channel is the famous CSP programming model.

In Swoole development, Channel is usually used for implementing connection pool or scheduling coroutine concurrent.

The simplest example of a connection pool

In the following example, we have a thousand concurrently requests to redis. Normally, this has exceeded the maximum number of Redis connections setting and will throw a connection exception, but the connection pool based on Channel can perfectly schedule requests. We don't have to worry about connection overload.

class RedisPool
{
    /**@var \Swoole\Coroutine\Channel */
    protected $pool;

    /**
     * RedisPool constructor.
     * @param int $size max connections
     */
    public function __construct(int $size = 100)
    {
        $this->pool = new \Swoole\Coroutine\Channel($size);
        for ($i = 0; $i < $size; $i++) {
            $redis = new \Swoole\Coroutine\Redis();
            $res = $redis->connect('127.0.0.1', 6379);
            if ($res == false) {
                throw new \RuntimeException("failed to connect redis server.");
            } else {
                $this->put($redis);
            }
        }
    }

    public function get(): \Swoole\Coroutine\Redis
    {
        return $this->pool->pop();
    }

    public function put(\Swoole\Coroutine\Redis $redis)
    {
        $this->pool->push($redis);
    }

    public function close(): void
    {
        $this->pool->close();
        $this->pool = null;
    }
}

go(function () {
    $pool = new RedisPool();
    // max concurrency num is more than max connections
    // but it's no problem, channel will help you with scheduling
    for ($c = 0; $c < 1000; $c++) {
        go(function () use ($pool, $c) {
            for ($n = 0; $n < 100; $n++) {
                $redis = $pool->get();
                assert($redis->set("awesome-{$c}-{$n}", 'swoole'));
                assert($redis->get("awesome-{$c}-{$n}") === 'swoole');
                assert($redis->delete("awesome-{$c}-{$n}"));
                $pool->put($redis);
            }
        });
    }
});

Producer and consumers

Some Swoole's clients implement the defer mode for concurrency, but you can still implement it flexible with a combination of coroutines and channels.

go(function () {
    // User: I need you to bring me some information back.
    // Channel: OK! I will be responsible for scheduling.
    $channel = new Swoole\Coroutine\Channel;
    go(function () use ($channel) {
        // Coroutine A: Ok! I will show you the github addr info
        $addr_info = Co::getaddrinfo('github.com');
        $channel->push(['A', json_encode($addr_info, JSON_PRETTY_PRINT)]);
    });
    go(function () use ($channel) {
        // Coroutine B: Ok! I will show you what your code look like
        $mirror = Co::readFile(__FILE__);
        $channel->push(['B', $mirror]);
    });
    go(function () use ($channel) {
        // Coroutine C: Ok! I will show you the date
        $channel->push(['C', date(DATE_W3C)]);
    });
    for ($i = 3; $i--;) {
        list($id, $data) = $channel->pop();
        echo "From {$id}:\n {$data}\n";
    }
    // User: Amazing, I got every information at earliest time!
});

Timer

$id = Swoole\Timer::tick(100, function () {
    echo "⚙️ Do something...\n";
});
Swoole\Timer::after(500, function () use ($id) {
    Swoole\Timer::clear($id);
    echo "⏰ Done\n";
});
Swoole\Timer::after(1000, function () use ($id) {
    if (!Swoole\Timer::exists($id)) {
        echo "✅ All right!\n";
    }
});

The way of coroutine

go(function () {
    $i = 0;
    while (true) {
        Co::sleep(0.1);
        echo "📝 Do something...\n";
        if (++$i === 5) {
            echo "🛎 Done\n";
            break;
        }
    }
    echo "🎉 All right!\n";
});

🔥 Amazing runtime hooks

As of Swoole v4.1.0, we added the ability to transform synchronous PHP network libraries into co-routine libraries using a single line of code.

Simply call the Swoole\Runtime::enableCoroutine() method at the top of your script. In the sample below we connect to php-redis and concurrently read 10k requests in 0.1s:

Swoole\Runtime::enableCoroutine();
$s = microtime(true);
Co\run(function() {
    for ($c = 100; $c--;) {
        go(function () {
            ($redis = new Redis)->connect('127.0.0.1', 6379);
            for ($n = 100; $n--;) {
                assert($redis->get('awesome') === 'swoole');
            }
        });
    }
});
echo 'use ' . (microtime(true) - $s) . ' s';

By calling this method, the Swoole kernel replaces ZendVM stream function pointers. If you use php_stream based extensions, all socket operations can be dynamically converted to be asynchronous IO scheduled by coroutine at runtime!

How many things you can do in 1s?

Sleep 10K times, read, write, check and delete files 10K times, use PDO and MySQLi to communicate with the database 10K times, create a TCP server and multiple clients to communicate with each other 10K times, create a UDP server and multiple clients to communicate with each other 10K times... Everything works well in one process!

Just see what the Swoole brings, just imagine...

Swoole\Runtime::enableCoroutine();
$s = microtime(true);
Co\run(function() {
    // i just want to sleep...
    for ($c = 100; $c--;) {
        go(function () {
            for ($n = 100; $n--;) {
                usleep(1000);
            }
        });
    }

    // 10K file read and write
    for ($c = 100; $c--;) {
        go(function () use ($c) {
            $tmp_filename = "/tmp/test-{$c}.php";
            for ($n = 100; $n--;) {
                $self = file_get_contents(__FILE__);
                file_put_contents($tmp_filename, $self);
                assert(file_get_contents($tmp_filename) === $self);
            }
            unlink($tmp_filename);
        });
    }

    // 10K pdo and mysqli read
    for ($c = 50; $c--;) {
        go(function () {
            $pdo = new PDO('mysql:host=127.0.0.1;dbname=test;charset=utf8', 'root', 'root');
            $statement = $pdo->prepare('SELECT * FROM `user`');
            for ($n = 100; $n--;) {
                $statement->execute();
                assert(count($statement->fetchAll()) > 0);
            }
        });
    }
    for ($c = 50; $c--;) {
        go(function () {
            $mysqli = new Mysqli('127.0.0.1', 'root', 'root', 'test');
            $statement = $mysqli->prepare('SELECT `id` FROM `user`');
            for ($n = 100; $n--;) {
                $statement->bind_result($id);
                $statement->execute();
                $statement->fetch();
                assert($id > 0);
            }
        });
    }

    // php_stream tcp server & client with 12.8K requests in single process
    function tcp_pack(string $data): string
    {
        return pack('n', strlen($data)) . $data;
    }

    function tcp_length(string $head): int
    {
        return unpack('n', $head)[1];
    }

    go(function () {
        $ctx = stream_context_create(['socket' => ['so_reuseaddr' => true, 'backlog' => 128]]);
        $socket = stream_socket_server(
            'tcp://0.0.0.0:9502',
            $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctx
        );
        if (!$socket) {
            echo "$errstr ($errno)\n";
        } else {
            $i = 0;
            while ($conn = stream_socket_accept($socket, 1)) {
                stream_set_timeout($conn, 5);
                for ($n = 100; $n--;) {
                    $data = fread($conn, tcp_length(fread($conn, 2)));
                    assert($data === "Hello Swoole Server #{$n}!");
                    fwrite($conn, tcp_pack("Hello Swoole Client #{$n}!"));
                }
                if (++$i === 128) {
                    fclose($socket);
                    break;
                }
            }
        }
    });
    for ($c = 128; $c--;) {
        go(function () {
            $fp = stream_socket_client("tcp://127.0.0.1:9502", $errno, $errstr, 1);
            if (!$fp) {
                echo "$errstr ($errno)\n";
            } else {
                stream_set_timeout($fp, 5);
                for ($n = 100; $n--;) {
                    fwrite($fp, tcp_pack("Hello Swoole Server #{$n}!"));
                    $data = fread($fp, tcp_length(fread($fp, 2)));
                    assert($data === "Hello Swoole Client #{$n}!");
                }
                fclose($fp);
            }
        });
    }

    // udp server & client with 12.8K requests in single process
    go(function () {
        $socket = new Swoole\Coroutine\Socket(AF_INET, SOCK_DGRAM, 0);
        $socket->bind('127.0.0.1', 9503);
        $client_map = [];
        for ($c = 128; $c--;) {
            for ($n = 0; $n < 100; $n++) {
                $recv = $socket->recvfrom($peer);
                $client_uid = "{$peer['address']}:{$peer['port']}";
                $id = $client_map[$client_uid] = ($client_map[$client_uid] ?? -1) + 1;
                assert($recv === "Client: Hello #{$id}!");
                $socket->sendto($peer['address'], $peer['port'], "Server: Hello #{$id}!");
            }
        }
        $socket->close();
    });
    for ($c = 128; $c--;) {
        go(function () {
            $fp = stream_socket_client("udp://127.0.0.1:9503", $errno, $errstr, 1);
            if (!$fp) {
                echo "$errstr ($errno)\n";
            } else {
                for ($n = 0; $n < 100; $n++) {
                    fwrite($fp, "Client: Hello #{$n}!");
                    $recv = fread($fp, 1024);
                    list($address, $port) = explode(':', (stream_socket_get_name($fp, true)));
                    assert($address === '127.0.0.1' && (int)$port === 9503);
                    assert($recv === "Server: Hello #{$n}!");
                }
                fclose($fp);
            }
        });
    }
});
echo 'use ' . (microtime(true) - $s) . ' s';

⌛️ Installation

As with any open source project, Swoole always provides the most reliable stability and the most powerful features in the latest released version. Please ensure as much as possible that you are using the latest version.

Compiling requirements

  • Linux, OS X or Cygwin, WSL
  • PHP 7.2.0 or later (The higher the version, the better the performance.)
  • GCC 4.8 or later

1. Install via PECL (beginners)

pecl install openswoole

2. Install from source (recommended)

Please download the source packages from Releases or:

git clone https://github.com/openswoole/swoole-src.git && \
cd swoole-src

Compile and install at the source folder:

phpize && \
./configure && \
make && make install

Enable extension in PHP

After compiling and installing to the system successfully, you have to add a new line extension=openswoole.so to php.ini to enable Swoole extension.

Extra compiler configurations

for example: ./configure --enable-openssl --enable-sockets

  • --enable-openssl or --with-openssl-dir=DIR
  • --enable-sockets
  • --enable-http2
  • --enable-mysqlnd (need mysqlnd, it just for supporting $mysql->escape method)
  • --enable-swoole-json
  • --enable-swoole-curl

Upgrade

⚠️ If you upgrade from source, don't forget to make clean before you upgrade your swoole

  1. pecl upgrade openswoole
  2. cd swoole-src && git pull && make clean && make && sudo make install
  3. if you change your PHP version, please re-run phpize clean && phpize then try to compile

💎 Frameworks & Components

  • Hyperf is a coroutine framework that focuses on hyperspeed and flexibility, specifically used for build microservices or middlewares.
  • Swoft is a modern, high-performance AOP and coroutine PHP framework.
  • Easyswoole is a simple, high-performance PHP framework, based on Swoole, which makes using Swoole as easy as echo "hello world".
  • MixPHP is a powerful single-threaded coroutine framework with a very small footprint, simple and elegant.
  • imi is a high-performance coroutine application development framework based on PHP Swoole, which supports the development of HttpApi, WebSocket, TCP, UDP services.
  • Saber is a human-friendly, high-performance HTTP client component that has almost everything you can imagine.
  • One is a minimalist, high-performance PHP framework that supports the [swoole | php-fpm] environment

🛠 Develop & Discussion

🍭 Benchmark

  • On the open source Techempower Web Framework benchmarks Swoole used MySQL database benchmark to rank first, and all performance tests ranked in the first echelon.
  • You can just run Benchmark Script to quickly test the maximum QPS of Swoole-HTTP-Server on your machine.

🔰️ Security issues

Security issues should be reported privately, via email, to the Swoole develop team [email protected]. You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message.

🖊️ Contribution

Your contribution to Swoole development is very welcome!

You may contribute in the following ways:

❤️ Contributors

This project exists thanks to all the people who contribute. [Contributors].

🎙️ Official Evangelist

Demin has been playing with PHP since 2000, focusing on building high-performance, secure web services. He is an occasional conference speaker on PHP and Swoole, and has been working for companies in the states like eBay, Visa and Glu Mobile for years. You may find Demin on Twitter or GitHub.

📃 License

Apache License Version 2.0 see http://www.apache.org/licenses/LICENSE-2.0.html

Owner
Open Swoole
Open source PHP extension for Async IO, Coroutines and Fibers
Open Swoole
Comments
  • Centos 7 PHP 8.1 openswoole 4.11 Segmentation fault when using composer  with openswoole enabled.

    Centos 7 PHP 8.1 openswoole 4.11 Segmentation fault when using composer with openswoole enabled.

    Segmentation fault when using composer with openswoole enabled.

    $ composer --version Composer version 2.2.9 2022-03-15 22:13:3

    $ composer self-update Loading composer repositories with package information Segmentation fault

    $ composer update Loading composer repositories with package information Segmentation fault

    [ 2302.606382] php[22817]: segfault at 100000011 ip 00007f0ef21bec39 sp 00007ffcb2df47e0 error 4 in openswoole.so[7f0ef2072000+168000] [ 2538.172864] php[23170]: segfault at 100000011 ip 00007fed669ccc39 sp 00007ffcffbe87a0 error 4 in openswoole.so[7fed66880000+168000] [ 2591.233557] php[23219]: segfault at 17 ip 00007f23e0a02c39 sp 00007ffc9b20c3f0 error 4 in openswoole.so[7f23e08b6000+168000] CentOS Linux release 7.9.2009 (Core) 3.10.0-1160.59.1.el7.x86_64 #1 SMP Wed Feb 23 16:47:03 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

    openswoole

    Open Swoole => enabled Author => Open Swoole Group [email protected] Version => 4.11.0 Built => Mar 24 2022 16:14:20 coroutine => enabled with boost asm context trace_log => enabled epoll => enabled eventfd => enabled signalfd => enabled cpu_affinity => enabled spinlock => enabled rwlock => enabled sockets => enabled openssl => OpenSSL 1.0.2k-fips 26 Jan 2017 http2 => enabled json => enabled curl-native => enabled pcre => enabled c-ares => 1.10.0 zlib => 1.2.7 mutex_timedlock => enabled pthread_barrier => enabled futex => enabled mysqlnd => enabled async_redis => enabled postgresql => enabled

    Directive => Local Value => Master Value swoole.enable_coroutine => On => On swoole.enable_library => On => On swoole.enable_preemptive_scheduler => Off => Off swoole.display_errors => On => On swoole.use_shortname => On => On swoole.unixsock_buffer_size => 8388608 => 8388608

  • Randomly throwing WARNING ProcessPool::wait(): worker#7 abnormal exit, status=0, signal=13

    Randomly throwing WARNING ProcessPool::wait(): worker#7 abnormal exit, status=0, signal=13

    1. What did you do? If possible, provide a simple script for reproducing the error.

    I have started to notice some requests failing in my server. I have an nginx in front of my openswoole-based app, that was returning 502 statuses randomly.

    I checked the logs of my application, and it was printing some random lines like this one, always matching the time of the failing requests:

    WARNING ProcessPool::wait(): worker#7 abnormal exit, status=0, signal=13

    The worker number changes, but the rest is always the same.

    I'm not aware of having done anything different recently, but I guess understanding what this warning means would probably help me find what is wrong. I have searched and haven't found any documentation relative to this.

    My application is running with 16 web workers and 16 task workers, and some requests might trigger tasks.

    1. What did you expect to see?

    No errors in the logs and all requests working properly.

    1. What did you see instead?

    The warning described above, followed by a failed request.

    1. What version of OpenSwoole are you using (show your php --ri openswoole)?
    # php --ri openswoole
    
    openswoole
    
    Open Swoole => enabled
    Author => Open Swoole Group <[email protected]>
    Version => 4.11.0
    Built => Apr 23 2022 09:58:09
    coroutine => enabled with boost asm context
    epoll => enabled
    eventfd => enabled
    signalfd => enabled
    spinlock => enabled
    rwlock => enabled
    mutex_timedlock => enabled
    pthread_barrier => enabled
    async_redis => enabled
    
    Directive => Local Value => Master Value
    swoole.enable_coroutine => On => On
    swoole.enable_library => On => On
    swoole.enable_preemptive_scheduler => Off => Off
    swoole.display_errors => On => On
    swoole.use_shortname => On => On
    swoole.unixsock_buffer_size => 8388608 => 8388608
    
    1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?
    # uname -a
    Linux ff7c15bffeda 5.15.0-27-generic #28-Ubuntu SMP Thu Apr 14 04:55:28 UTC 2022 x86_64 Linux
    
    # php -v
    PHP 8.1.5 (cli) (built: Apr 18 2022 23:48:54) (NTS)
    Copyright (c) The PHP Group
    Zend Engine v4.1.5, Copyright (c) Zend Technologies
    
    # gcc -v
    /bin/sh: gcc: not found
    

    There's no gcc, as this is running on Alpine.

  • Pecl install requires libpq-fe.h (Postgres) even though --with-postgres=n

    Pecl install requires libpq-fe.h (Postgres) even though --with-postgres=n

    Please answer these questions before submitting your issue. Thanks!

    1. What did you do? If possible, provide a simple script for reproducing the error. pecl install openswoole-4.8.1

    Full output at the bottom of this issue.

    Also note that this is a brand new installation of ubuntu 18.04, just upgraded to 20.04. This is a bare metal install, and not a virtualized install. I have installed some things necessary for php8.1, and that is it. (my php module list is below)

    This may also be important: the first time I tried to install openswoole on this machine, I selected 'y' for postgres support. When it failed, I tried setting it to 'n'. When that also failed, I tried deleting pear's cache and selecting 'n' again. When that failed, I rebooted and selected 'n' again. I rebooted a couple more times, and the install failed every time in the same was as what I've pasted at the bottom of this issue.

    1. What did you expect to see?

    I expected the installation to run successfully

    1. What did you see instead?

    That it failed requiring Postgres, even though I selected 'n' for Postgres support.

    1. What version of Open Swoole are you using (show your php --ri openswoole)?

    Attempting to install openswoole-4.8.1 from pecl, on php8.1

    1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?

    uname -a

    Linux s187667 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
    

    php -v

    PHP 8.1.0 (cli) (built: Nov 25 2021 20:22:03) (NTS)
    Copyright (c) The PHP Group
    Zend Engine v4.1.0, Copyright (c) Zend Technologies
        with Zend OPcache v8.1.0, Copyright (c), by Zend Technologies
    

    gcc -v

    Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.3.0-17ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-HskZEa/gcc-9-9.3.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
    Thread model: posix
    gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)
    

    php -m

    [PHP Modules]
    calendar
    Core
    ctype
    curl
    date
    dba
    dom
    exif
    FFI
    fileinfo
    filter
    ftp
    gd
    gettext
    hash
    iconv
    igbinary
    imap
    intl
    json
    libxml
    mbstring
    mysqli
    mysqlnd
    openssl
    pcntl
    pcre
    PDO
    pdo_mysql
    pdo_pgsql
    pdo_sqlite
    pgsql
    Phar
    posix
    readline
    Reflection
    session
    shmop
    SimpleXML
    sockets
    sodium
    SPL
    sqlite3
    standard
    sysvmsg
    sysvsem
    sysvshm
    tidy
    tokenizer
    xml
    xmlreader
    xmlwriter
    xsl
    Zend OPcache
    zip
    zlib
    
    [Zend Modules]
    Zend OPcache
    

    full install output:

    # pecl install openswoole-4.8.1
    WARNING: channel "pecl.php.net" has updated its protocols, use "pecl channel-update pecl.php.net" to update
    downloading openswoole-4.8.1.tgz ...
    Starting to download openswoole-4.8.1.tgz (1,623,495 bytes)
    .................................................................................................................................................................................................................................................................................................................................done: 1,623,495 bytes
    447 source files, building
    running: phpize
    Configuring for:
    PHP Api Version:         20210902
    Zend Module Api No:      20210902
    Zend Extension Api No:   420210902
    enable sockets supports? [no] : y
    enable openssl support? [no] : y
    enable http2 support? [no] : y
    enable mysqlnd support? [no] : y
    enable json support? [no] : y
    enable curl support? [no] : y
    enable postgres support? [no] : n
    building in /tmp/pear/temp/pear-build-customeriMr8YV/openswoole-4.8.1
    running: /tmp/pear/temp/openswoole/configure --with-php-config=/usr/bin/php-config --enable-sockets=y --enable-openssl=y --enable-http2=y --enable-mysqlnd=y --enable-swoole-json=y --enable-swoole-curl=y --with-postgres=n
    checking for grep that handles long lines and -e... /bin/grep
    checking for egrep... /bin/grep -E
    checking for a sed that does not truncate output... /bin/sed
    checking for pkg-config... /usr/bin/pkg-config
    checking pkg-config is at least version 0.9.0... yes
    checking for cc... cc
    checking whether the C compiler works... yes
    checking for C compiler default output file name... a.out
    checking for suffix of executables...
    checking whether we are cross compiling... no
    checking for suffix of object files... o
    checking whether we are using the GNU C compiler... yes
    checking whether cc accepts -g... yes
    checking for cc option to accept ISO C89... none needed
    checking how to run the C preprocessor... cc -E
    checking for icc... no
    checking for suncc... no
    checking for system library directory... lib
    checking if compiler supports -R... no
    checking if compiler supports -Wl,-rpath,... yes
    checking build system type... x86_64-pc-linux-gnu
    checking host system type... x86_64-pc-linux-gnu
    checking target system type... x86_64-pc-linux-gnu
    checking for PHP prefix... /usr
    checking for PHP includes... -I/usr/include/php/20210902 -I/usr/include/php/20210902/main -I/usr/include/php/20210902/TSRM -I/usr/include/php/20210902/Zend -I/usr/include/php/20210902/ext -I/usr/include/php/20210902/ext/date/lib
    checking for PHP extension directory... /usr/lib/php/20210902
    checking for PHP installed headers prefix... /usr/include/php/20210902
    checking if debug is enabled... no
    checking if zts is enabled... no
    checking for gawk... no
    checking for nawk... nawk
    checking if nawk is broken... no
    checking enable debug log... no
    checking enable trace log... no
    checking enable sockets support... y
    checking enable openssl support... y
    checking enable http2.0 support... y
    checking swoole support... yes, shared
    checking enable mysqlnd support... y
    checking enable postgreSQL support... n
    checking enable c-ares support... no
    checking dir of openssl... no
    checking dir of jemalloc... no
    checking enable asan... no
    checking whether to enable swoole coverage support... no
    checking whether to enable Swoole developer build flags... no
    checking whether to enable Swoole JSON build flags... y
    checking whether to enable Swoole CURL build flags... y
    checking whether to enable thread context... no
    checking if compiling with clang... no
    checking for cc option to accept ISO C99... none needed
    checking for accept4 in -lc... yes
    checking for signalfd in -lc... yes
    checking for eventfd in -lc... yes
    checking for epoll_create in -lc... yes
    checking for poll in -lc... yes
    checking for sendfile in -lc... yes
    checking for kqueue in -lc... no
    checking for backtrace in -lc... yes
    checking for daemon in -lc... yes
    checking for mkostemp in -lc... yes
    checking for inotify_init in -lc... yes
    checking for malloc_trim in -lc... yes
    checking for inotify_init1 in -lc... yes
    checking for ptrace in -lc... yes
    checking for getrandom in -lc... yes
    checking for arc4random in -lc... no
    checking for pthread_rwlock_init in -lpthread... yes
    checking for pthread_spin_lock in -lpthread... yes
    checking for pthread_mutex_timedlock in -lpthread... yes
    checking for pthread_barrier_init in -lpthread... yes
    checking for pthread_mutexattr_setpshared in -lpthread... yes
    checking for pthread_mutexattr_setrobust in -lpthread... yes
    checking for pthread_mutex_consistent in -lpthread... yes
    checking for pcre_compile in -lpcre... no
    checking for ares_gethostbyname in -lcares... yes
    checking for gzgets in -lz... yes
    checking for BrotliEncoderCreateInstance in -lbrotlienc... yes
    checking for BrotliDecoderCreateInstance in -lbrotlidec... yes
    checking for cpu affinity... yes
    checking for socket REUSEPORT... yes
    checking for futex... yes
    checking for ucontext... yes
    checking for g++... g++
    checking whether we are using the GNU C++ compiler... yes
    checking whether g++ accepts -g... yes
    checking for valgrind... no
    checking how to run the C++ preprocessor... g++ -E
    checking for ANSI C header files... yes
    checking for sys/types.h... yes
    checking for sys/stat.h... yes
    checking for stdlib.h... yes
    checking for string.h... yes
    checking for memory.h... yes
    checking for strings.h... yes
    checking for inttypes.h... yes
    checking for stdint.h... yes
    checking for unistd.h... yes
    checking for struct cmsghdr... yes
    checking for hstrerror... yes
    checking for socketpair... yes
    checking for if_nametoindex... yes
    checking for if_indextoname... yes
    checking netdb.h usability... yes
    checking netdb.h presence... yes
    checking for netdb.h... yes
    checking netinet/tcp.h usability... yes
    checking netinet/tcp.h presence... yes
    checking for netinet/tcp.h... yes
    checking sys/un.h usability... yes
    checking sys/un.h presence... yes
    checking for sys/un.h... yes
    checking sys/sockio.h usability... no
    checking sys/sockio.h presence... no
    checking for sys/sockio.h... no
    checking for field ss_family in struct sockaddr_storage... yes
    checking if getaddrinfo supports AI_V4MAPPED... yes
    checking if getaddrinfo supports AI_ALL... yes
    checking if getaddrinfo supports AI_IDN... yes
    checking if gethostbyname2_r is supported... yes
    checking for valgrind... no
    checking for clock_gettime in -lrt... yes
    checking openssl fallback dir... checking for SSL_connect in -lssl... yes
    checking for pg_config... not found
    configure: error: Cannot find libpq-fe.h. Please specify correct PostgreSQL installation path
    ERROR: `/tmp/pear/temp/openswoole/configure --with-php-config=/usr/bin/php-config --enable-sockets=y --enable-openssl=y --enable-http2=y --enable-mysqlnd=y --enable-swoole-json=y --enable-swoole-curl=y --with-postgres=n' failed
    
  • Bug When Calling a Coroutine from Within Loops?

    Bug When Calling a Coroutine from Within Loops?

    Please answer these questions before submitting your issue. Thanks!

    1. What did you do? If possible, provide a simple script for reproducing the error.

    Using the code below, run it as-is. Then uncomment the three lines in two separate places below, to add a while loop. You'll notice that it does not return the IP addresses.

    I am not sure why this would be happening, but I just spent a few hours trying to narrow down why another piece of code wasn't working, and was able to narrow down an example to this.

    <?php
    Co::set(['dns_server' => '8.8.8.8:53']);
    
    ////////////////////////////////////////////////////////////////////////////////
    class ObjectGetIp
    {
    	//----------------------------------------------------------------------------
    	public function coroDoTask($cb, $host) {
    		Swoole\Coroutine::create($cb, ['scheme' => 'https',
    		                               'host'   => $host,
    		                               'path'   => '/']);
    	}
    
    	//----------------------------------------------------------------------------
    	public function download($params) {
    		$host = $params['host'];
    		echo "LINE: ".__LINE__."\n";
    		$ip = Swoole\Coroutine\System::dnsLookup($host, $timeout = 2);
    		echo "Found IP: $ip\n\n";
    	}
    
    	//----------------------------------------------------------------------------
    	public function getHost()
    	{
    		$hosts = [
    			'yahoo.com','msn.com','google.com','bing.com','twitch.tv','qq.com','ebay.com','duckduckgo.com','tiktok.com','paypal.com','aliexpress.com',
    		];
    		return [$hosts[rand(0,10)]];
    	}
    
    	//----------------------------------------------------------------------------
    	public function GetIps()
    	{
    
    		// BEGIN: TEST UN/COMMENT OUT THIS LINE
    		// while (1) {
    		// END: TEST UN/COMMENT OUT THIS LINE
    
    			$x = 5;
    			while ($x--) {
    				$hosts = $this->getHost();
    				foreach ($hosts as $host) {
    					$this->coroDoTask([$this,'download'], $host);
    				}
    			}
    
    		// BEGIN: TEST UN/COMMENT OUT THESE TWO LINES
    		// 	sleep(1);
    		// }
    		// END: TEST UN/COMMENT OUT THESE TWO LINES
    
    	}
    }
    
    //==============================================================================
    $obj = new ObjectGetIp;
    $obj->GetIps();
    
    1. What did you expect to see?

    I expected to see IP addresses.

    1. What did you see instead?

    I saw nothing.

    1. What version of Open Swoole are you using (show your php --ri openswoole)? swoole

      Swoole => enabled Author => Swoole Team [email protected] Version => 4.8.1 Built => Oct 30 2021 14:45:42 coroutine => enabled with boost asm context epoll => enabled eventfd => enabled signalfd => enabled cpu_affinity => enabled spinlock => enabled rwlock => enabled sockets => enabled openssl => OpenSSL 1.1.1j 16 Feb 2021 dtls => enabled http2 => enabled json => enabled curl-native => enabled pcre => enabled zlib => 1.2.11 brotli => E16777225/D16777225 mutex_timedlock => enabled pthread_barrier => enabled futex => enabled mysqlnd => enabled async_redis => enabled

      Directive => Local Value => Master Value swoole.enable_coroutine => On => On swoole.enable_library => On => On swoole.enable_preemptive_scheduler => Off => Off swoole.display_errors => On => On swoole.use_shortname => On => On swoole.unixsock_buffer_size => 8388608 => 8388608

    2. What is your machine environment used (show your uname -a & php -v & gcc -v) ?

      Linux hostname 5.4.0-90-generic #101-Ubuntu SMP Fri Oct 15 20:00:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

      PHP 8.0.13 (cli) (built: Nov 22 2021 09:50:43) ( NTS ) Copyright (c) The PHP Group Zend Engine v4.0.13, Copyright (c) Zend Technologies with Zend OPcache v8.0.13, Copyright (c), by Zend Technologies

      Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:hsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.3.0-17ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-HskZEa/gcc-9-9.3.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)

  • Executing multiple processes through scheduler with blocking I/O

    Executing multiple processes through scheduler with blocking I/O

    Please answer these questions before submitting your issue. Thanks!

    1. What did you do? If possible, provide a simple script for reproducing the error.
    $run = new Coroutine\Scheduler();
    
    $channel = $this->conn->channel();
    $tokenService = $this->tokenService;
    $connAssignService = $this->serverAssignmentService;
    $appManager = $this->applicationManager;
    
    foreach($this->queues->toArray() as $queue){
        $run->add(static function() use ($queue, $channel, $tokenService, $connAssignService, $appManager){
            echo "1\n";
            $channel->queue_declare($queue->getName(), ...$queue->getOptions());
    
            $channel->basic_consume(
                $queue->getName(),
                '',
                false,
                true,
                false,
                false,
                /**
                 * @param AMQPMessage $msg
                 */
                static function($msg) use ($queue, $tokenService, $connAssignService){
                    $msg = QueueMessage::fromAMQPMessage($msg);
                    dump($msg->getEvent());
                    /**
                     * Find the server where this message is coming from
                     */
                    $server = $connAssignService->findServerById($msg->getServer());
    
                    if(null === $server){
                        dump("Unknown server {$msg->getServer()}");
                        return;
                    }
    
                    /**
                     * Check if client is authenticated and token has not expired
                     */
                    $token = $tokenService->findByToken($msg->getToken(), false);
    
                    if(null === $token){
                        dump("No records found for token (or token expired): {$msg->getToken()}");
                        return;
                    }
    
                    /**
                     * Refresh token expiry time only if token is not a permanent token
                     */
                    if(!$token->isPermaToken()) {
                        $tokenService->refresh($token);
                    }
    
                    /**
                     * If token is not found within server connections, create it
                     */
                    if(!$connAssignService->findByToken($token)){
    
                        $connAssignService->create($server, $token, $msg->getConnectionID());
    
                    }else{
                        /**
                         * If token IS found, update connection ID as it may change on reconnects
                         */
                        $connAssignService->updateConnectionId($token, $msg->getConnectionID());
                    }
    
                    $queue->run(
                        $msg,
                        $token, //Pass current token
                        $tokenService->findByUser($token->getUser()) //Pass along all available tokens
                    );
                }
            );
    
            while ($channel->is_open()){
                $channel->wait();
            }
        });
    }
    $run->start();
    
    1. What did you expect to see?

    I expected that all lambdas would be executed but only the first one gets executed and the other one never runs

    1. What did you see instead?

    2. What version of Open Swoole are you using (show your php --ri openswoole)?

    Version => 4.7.1

    1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?

    Linux 998e65b5fd02 4.19.0-18-amd64 #1 SMP Debian 4.19.208-1 (2021-09-29) x86_64 GNU/Linux Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 10.2.1-6' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-Km9U7s/gcc-10-10.2.1/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-10-Km9U7s/gcc-10-10.2.1/debian/tmp-gcn/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 10.2.1 20210110 (Debian 10.2.1-6) [1]- Done uname -a [email protected]:/var/www/html# PHP 7.3.31 (cli) (built: Sep 28 2021 16:33:55) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.31, Copyright (c) 1998-2018 Zend Technologies

  • malloc: *** error for object 0x7f9c5ff9a940: pointer being freed was not allocated

    malloc: *** error for object 0x7f9c5ff9a940: pointer being freed was not allocated

    Please answer these questions before submitting your issue. Thanks!

    1. What did you do? If possible, provide a simple script for reproducing the error.

    I ran into an issue in a real application of mine, and managed to reduce it to a reproducible script:

    https://github.com/apinstein/swoole-utils/blob/main/examples/cause-swoole-malloc.php

    Should be able to just download that repo, composer install and run php examples/cause-swoole-malloc.php

    1. What did you expect to see?

    No crash :)

    1. What did you see instead?

    php(93377,0x10b853e00) malloc: *** error for object 0x7f9c5ff9a940: pointer being freed was not allocated php(93377,0x10b853e00) malloc: *** set a breakpoint in malloc_error_break to debug zsh: abort php examples/crash.php

    Occurs after about 10 minutes.

    1. What version of Swoole are you using (show your php --ri swoole)?
    [ [email protected] ]:☹ 1> php --ri swoole
    
    swoole
    
    Swoole => enabled
    Author => Swoole Team <[email protected]>
    Version => 4.7.1
    Built => Aug 27 2021 10:56:54
    coroutine => enabled with boost asm context
    kqueue => enabled
    rwlock => enabled
    openssl => OpenSSL 1.1.1l  24 Aug 2021
    dtls => enabled
    http2 => enabled
    pcre => enabled
    zlib => 1.2.11
    brotli => E16777225/D16777225
    async_redis => enabled
    
    Directive => Local Value => Master Value
    swoole.enable_coroutine => On => On
    swoole.enable_library => On => On
    swoole.enable_preemptive_scheduler => Off => Off
    swoole.display_errors => On => On
    swoole.use_shortname => On => On
    swoole.unixsock_buffer_size => 262144 => 262144
    
    1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?
    [ [email protected] ]:☺ > uname -a      
    Darwin Alans-MacBook-Pro-2.local 20.6.0 Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:31 PDT 2021; root:xnu-7195.141.2~5/RELEASE_X86_64 x86_64
    
    [ [email protected] ]:☺ > php -v       
    PHP 8.0.10 (cli) (built: Aug 27 2021 10:07:52) ( NTS )
    Copyright (c) The PHP Group
    Zend Engine v4.0.10, Copyright (c) Zend Technologies
        with Zend OPcache v8.0.10, Copyright (c), by Zend Technologies
    
    # This is using a prebuild PHP binary from macports
    Build System => Darwin bigsurx.internal.macports.net 20.6.0 Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:31 PDT 2021; root:xnu-7195.141.2~5/RELEASE_X86_64 x86_64
    
    []:☺ > gcc -v
    Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
    Apple clang version 12.0.5 (clang-1205.0.22.11)
    Target: x86_64-apple-darwin20.6.0
    Thread model: posix
    InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
    
  • Add pgsql status and reset commands to client

    Add pgsql status and reset commands to client

    This PR adds libpq PQstatus and PQreset functions to the PostgreSQL client.

    This is mainly to assist long-lived connections to a database within a connection pool, where a connection may be dropped while the connection is still in the pool due to network or database resets.

  • PHP 8.1.0RC6 issue

    PHP 8.1.0RC6 issue

    Please answer these questions before submitting your issue. Thanks!

    1. What did you do? If possible, provide a simple script for reproducing the error.

    Unknown error type: [8192]: Return type of Swoole\ArrayObject::rewind() should either be compatible with Iterator::rewind(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in @swoole-src/library/core/ArrayObject.php on line 80

    1. What did you expect to see?

    n/a

    1. What did you see instead?

    n/a

    1. What version of Open Swoole are you using (show your php --ri openswoole)?

    Compiled from Master - 20.11.2021

    openswoole
    
    Open Swoole => enabled
    Author => Open Swoole Group & Contributors <[email protected]>
    Version => 4.7.2
    Built => Nov 20 2021 22:37:49
    coroutine => enabled with boost asm context
    epoll => enabled
    eventfd => enabled
    signalfd => enabled
    cpu_affinity => enabled
    spinlock => enabled
    rwlock => enabled
    sockets => enabled
    openssl => OpenSSL 1.1.1f  31 Mar 2020
    dtls => enabled
    http2 => enabled
    json => enabled
    mutex_timedlock => enabled
    pthread_barrier => enabled
    futex => enabled
    async_redis => enabled
    
    Directive => Local Value => Master Value
    swoole.enable_coroutine => On => On
    swoole.enable_library => On => On
    swoole.enable_preemptive_scheduler => Off => Off
    swoole.display_errors => On => On
    swoole.use_shortname => On => On
    swoole.unixsock_buffer_size => 8388608 => 8388608
    
    1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?

    Linux 5.4.0-90-generic #101-Ubuntu SMP Fri Oct 15 20:00:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

    PHP 8.1.0RC6 (cli) (built: Nov 19 2021 06:49:51) (NTS)

    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
    OFFLOAD_TARGET_NAMES=nvptx-none:hsa
    OFFLOAD_TARGET_DEFAULT=1
    Target: x86_64-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.3.0-17ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-HskZEa/gcc-9-9.3.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
    Thread model: posix
    gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)
    
  • [bug] usleep function (with hooks) - unexpected behaviour (without actually delay)

    [bug] usleep function (with hooks) - unexpected behaviour (without actually delay)

    1. What did you do? If possible, provide a simple script for reproducing the error.
    Swoole\Runtime::enableCoroutine(true);
    Co\run(function () {
        go(function () {
            $t = microtime(true);
            usleep(10000);
            echo (microtime(true) - $t) * 1e6 . PHP_EOL;
        });
    });
    
    1. What did you expect to see?

    something like value with 10k microseconds. So I expected SAME result if I run Co::usleep(10000);

    Swoole\Runtime::enableCoroutine(true);
    Co\run(function () {
        go(function () {
            $t = microtime(true);
            Co::usleep(10000);
            echo (microtime(true) - $t) * 1e6 . PHP_EOL;
        });
    });
    
    1. What did you see instead?

    First code not return same result as second code. All values less then 1 000 000 works WITHOUT delay by fact with usleep() function.

    Co::usleep() works as expected.

    1. What version of OpenSwoole are you using (show your php --ri openswoole)?
    4.11.1
    
    
    1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?
    Linux platform-worker-75ccf956d4-c4frs 5.10.109+ #1 SMP Sun Apr 24 09:09:13 UTC 2022 x86_64 GNU/Linux
    
    PHP 8.1.8 (cli) (built: Jul  7 2022 22:48:08) (NTS)
    Copyright (c) The PHP Group
    Zend Engine v4.1.8, Copyright (c) Zend Technologies
        with Zend OPcache v8.1.8, Copyright (c), by Zend Technologies
    
    
  • openssl 1.1.1n error

    openssl 1.1.1n error

    my program run without SWOOLE_SSL but when i am use SWOOLE_SSL get error Segmentation fault. Please answer these questions before submitting your issue.

    1. What did you do? If possible, provide a simple script for reproducing the error. $server = new Server("0.0.0.0", 9502, SWOOLE_PROCESS,SWOOLE_SOCK_TCP | SWOOLE_SSL); $server->set([ 'daemonize' => false, 'ssl_verify_peer' => true, 'dispatch_mode' => 2, 'debug_mode' => 1, 'open_websocket_protocol' => true, 'log_file' => "./swoole.log", 'buffer_output_size' => 32 * 1024 * 1024, 'ssl_cert_file' => env('WS_SSL_CERT_FILE'), 'ssl_key_file' => env('WS_SSL_KEY_FILE'), ]);

    2. What did you expect to see? just run

    3. What did you see instead? [[email protected] panel]# gdb php -c core.12620 GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: http://www.gnu.org/software/gdb/bugs/... "/usr/local/bin/php": not in executable format: File format not recognized [New LWP 12620] Missing separate debuginfo for the main executable file Try: yum --enablerepo='debug' install /usr/lib/debug/.build-id/9c/1874600eef209dc28a768a2cbd7528cc807b55 Core was generated by `ea-php80 artisan swoole:serve'. Program terminated with signal 11, Segmentation fault. #0 0x00007fbdc313ebc0 in ?? () (gdb) bt #0 0x00007fbdc313ebc0 in ?? () #1 0x00007fbdbedbda9d in ?? () #2 0x0000000003055920 in ?? () #3 0x0000000003055920 in ?? () #4 0x00000000030557a0 in ?? () #5 0x00007fbdae49bae1 in ?? () #6 0x0000000000000000 in ?? ()

    4. What version of OpenSwoole are you using (show your php --ri openswoole)? swoole

    Swoole => enabled Author => Swoole Team [email protected] Version => 4.8.8 Built => Mar 31 2022 09:09:00 coroutine => enabled with boost asm context epoll => enabled eventfd => enabled signalfd => enabled cpu_affinity => enabled spinlock => enabled rwlock => enabled sockets => enabled openssl => OpenSSL 1.1.1n 15 Mar 2022 dtls => enabled http2 => enabled json => enabled curl-native => enabled pcre => enabled zlib => 1.2.7 mutex_timedlock => enabled pthread_barrier => enabled futex => enabled mysqlnd => enabled async_redis => enabled

    Directive => Local Value => Master Value swoole.enable_coroutine => On => On swoole.enable_library => On => On swoole.enable_preemptive_scheduler => Off => Off swoole.display_errors => On => On swoole.use_shortname => On => On swoole.unixsock_buffer_size => 8388608 => 8388608

    1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?

    Operating System: CentOS Linux 7 (Core) CPE OS Name: cpe:/o:centos:centos:7 Kernel: Linux 3.10.0-1160.59.1.el7.x86_64 Architecture: x86-64

    PHP 8.0.17 (cli) (built: Mar 23 2022 07:36:32) ( NTS ) Copyright (c) The PHP Group Zend Engine v4.0.17, Copyright (c) Zend Technologies with Zend OPcache v8.0.17, Copyright (c), by Zend Technologies

    Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux Thread model: posix gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)

  • Compilation failed on Debian Stretch: 'struct php_curl' has no member named 'postfields'

    Compilation failed on Debian Stretch: 'struct php_curl' has no member named 'postfields'

    Please answer these questions before submitting your issue. Thanks!

    1. What did you do? If possible, provide a simple script for reproducing the error.

    Start a docker image with

    docker run --rm -it php:7.3-cli-stretch bash
    

    From within the docker container, run these commands:

    apt-get update
    apt-get install -y libcurl4-gnutls-dev libpq-dev libssl1.0-dev
    pecl install openswoole
    # Enable curl support, that is, answer with:
    # enable sockets supports? [no] : no
    # enable openssl support? [no] : no
    # enable http2 support? [no] : no
    # enable mysqlnd support? [no] : no
    # enable json support? [no] : no
    # enable curl support? [no] : yes
    # enable postgres support? [no] : no
    
    1. What did you expect to see?

    The extension should compile

    1. What did you see instead?
    [...]
     g++ -DENABLE_PHP_SWOOLE -I. -I/tmp/pear/temp/openswoole -DPHP_ATOM_INC -I/tmp/pear/temp/pear-build-defaultuserRqGatl/openswoole-4.9.0/include -I/tmp/pear/temp/pear-build-defaultuserRqGatl/openswoole-4.9.0/main -I/tmp/pear/temp/openswoole -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib -I/tmp/pear/temp/openswoole -I/tmp/pear/temp/openswoole/include -I/tmp/pear/temp/openswoole/ext-src -I/tmp/pear/temp/openswoole/thirdparty/hiredis -DHAVE_CONFIG_H -g -O2 -Wall -Wno-unused-function -Wno-deprecated -Wno-deprecated-declarations -std=c++11 -c /tmp/pear/temp/openswoole/thirdparty/php/curl/interface.cc  -fPIC -DPIC -o thirdparty/php/curl/.libs/interface.o
    In file included from /usr/local/include/php/main/php_ini.h:22:0,
                     from /usr/local/include/php/main/fopen_wrappers.h:24,
                     from /usr/local/include/php/main/php.h:462,
                     from /tmp/pear/temp/openswoole/php_swoole.h:20,
                     from /tmp/pear/temp/openswoole/ext-src/php_swoole_private.h:25,
                     from /tmp/pear/temp/openswoole/ext-src/php_swoole_cxx.h:19,
                     from /tmp/pear/temp/openswoole/thirdparty/php/curl/interface.cc:19:
    /tmp/pear/temp/openswoole/thirdparty/php/curl/interface.cc: In function 'void _php_curl_set_default_options(php_curl*)':
    /usr/local/include/php/Zend/zend_ini.h:143:73: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
     #define INI_STR(name) zend_ini_string_ex((name), sizeof(name)-1, 0, NULL)
                                                                             ^
    /tmp/pear/temp/openswoole/thirdparty/php/curl/interface.cc:999:14: note: in expansion of macro 'INI_STR'
         cainfo = INI_STR("openssl.cafile");
                  ^~~~~~~
    /usr/local/include/php/Zend/zend_ini.h:143:73: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
     #define INI_STR(name) zend_ini_string_ex((name), sizeof(name)-1, 0, NULL)
                                                                             ^
    /tmp/pear/temp/openswoole/thirdparty/php/curl/interface.cc:1001:18: note: in expansion of macro 'INI_STR'
             cainfo = INI_STR("curl.cainfo");
                      ^~~~~~~
    /tmp/pear/temp/openswoole/thirdparty/php/curl/interface.cc: In function 'void _php_curl_free(php_curl*)':
    /tmp/pear/temp/openswoole/thirdparty/php/curl/interface.cc:2838:24: error: 'struct php_curl' has no member named 'postfields'
         zval_ptr_dtor(&ch->postfields);
                            ^~~~~~~~~~
    Makefile:400: recipe for target 'thirdparty/php/curl/interface.lo' failed
    make: *** [thirdparty/php/curl/interface.lo] Error 1
    ERROR: `make' failed
    
    1. What version of Open Swoole are you using (show your php --ri openswoole)?

    4.9.0

    1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?

    The php:7.3-cli-stretch docker image, where we have:

    $ uname -a
    Linux 9886c58d90f6 5.10.60.1-microsoft-standard-WSL2 #1 SMP Wed Aug 25 23:20:18 UTC 2021 x86_64 GNU/Linux
    
    $ php -v
    PHP 7.3.29 (cli) (built: Aug 17 2021 13:48:34) ( NTS )
    Copyright (c) 1997-2018 The PHP Group
    Zend Engine v3.3.29, Copyright (c) 1998-2018 Zend Technologies
    
    $ gcc -v
    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper
    Target: x86_64-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Debian 6.3.0-18+deb9u1' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-6 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
    Thread model: posix
    gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)
    
  • FreeBSD port for openswoole?

    FreeBSD port for openswoole?

    A simple copy of devel/pecl-swoole and brief edit of the Makefile (and a make makesum) is all that's needed apparently. I have this working if you want me to try and upload it here, but it's pretty straightforward.

  • [BUG] Postgresql fetch: reset internal pointer on row in some cases

    [BUG] Postgresql fetch: reset internal pointer on row in some cases

    1. What did you do? If possible, provide a simple script for reproducing the error.
    $pg = new Swoole\Coroutine\PostgreSQL();
    $conn = $pg->connect("host=127.0.0.1;port=5432;dbname=test;user=postgres;password=***");
    $pg->query('BEGIN');
    $result = $pg->query('SELECT * FROM test');
    $row1 = $pg->fetchAssoc($result); // Get First row
    $pg->query('SELECT 1'); // Some another query
    $row2 = $pg->fetchAssoc($result); // Try get second query BUT get row 1 again 
    $pg->query('COMMIT');
    
    
    1. What did you expect to see?
    $row1 - first row of SELECT * FROM test
    $row2 - second row
    
    
    1. What did you see instead?
    $row1 & $row2 - is same
    
    
    1. What version of OpenSwoole are you using (show your php --ri openswoole)?
    4.11.1
    
    
    1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?
    PHP 8.1
    
    

    I used example from docs, but without transaction for SQL result is same.

    Even using prepare queries can possible reproduce this bug:

    $pg = new Swoole\Coroutine\PostgreSQL();
    $conn = $pg->connect("host=127.0.0.1;port=5432;dbname=test;user=postgres;password=***");
    $pg->prepare('selectOne', 'SELECT * FROM test');
    $result = $pg->execute('selectOne', []);
    $row1 = $pg->fetchAssoc($result); // Get First row
    // now make some INSERT or UPDATE query to ANY table
    $pg->prepare('update',"UPDATE test SET ....'");
    $pg->execute('update', []);
    // Try get second row
    $row2 = $pg->fetchAssoc($result);  // NOW row2 is same as row1
    

    I believe bug not only in fetchAssoc method and in others too.

    P.S. Yes I remember about second param in method. If I will use it - fetch will work fine. But PDO works right without parameterm so I expect what openswoole client will be works too)

  • Regarding php_swoole_library.h

    Regarding php_swoole_library.h

    Does Openswoole plan to indefinitely maintain it's PHP usersland library within ext-src/php_swoole_library.h? I believe it would be a better practice to reseparate the PHP code from the hard-coded library.

  • Can't install on Raspberry Pi 2 Model B

    Can't install on Raspberry Pi 2 Model B

    I tried to install openswoole on my Raspberry (Ubuntu 21.10) with the command:

    pecl install openswoole

    After a long time it breaks with the error:

    libtool: compile: cc -I. -I/tmp/pear/temp/openswoole -I/tmp/pear/temp/pear-build-root6fqqK8/openswoole-4.10.0/include -I/tmp/pear/temp/pear-build-root6fqqK8/openswoole-4.10.0/main -I/tmp/pear/temp/openswoole -I/usr/include/php/20200930 -I/usr/include/php/20200930/main -I/usr/include/php/20200930/TSRM -I/usr/include/php/20200930/Zend -I/usr/include/php/20200930/ext -I/usr/include/php/20200930/ext/date/lib -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/tmp/pear/temp/openswoole -I/tmp/pear/temp/openswoole/include -I/tmp/pear/temp/openswoole/ext-src -I/tmp/pear/temp/openswoole/thirdparty/hiredis -DHAVE_CONFIG_H -Wall -pthread -g -O2 -DENABLE_PHP_SWOOLE -c /tmp/pear/temp/openswoole/thirdparty/boost/asm/jump_arm_aapcs_elf_gas.S -fPIC -DPIC -o thirdparty/boost/asm/.libs/jump_arm_aapcs_elf_gas.o /tmp/pear/temp/openswoole/thirdparty/boost/asm/jump_arm_aapcs_elf_gas.S: Assembler messages: /tmp/pear/temp/openswoole/thirdparty/boost/asm/jump_arm_aapcs_elf_gas.S:60: Error: selected processor does not support vstmia sp,{d8-d15}' in ARM mode /tmp/pear/temp/openswoole/thirdparty/boost/asm/jump_arm_aapcs_elf_gas.S:77: Error: selected processor does not supportvldmia sp,{d8-d15}' in ARM mode make: *** [Makefile:463: thirdparty/boost/asm/jump_arm_aapcs_elf_gas.lo] Error 1 ERROR: `make' failed

    How can I fix this?

  • swoole table memory rezerve and usage problem.

    swoole table memory rezerve and usage problem.

    $table = new Swoole\Table(1024); $table->column('name', Swoole\Table::TYPE_STRING, 64); $table->column('id', Swoole\Table::TYPE_INT, 4); //1,2,4,8 $table->column('num', Swoole\Table::TYPE_FLOAT); $table->create();

    As the columns increase, the initial size of memory (1024) is automatically allocated at application startup.

    For example, for 10k clients, when we use this together with other values ​​to create 10k sessionids, the application gets an error because it tries to allocate too large memory space at startup.

    in fact, the table is empty, for example, it will store a maximum of 1000 session data instantly,

    For example, when php is in use, it falls into insufficient memory.

    The fact that the swoole initially auto-reserves this memory for this tablespace is exploiting the physical memory for other swoole scripts even though it is not being used.

    For high memory usage of the table, it would be nice to make some kind of compression on the swoole side, or to set the table to use disk file for storage.

C++14 asynchronous allocation aware futures (supporting then, exception handling, coroutines and connections)
C++14 asynchronous allocation aware futures (supporting then, exception handling, coroutines and connections)

Continuable is a C++14 library that provides full support for: lazy async continuation chaining based on callbacks (then) and expression templates, ca

Aug 5, 2022
C++20 coroutines-based cooperative multitasking library

?? Coop Coop is a C++20 coroutines-based library to support cooperative multitasking in the context of a multithreaded application. The syntax will be

Aug 11, 2022
Discrete-event simulation in C++20 using coroutines

SimCpp20 SimCpp20 is a discrete-event simulation framework for C++20. It is similar to SimPy and aims to be easy to set up and use. Processes are defi

Apr 29, 2022
Header-Only C++20 Coroutines library

CPP20Coroutines Header-Only C++20 Coroutines library This repository aims to demonstrate the capabilities of C++20 coroutines. generator Generates val

Mar 2, 2022
Cppcoro - A library of C++ coroutine abstractions for the coroutines TS

CppCoro - A coroutine library for C++ The 'cppcoro' library provides a large set of general-purpose primitives for making use of the coroutines TS pro

Aug 14, 2022
Coro - Single-header library facilities for C++2a Coroutines

coro This is a collection of single-header library facilities for C++2a Coroutines. coro/include/ co_future.h Provides co_future<T>, which is like std

Jul 20, 2022
Async++ concurrency framework for C++11

Async++ Async++ is a lightweight concurrency framework for C++11. The concept was inspired by the Microsoft PPL library and the N3428 C++ standard pro

Aug 15, 2022
Async GRPC with C++20 coroutine support

agrpc Build an elegant GRPC async interface with C++20 coroutine and libunifex (target for C++23 executor). Get started mkdir build && cd build conan

Aug 8, 2022
Open source re-creation of the copenheimer project.

openheimer Open source re-creation of the copenheimer project. Stage 1: Completed! - Make a extremely fast minecraft server scanner that does the hand

Jul 19, 2022
Open MPI main development repository

Open MPI The Open MPI Project is an open source Message Passing Interface (MPI) implementation that is developed and maintained by a consortium of aca

Aug 9, 2022
Kernel source code of EZ-FLASH OMEGA Definitive Edition

#EZ-FLASH Omega Definitive Edition Kernel How to build 1.We use devkitARM_r53, you can use the current version or newer. 2.Set the following environme

Jun 30, 2022
Aug 17, 2022
An implementation of Actor, Publish-Subscribe, and CSP models in one rather small C++ framework. With performance, quality, and stability proved by years in the production.
An implementation of Actor, Publish-Subscribe, and CSP models in one rather small C++ framework. With performance, quality, and stability proved by years in the production.

What is SObjectizer? What distinguishes SObjectizer? SObjectizer is not like TBB, taskflow or HPX Show me the code! HelloWorld example Ping-Pong examp

Aug 11, 2022
Simple and fast C library implementing a thread-safe API to manage hash-tables, linked lists, lock-free ring buffers and queues

libhl C library implementing a set of APIs to efficiently manage some basic data structures such as : hashtables, linked lists, queues, trees, ringbuf

Jul 30, 2022
Sqrt OS is a simulation of an OS scheduler and memory manager using different scheduling algorithms including Highest Priority First (non-preemptive), Shortest Remaining Time Next, and Round Robin
Sqrt OS is a simulation of an OS scheduler and memory manager using different scheduling algorithms including Highest Priority First (non-preemptive), Shortest Remaining Time Next, and Round Robin

A CPU scheduler determines an order for the execution of its scheduled processes; it decides which process will run according to a certain data structure that keeps track of the processes in the system and their status.

Jul 14, 2021
RocketOS is a Unix based OS that uses legacy BIOS and GRUB and is written in C17. It is being developed for educational purposes primarily, but it still is a serious project. It is currently in its infancy.

RocketOS What is RocketOS? RocketOS is a Unix based OS that uses legacy BIOS and GRUB and is written in C17. It is being developed for educational pur

Jul 17, 2022
Nov 24, 2021
OOX: Out-of-Order Executor library. Yet another approach to efficient and scalable tasking API and task scheduling.

OOX Out-of-Order Executor library. Yet another approach to efficient and scalable tasking API and task scheduling. Try it Requirements: Install cmake,

Aug 9, 2022