libcopp
Cross-platform coroutine library in C++ .
CI Job Matrix
Target System Toolchain Note
Linux GCC Static linking
Linux GCC Dynamic linking
Linux GCC-latest
Linux GCC-latest No Exception
Linux GCC-latest Thread Unsafe
Linux GCC 4.8 Legacy
Linux Clang-latest With libc++
MinGW64 GCC Dynamic linking
Windows Visual Studio 2019 Static linking
Windows Visual Studio 2019 Dynamic linking
Windows Visual Studio 2017 Legacy,Static linking
macOS AppleClang With libc++
LICENSE
License under the MIT
LICENSE
Document
Documents can be found at https://libcopp.atframe.work , API
references canbe found at https://libcopp.atframe.work/doxygen/html/
.(Generated by sphinx and doxygen with
docs/sphinx and
docs/libcopp.doxyfile.in).
UPGRADE FROM 1.3.X-1.4.X to 2.X
- Add
using value_type = int;
intoT
when usingcotask::task<T>
. - Rename
stack_allocator_t
tostack_allocator_type
inT
when
usingcotask::task<T>
. - Rename
coroutine_t
tocoroutine_type
inT
when using
cotask::task<T>
. - Rename
libcopp::util::*
tocopp::util::
. - We are not allowed to use
libcopp::util::intrusive_ptr<cotask::impl::task_impl>
now, please
usecotask::task<T>::ptr_type
instead.
UPGRADE FROM 1.2.X to 1.3.X-1.4.X
- Rename
cotask::task::await
intocotask::task::await_task
- Replace
cotask::task<TCO_MACRO, TTASK_MACRO>
with
cotask::task<TCO_MACRO>
, we don't allow to custom id allocator
now. - Replace
cotask::core::standard_int_id_allocator<uint64_t>
with
copp::util::uint64_id_allocator
, we don't allow to custom id
allocator now. - Require gcc 4.8+, MSVC 15+(Visual Studio 2017)>)
- Require cmake 3.12.0 or upper
INSTALL
| libcopp use cmake to generate makefile and
switch build tools.
Prerequisites
- [required] GCC or Clang or MSVC or clang-cl support ISO C++ 11
and upper - [required] cmake 3.16.0 and upper
- [optional] gtest 1.6.0
and upper (Better unit test supported) - [optional]
[Boost.Test]((http://www.boost.org/doc/libs/release/libs/test)
(Boost.Test supported)
Unix
Windows
- [required] masm (in MSVC)
- [optional] if using
gtest, pthread is required.
Install with vcpkg
Clone and setup [vcpkg](https://github.com/Microsoft/vcpkg) (See more detail on <https://github.com/Microsoft/vcpkg>)
: ``` shell
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
PS> bootstrap-vcpkg.bootstrap
Linux:~/$ ./bootstrap-vcpkg.sh
```
Install libcopp
: ``` shell
PS> .\vcpkg install libcopp [--triplet x64-windows-static/x64-windows/x64-windows-static-md and etc...]
Linux:~/$ ./vcpkg install libcopp
```
- See
using with cmake <usage-using with-cmake>
{.interpreted-text
role="ref"} for cmake below.
Custom Build
Clone and make a build directory
: ``` shell
git clone --single-branch --depth=1 -b master https://github.com/owent/libcopp.git
mkdir libcopp/build && cd libcopp/build
```
Run cmake command
: ``` shell
# cmake <libcopp dir> [options...]
cmake .. -DPROJECT_ENABLE_UNITTEST=YES -DPROJECT_ENABLE_SAMPLE=YES
```
Make libcopp
: ``` shell
cmake --build . --config RelWithDebInfo # or make [options] when using Makefile
```
Run `test/sample/benchmark` *\[optional\]*
: ``` shell
# Run test => Required: PROJECT_ENABLE_UNITTEST=YES
ctest -VV . -C RelWithDebInfo -L libcopp.unit_test
# Run sample => Required: PROJECT_ENABLE_SAMPLE=YES
ctest -VV . -C RelWithDebInfo -L libcopp.sample
# Run benchmark => Required: PROJECT_ENABLE_SAMPLE=YES
ctest -VV . -C RelWithDebInfo -L libcopp.benchmark
```
Install *\[optional\]*
: ``` shell
cmake --build . --config RelWithDebInfo --target install # or make install when using Makefile
```
- Then just include and link
libcopp.*/libcotask.*
, or see
using with cmake <usage-using with-cmake>
{.interpreted-text
role="ref"} for cmake below.
CMake Options
Options can be cmake options. such as set compile toolchains, source
directory or options of libcopp that control build actions. libcopp
options are listed below:
Option Description
BUILD_SHARED_LIBS=YES|NO [default=NO] Build dynamic library.
LIBCOPP_ENABLE_SEGMENTED_STACKS=YES|NO [default=NO] Enable split stack supported
context.(it's only availabe in linux and gcc 4.7.0 or
upper)
LIBCOPP_ENABLE_VALGRIND=YES|NO [default=YES] Enable valgrind supported context.
PROJECT_ENABLE_UNITTEST=YES|NO [default=NO] Build unit test.
PROJECT_ENABLE_SAMPLE=YES|NO [default=NO] Build samples.
LIBCOPP_LOCK_DISABLE_THIS_MT=YES|NO [default=NO] Disable multi-thread support for
copp::this_coroutine
and cotask::this_task
.
LIBCOPP_DISABLE_ATOMIC_LOCK=YES|NO [default=NO] Disable multi-thread support.
LIBCOTASK_ENABLE=YES|NO [default=YES] Enable build libcotask.
LIBCOPP_FCONTEXT_USE_TSX=YES|NO [default=YES] Enable Intel Transactional
Synchronisation Extensions
(TSX).
LIBCOPP_MACRO_TLS_STACK_PROTECTOR=YES|NO [default=NO] Users need set
LIBCOPP_MACRO_TLS_STACK_PROTECTOR=ON when compiling
with -fstack-protector
. Because it changes the
default context switching logic.
GTEST_ROOT=[path] set gtest library install prefix path
BOOST_ROOT=[path] set Boost.Test library install prefix path
USAGE
Using with cmake {#usage-using with-cmake}
- Using
set(Libcopp_ROOT <where to find libcopp/INSTALL_PREFIX>)
- Just using
find_package(Libcopp)
to use libcopp module. - Example:(we assume the target name is stored in
${CUSTOM_TARGET_NAME}
)
find_package(Libcopp CONFIG REQUIRED)
target_link_libraries(${CUSTOM_TARGET_NAME} libcopp::cotask)
# Or just using copp by target_link_libraries(${CUSTOM_TARGET_NAME} libcopp::copp)
If using MSVC and vcpkg, CRT must match the triplet of vcpkg, these
codes below may be helpful:
if (MSVC AND VCPKG_TOOLCHAIN)
if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "")
endif()
if (VCPKG_TARGET_TRIPLET MATCHES "^.*windows-static$")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING "")
else ()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL" CACHE STRING "")
endif ()
endif ()
See more detail on
https://github.com/Microsoft/vcpkg/tree/master/ports/libcopp .
Directly use headers and libraries
Just include headers and linking library file of your platform to use
libcopp.
LIBCOPP_PREFIX=<WHERE TO INSTALL libcopp>
# Example command for build sample with gcc 4.9 or upper on Linux
for source in sample_readme_*.cpp; do
g++ -std=c++14 -O2 -g -ggdb -Wall -Werror -fPIC -rdynamic -fdiagnostics-color=auto -Wno-unused-local-typedefs \
-I$LIBCOPP_PREFIX/include -L$LIBCOPP_PREFIX/lib64 -lcopp -lcotask $source -o $source.exe;
done
# Example command for build sample with clang 3.9 or upper and libc++ on Linux
for source in sample_readme_*.cpp; do
clang++ -std=c++17 -stdlib=libc++ -O2 -g -ggdb -Wall -Werror -fPIC -rdynamic \
-I$LIBCOPP_PREFIX/include -L$LIBCOPP_PREFIX/lib64 -lcopp -lcotask -lc++ -lc++abi \
$source -o $source.exe;
done
# AppleClang on macOS just like those scripts upper.
# If you are using MinGW on Windows, it's better to add -static-libstdc++ -static-libgcc to
# use static linking and other scripts are just like those on Linux.
# Example command for build sample with MSVC 1914 or upper on Windows & powershell(Debug Mode /MDd)
foreach ($source in Get-ChildItem -File -Name .\sample_readme_*.cpp) {
cl /nologo /MP /W4 /wd"4100" /wd"4125" /EHsc /std:c++17 /Zc:__cplusplus /O2 /MDd /I$LIBCOPP_PREFIX/include $LIBCOPP_PREFIX/lib64/copp.lib $LIBCOPP_PREFIX/lib64/cotask.lib $source
}
Get Start & Example
There serveral samples to use copp::coroutine_context
、
copp::coroutine_context_fiber
and cotask::task
:
- Using coroutine context
- Using coroutine task
- Using coroutine task manager
- Using stack pool
- Using
task::then
ortask::await_task
- Using
copp::callable_promise
of c++20 coroutine - Using
copp::generator_future
for c++20 coroutine - Custom error (timeout for example) when using c++20 coroutine
- Let c++20 coroutine work with
cotask::task
- Using Windows fiber and
SetUnhandledExceptionFilter
on Windows
withcotask::task
All sample codes can be found on
EXAMPLES <examples_doc_anchor>
{.interpreted-text role="ref"} and
sample .
NOTICE
Split stack support: if in Linux and user gcc 4.7.0 or upper, add
-DLIBCOPP_ENABLE_SEGMENTED_STACKS=YES
to use split stack supported
context.
It's recommanded to use stack pool instead of gcc splited stack.
BENCHMARK
Please see CI output for latest benchmark report. Click to visit Github
Actions .
FAQ
Q: How to enable c++20 coroutine
| ANS: Add /std:c++latest /await
for MSVC 1932 and below or
-std=c++20 -fcoroutines-ts -stdlib=libc++
for clang 13 and below or
-std=c++20 -fcoroutines
for gcc 10.
If you can just use -std=c++20 -stdlib=libc++
clang 14 or above,
-astd=c++20
for gcc 11 or above, and /std:c++latest
for MSVC 1932 or
above.
Q: Will libcopp handle exception?
| ANS: When using c++11 or above, libcopp will catch all unhandled
exception and rethrow it after coroutine resumed.
Q: Why SetUnhandledExceptionFilter
can not catch the unhandled
exception in a coroutine?
| ANS: SetUnhandledExceptionFilter
only works with Windows Fiber,
please see
sample/sample_readme_11.cpp
for details.
FEEDBACK
If you has any question, please create a issue and provide the
information of your environments. For example:
- OS: Windows 10 Pro 19041 (This can be see after running
``msinfo32``) / Manjaro(Arch) Linux Linux 5.4.39-1-MANJARO - Compiler: Visual Studio 2019 C++ 16.5.5 with VS 2019 C++ v14.25
or MSVC 1925/ gcc 9.3.0 - CMake Commands:
cmake .. -G "Visual Studio 16 2019" -A x64 -DLIBCOPP_FCONTEXT_USE_TSX=ON -DPROJECT_ENABLE_UNITTEST=ON -DPROJECT_ENABLE_SAMPLE=ON-DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=%cd%/install-prefix
/
cmake .. -G Ninja -DLIBCOPP_FCONTEXT_USE_TSX=ON -DPROJECT_ENABLE_UNITTEST=ON -DPROJECT_ENABLE_SAMPLE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/opt/libcopp
- Compile Commands:
cmake --build . -j
- Related Environment Variables: Please provide all the
environment variables which will change the cmake toolchain,CC
、
CXX
、AR
and etc.