[DOC-CVS] [doc-en] master: Add swoole coroutine lock docs (#4776)

[email protected] (MARiA so cute via GitHub)
Newsgroups php.doc.cvs
Message-ID <[email protected]>
Author: MARiA so cute (NathanFreeman)
Committer: GitHub (web-flow)
Pusher: sy-records
Date: 2025-07-14T16:23:26+08:00

Commit: https://github.com/php/doc-en/commit/93e05c681bfdbfdd60cec941173c6fe8e8c95cf6
Raw diff: https://github.com/php/doc-en/commit/93e05c681bfdbfdd60cec941173c6fe8e8c95cf6.diff

Add swoole coroutine lock docs (#4776)

Co-authored-by: Luffy <[email protected]>

Changed paths:
  A  reference/swoole/swoole.coroutine.lock.xml
  A  reference/swoole/swoole/coroutine/lock/construct.xml
  A  reference/swoole/swoole/coroutine/lock/lock.xml
  A  reference/swoole/swoole/coroutine/lock/trylock.xml
  A  reference/swoole/swoole/coroutine/lock/unlock.xml
  M  reference/swoole/book.xml


Diff:

diff --git a/reference/swoole/book.xml b/reference/swoole/book.xml
index fe0f4feeeff3..6d7156aa16b6 100644
--- a/reference/swoole/book.xml
+++ b/reference/swoole/book.xml
@@ -34,6 +34,7 @@
  &reference.swoole.swoole.client;
  &reference.swoole.swoole.connection.iterator;
  &reference.swoole.swoole.coroutine;
+ &reference.swoole.swoole.coroutine.lock;
  <!-- &reference.swoole.swoole.coroutine.client; -->
  <!-- &reference.swoole.swoole.coroutine.http.client; -->
  <!-- &reference.swoole.swoole.coroutine.mysql; -->
diff --git a/reference/swoole/swoole.coroutine.lock.xml b/reference/swoole/swoole.coroutine.lock.xml
new file mode 100644
index 000000000000..d536aeca854f
--- /dev/null
+++ b/reference/swoole/swoole.coroutine.lock.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- $Revision$ -->
+
+<reference xml:id="class.swoole-coroutine-lock" role="class" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <title>The Swoole\Coroutine\Lock class</title>
+ <titleabbrev>Swoole\Coroutine\Lock</titleabbrev>
+
+ <partintro>
+
+<!-- {{{ Swoole\Coroutine\Lock intro -->
+  <section xml:id="swoole-coroutine-lock.intro">
+   &reftitle.intro;
+   <para>
+    Swoole 6.0.1 introduced a coroutine lock that supports inter-process and inter-thread sharing.
+    This lock is designed with non-blocking behavior and enables efficient coroutine synchronization
+    in multi-process and multi-thread environments.
+   </para>
+   <para>
+    When compiled with the <literal>--enable-iouring</literal> option and the Linux kernel supports
+    the <literal>io_uring futex</literal> feature, Swoole's coroutine lock implements synchronization
+    using <literal>io_uring futex</literal>. In this case, coroutines wait for lock wakeups using
+    an efficient queuing mechanism, significantly improving performance.
+   </para>
+   <para>
+    Without <literal>io_uring futex</literal>, the coroutine lock falls back to an exponential backoff
+    sleep mechanism, where the wait time increases by 2^n milliseconds (n being the number of failures)
+    after each failed attempt to acquire the lock. While this approach avoids busy waiting, it introduces
+    additional CPU scheduling overhead and latency.
+   </para>
+   <para>
+    The coroutine lock is reentrant, allowing the currently holding coroutine to safely perform
+    multiple lock operations.
+   </para>
+   <warning>
+    <para>
+     Do not create locks in callback functions like <literal>onReceive</literal>, as this will cause
+     continuous memory growth and lead to memory leaks.
+    </para>
+   </warning>
+   <warning>
+    <para>
+     Locking and unlocking must be performed in the same coroutine, otherwise it will break
+     static conditions.
+    </para>
+   </warning>
+  </section>
+<!-- }}} -->
+
+  <section xml:id="swoole-coroutine-lock.synopsis">
+   &reftitle.classsynopsis;
+
+<!-- {{{ Synopsis -->
+   <classsynopsis>
+    <ooclass><classname>Swoole\Coroutine\Lock</classname></ooclass>
+
+<!-- {{{ Class synopsis -->
+    <classsynopsisinfo>
+     <ooclass>
+      <classname>Swoole\Coroutine\Lock</classname>
+     </ooclass>
+    </classsynopsisinfo>
+<!-- }}} -->
+
+    <classsynopsisinfo role="comment">&Methods;</classsynopsisinfo>
+    <xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.swoole-coroutine-lock')/db:refentry/db:refsect1[@role='description']/descendant::db:methodsynopsis[not(@role='procedural')])" />
+   </classsynopsis>
+<!-- }}} -->
+
+  </section>
+
+  <section xml:id="swoole-coroutine-lock.examples">
+   &reftitle.examples;
+   <example xml:id="swoole-coroutine-lock.example.basic">
+    <title>Basic usage</title>
+    <programlisting role="php">
+<![CDATA[
+<?php
+use Swoole\Coroutine\Lock;
+use Swoole\Coroutine\WaitGroup;
+use function Swoole\Coroutine\go;
+use function Swoole\Coroutine\run;
+
+$lock = new Lock();
+$waitGroup = new WaitGroup();
+
+run(function() use ($lock, $waitGroup) {
+    go(function() use ($lock, $waitGroup) {
+        $waitGroup->add();
+        $lock->lock();
+        sleep(1);
+        $lock->unlock();
+        $waitGroup->done();
+    });
+
+    go(function() use ($lock, $waitGroup) {
+        $waitGroup->add();
+        $lock->lock(); // Wait for the holding coroutine to unlock
+        sleep(1);
+        $lock->unlock();
+        $waitGroup->done();
+    });
+
+    echo 'Lock does not block the process';
+    $waitGroup->wait();
+});
+]]>
+    </programlisting>
+   </example>
+  </section>
+
+ </partintro>
+
+ &reference.swoole.swoole.coroutine.entities.lock;
+</reference>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+indent-tabs-mode:nil
+sgml-parent-document:nil
+sgml-default-dtd-file:"~/.phpdoc/manual.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+vim600: syn=xml fen fdm=syntax fdl=2 si
+vim: et tw=78 syn=sgml
+vi: ts=1 sw=1
+-->
diff --git a/reference/swoole/swoole/coroutine/lock/construct.xml b/reference/swoole/swoole/coroutine/lock/construct.xml
new file mode 100644
index 000000000000..384163b7afc8
--- /dev/null
+++ b/reference/swoole/swoole/coroutine/lock/construct.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- $Revision$ -->
+
+<refentry xml:id="swoole-coroutine-lock.construct" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <refnamediv>
+  <refname>Swoole\Coroutine\Lock::__construct</refname>
+  <refpurpose>Construct a new coroutine lock</refpurpose>
+ </refnamediv>
+
+ <refsect1 role="description">
+  &reftitle.description;
+  <methodsynopsis>
+   <modifier>public</modifier> <type>void</type><methodname>Swoole\Coroutine\Lock::__construct</methodname>
+   <void />
+  </methodsynopsis>
+  <para>
+   Create a new coroutine lock instance.
+  </para>
+ </refsect1>
+
+ <refsect1 role="parameters">
+  &reftitle.parameters;
+  &no.function.parameters;
+ </refsect1>
+
+ <refsect1 role="returnvalues">
+  &reftitle.returnvalues;
+  <para>
+   &return.void;
+  </para>
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+indent-tabs-mode:nil
+sgml-parent-document:nil
+sgml-default-dtd-file:"~/.phpdoc/manual.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+vim600: syn=xml fen fdm=syntax fdl=2 si
+vim: et tw=78 syn=sgml
+vi: ts=1 sw=1
+-->
diff --git a/reference/swoole/swoole/coroutine/lock/lock.xml b/reference/swoole/swoole/coroutine/lock/lock.xml
new file mode 100644
index 000000000000..41421d671529
--- /dev/null
+++ b/reference/swoole/swoole/coroutine/lock/lock.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- $Revision$ -->
+
+<refentry xml:id="swoole-coroutine-lock.lock" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <refnamediv>
+  <refname>Swoole\Coroutine\Lock::lock</refname>
+  <refpurpose>Acquire the lock, blocking if necessary</refpurpose>
+ </refnamediv>
+
+ <refsect1 role="description">
+  &reftitle.description;
+  <methodsynopsis>
+   <modifier>public</modifier> <type>bool</type><methodname>Swoole\Coroutine\Lock::lock</methodname>
+   <void />
+  </methodsynopsis>
+  <para>
+   When executing the lock operation, if the lock is already held by another coroutine,
+   the current coroutine will actively yield CPU control and enter a suspended state.
+   When the coroutine holding the lock calls unlock(), the waiting coroutine will be
+   awakened and try to acquire the lock again.
+  </para>
+ </refsect1>
+
+ <refsect1 role="parameters">
+  &reftitle.parameters;
+  &no.function.parameters;
+ </refsect1>
+
+ <refsect1 role="returnvalues">
+  &reftitle.returnvalues;
+  <para>
+   Returns <literal>true</literal> if the lock was acquired successfully,
+   <literal>false</literal> otherwise.
+  </para>
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+indent-tabs-mode:nil
+sgml-parent-document:nil
+sgml-default-dtd-file:"~/.phpdoc/manual.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+vim600: syn=xml fen fdm=syntax fdl=2 si
+vim: et tw=78 syn=sgml
+vi: ts=1 sw=1
+-->
diff --git a/reference/swoole/swoole/coroutine/lock/trylock.xml b/reference/swoole/swoole/coroutine/lock/trylock.xml
new file mode 100644
index 000000000000..19a75d354e8a
--- /dev/null
+++ b/reference/swoole/swoole/coroutine/lock/trylock.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- $Revision$ -->
+
+<refentry xml:id="swoole-coroutine-lock.trylock" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <refnamediv>
+  <refname>Swoole\Coroutine\Lock::trylock</refname>
+  <refpurpose>Attempt to acquire the lock without blocking</refpurpose>
+ </refnamediv>
+
+ <refsect1 role="description">
+  &reftitle.description;
+  <methodsynopsis>
+   <modifier>public</modifier> <type>bool</type><methodname>Swoole\Coroutine\Lock::trylock</methodname>
+   <void />
+  </methodsynopsis>
+  <para>
+   When calling the lock operation, if the lock is already held by another coroutine,
+   the function will immediately return false without suspending the current coroutine
+   or yielding CPU control. This non-blocking design allows the caller to flexibly
+   handle contention situations, such as retrying, giving up, or executing other logic.
+  </para>
+ </refsect1>
+
+ <refsect1 role="parameters">
+  &reftitle.parameters;
+  &no.function.parameters;
+ </refsect1>
+
+ <refsect1 role="returnvalues">
+  &reftitle.returnvalues;
+  <para>
+   Returns <literal>true</literal> if the lock was acquired successfully,
+   <literal>false</literal> if the lock is not available.
+  </para>
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+indent-tabs-mode:nil
+sgml-parent-document:nil
+sgml-default-dtd-file:"~/.phpdoc/manual.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+vim600: syn=xml fen fdm=syntax fdl=2 si
+vim: et tw=78 syn=sgml
+vi: ts=1 sw=1
+-->
diff --git a/reference/swoole/swoole/coroutine/lock/unlock.xml b/reference/swoole/swoole/coroutine/lock/unlock.xml
new file mode 100644
index 000000000000..d9d69d377aff
--- /dev/null
+++ b/reference/swoole/swoole/coroutine/lock/unlock.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- $Revision$ -->
+
+<refentry xml:id="swoole-coroutine-lock.unlock" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <refnamediv>
+  <refname>Swoole\Coroutine\Lock::unlock</refname>
+  <refpurpose>Release the lock</refpurpose>
+ </refnamediv>
+
+ <refsect1 role="description">
+  &reftitle.description;
+  <methodsynopsis>
+   <modifier>public</modifier> <type>bool</type><methodname>Swoole\Coroutine\Lock::unlock</methodname>
+   <void />
+  </methodsynopsis>
+ </refsect1>
+
+ <refsect1 role="behavior">
+  <title>Unlock Behavior</title>
+  <orderedlist>
+   <listitem>
+    <para>
+     <emphasis>With io_uring futex:</emphasis> the system will precisely wake up one coroutine in the waiting queue.
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     <emphasis>Without io_uring futex:</emphasis> waiting coroutines need to wait for their backoff time to end
+     and compete to reacquire the lock.
+    </para>
+   </listitem>
+  </orderedlist>
+ </refsect1>
+
+ <refsect1 role="parameters">
+  &reftitle.parameters;
+  &no.function.parameters;
+ </refsect1>
+
+ <refsect1 role="returnvalues">
+  &reftitle.returnvalues;
+  <para>
+   Returns <literal>true</literal> if the lock was released successfully,
+   <literal>false</literal> otherwise.
+  </para>
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+indent-tabs-mode:nil
+sgml-parent-document:nil
+sgml-default-dtd-file:"~/.phpdoc/manual.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+vim600: syn=xml fen fdm=syntax fdl=2 si
+vim: et tw=78 syn=sgml
+vi: ts=1 sw=1
+-->
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.