• Stars
    star
    829
  • Rank 55,018 (Top 2 %)
  • Language
    C++
  • License
    MIT License
  • Created almost 11 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

cross-platform coroutine library in c++

libcopp

Cross-platform coroutine library in C++ .

https://img.shields.io/github/forks/owent/libcopp?style=social

https://img.shields.io/github/stars/owent/libcopp?style=social

Release Code size Repo size CI build status Coveralls coverage Language grade: C/C++ Forks Stars

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; into T when using cotask::task<T>.
  • Rename stack_allocator_t to stack_allocator_type in T when using cotask::task<T>.
  • Rename coroutine_t to coroutine_type in T when using cotask::task<T>.
  • Rename libcopp::util::* to copp::util::.
  • We are not allowed to use libcopp::util::intrusive_ptr<cotask::impl::task_impl> now, please use cotask::task<T>::ptr_type instead.

UPGRADE FROM 1.2.X to 1.3.X-1.4.X

  • Rename cotask::task::await into cotask::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 (Boost.Test supported)

Unix

  • [required] ar, as, ld (binutils) or llvm
  • [optional] if using gtest , pthread is required.

Windows

  • [required] masm (in MSVC)
  • [optional] if using gtest, pthread is required.

Install with vcpkg

  1. Clone and setup vcpkg (See more detail on https://github.com/Microsoft/vcpkg)
    git clone https://github.com/Microsoft/vcpkg.git
    cd vcpkg
    PS> bootstrap-vcpkg.bootstrap
    Linux:~/$ ./bootstrap-vcpkg.sh
  2. Install libcopp
    PS> .\vcpkg install libcopp [--triplet x64-windows-static/x64-windows/x64-windows-static-md and etc...]
    Linux:~/$ ./vcpkg install libcopp
  3. See :ref:`using with cmake <usage-using with-cmake>` for cmake below.

Custom Build

  1. Clone and make a build directory
    git clone --single-branch --depth=1 -b master https://github.com/owent/libcopp.git
    mkdir libcopp/build && cd libcopp/build
  2. Run cmake command
    # cmake <libcopp dir> [options...]
    cmake .. -DPROJECT_ENABLE_UNITTEST=YES -DPROJECT_ENABLE_SAMPLE=YES
  3. Make libcopp
    cmake --build . --config RelWithDebInfo # or make [options] when using Makefile
  4. Run test/sample/benchmark [optional]
    # 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
  5. Install [optional]
    cmake --build . --config RelWithDebInfo --target install # or make install when using Makefile
  6. Then just include and link libcopp.*/libcotask.*, or see :ref:`using with cmake <usage-using with-cmake>` 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

  1. Using set(Libcopp_ROOT <where to find libcopp/INSTALL_PREFIX>)
  2. Just using find_package(Libcopp) to use libcopp module.
  3. 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_contextcopp::coroutine_context_fiber and cotask::task :

  1. Using coroutine context
  2. Using coroutine task
  3. Using coroutine task manager
  4. Using stack pool
  5. Using task::then or task::await_task
  6. Using copp::callable_promise of c++20 coroutine
  7. Using copp::generator_future for c++20 coroutine
  8. Custom error (timeout for example) when using c++20 coroutine
  9. Let c++20 coroutine work with cotask::task
  10. Using Windows fiber and SetUnhandledExceptionFilter on Windows with cotask::task

All sample codes can be found on :ref:`EXAMPLES <examples_doc_anchor>` 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, CCCXXAR and etc.

CONSTRIBUTORS

THANKS TO

More Repositories

1

xresloader

跨平台Excel导表工具(Excel=>protobuf/msgpack/lua/javascript/json/xml)
Java
269
star
2

bash-shell

OWenT's Utils -- Bash&Shell branch
Shell
107
star
3

atframe_utils

cxx utils code
C++
79
star
4

wxwork_robotd

企业微信机器人接入服务
Rust
61
star
5

xresconv-gui

批量转表工具的GUI版本,依赖electron
JavaScript
58
star
6

libatbus

用于搭建高性能、全异步、树形结构的BUS消息系统的跨平台框架库。项目迁移到 https://github.com/atframework/libatbus
C++
51
star
7

libiniloader

一个简单而的ini配置读取库(带扩展语法)
C++
38
star
8

WP-Code-Highlight.js

highligh.js plugin for wordpress
CSS
26
star
9

hiredis-happ

Redis high available solution for c++
C++
26
star
10

cmake-toolset

CMake
25
star
11

docker-setup

My docker setup scripts
Shell
25
star
12

libatapp

server app framework based on libatbus
C++
21
star
13

libsimulator

游戏服务器-客户端模拟框架,可用于模拟客户端发包,接入Lua脚本,开发自测,压测等
C++
17
star
14

xresconv-cli

批量转表工具的CLI版本,依赖python。(python2和python3均支持)
Python
10
star
15

devops_webtools

开发运维工具-用于内网开发环境服务器发布和管理
JavaScript
8
star
16

devops_mirrors

用于同步一些开源镜像供内网使用
TypeScript
7
star
17

OWenT-s-Utils

个人代码记录册,已迁移到 https://github.com/owent-utils
7
star
18

flying_chess

flying chess written with cocos2d-x 3.X
C++
6
star
19

Programmer-s-Almanac

程序猿老黄历
JavaScript
5
star
20

ddns-cli

Rust
4
star
21

client-debuger

客户端集成开发工具
C++
3
star
22

xres-code-generator

Mako
3
star
23

SimpleMetro

Just a simple metro ui library in javascript
JavaScript
2
star
24

CmdOption

命令函数绑定器
C++
1
star
25

hugo-theme-distinctionpp

Distinctionpp theme for hugo.
HTML
1
star