├── .gitignore ├── LICENSE.txt ├── Makefile ├── README.md ├── README_cn.md ├── benchmark ├── libco │ ├── Makefile │ └── libco_server.cpp ├── libgo │ ├── Makefile │ └── libgo_server.cpp ├── libmill │ ├── Makefile │ └── libmill_server.c ├── patch.cpp ├── patch.h └── tbox │ ├── Makefile │ └── tbox_server.c ├── c ├── CMakeLists.txt ├── Makefile ├── fiber_vc2012.sln ├── fiber_vc2013.sln ├── fiber_vc2015.sln ├── include │ └── fiber │ │ ├── fiber_base.h │ │ ├── fiber_channel.h │ │ ├── fiber_cond.h │ │ ├── fiber_define.h │ │ ├── fiber_event.h │ │ ├── fiber_hook.h │ │ ├── fiber_lock.h │ │ ├── fiber_mutex.h │ │ ├── fiber_sem.h │ │ ├── lib_fiber.h │ │ └── libfiber.h ├── libfiber.rc ├── libfiber_vc2012.vcxproj ├── libfiber_vc2012.vcxproj.filters ├── libfiber_vc2013.vcxproj ├── libfiber_vc2013.vcxproj.filters ├── libfiber_vc2019.vcxproj ├── libfiber_vc2019.vcxproj.filters ├── resource.h ├── src │ ├── common.h │ ├── common │ │ ├── argv.c │ │ ├── argv.h │ │ ├── array.c │ │ ├── array.h │ │ ├── atomic.c │ │ ├── atomic.h │ │ ├── avl.c │ │ ├── avl.h │ │ ├── avl_impl.h │ │ ├── close_on_exec.c │ │ ├── doze.c │ │ ├── fifo.c │ │ ├── fifo.h │ │ ├── gettimeofday.c │ │ ├── gettimeofday.h │ │ ├── htable.c │ │ ├── htable.h │ │ ├── init.c │ │ ├── init.h │ │ ├── iostuff.h │ │ ├── iterator.h │ │ ├── mbox.c │ │ ├── mbox.h │ │ ├── memory.c │ │ ├── memory.h │ │ ├── msg.c │ │ ├── msg.h │ │ ├── non_blocking.c │ │ ├── open_limit.c │ │ ├── pthread_patch.c │ │ ├── pthread_patch.h │ │ ├── queue.c │ │ ├── queue.h │ │ ├── read_wait.c │ │ ├── ring.c │ │ ├── ring.h │ │ ├── sane_socket.c │ │ ├── sane_socket.h │ │ ├── socketpair.c │ │ ├── strops.c │ │ ├── strops.h │ │ ├── tcp_nodelay.c │ │ ├── timer_cache.c │ │ ├── timer_cache.h │ │ ├── ypipe.c │ │ ├── ypipe.h │ │ ├── yqueue.c │ │ └── yqueue.h │ ├── define.h │ ├── dns │ │ ├── resolver.c │ │ ├── resolver.h │ │ ├── rfc1035.c │ │ ├── rfc1035.h │ │ ├── sane_inet.c │ │ ├── sane_inet.h │ │ ├── valid_hostname.c │ │ └── valid_hostname.h │ ├── event.c │ ├── event.h │ ├── event │ │ ├── event_epoll.c │ │ ├── event_epoll.h │ │ ├── event_io_uring.c │ │ ├── event_io_uring.h │ │ ├── event_iocp.c │ │ ├── event_iocp.h │ │ ├── event_kqueue.c │ │ ├── event_kqueue.h │ │ ├── event_poll.c │ │ ├── event_poll.h │ │ ├── event_select.c │ │ ├── event_select.h │ │ ├── event_wmsg.c │ │ └── event_wmsg.h │ ├── fbase_event.c │ ├── fiber.c │ ├── fiber.h │ ├── fiber │ │ ├── boost │ │ │ ├── jump_arm64_aapcs_elf_gas.S │ │ │ ├── jump_arm64_aapcs_macho_gas.S │ │ │ ├── jump_arm_aapcs_elf_gas.S │ │ │ ├── jump_arm_aapcs_macho_gas.S │ │ │ ├── jump_arm_aapcs_pe_armasm.asm │ │ │ ├── jump_combined_sysv_macho_gas.S │ │ │ ├── jump_gas.S │ │ │ ├── jump_i386_ms_pe_gas.asm │ │ │ ├── jump_i386_ms_pe_masm.asm │ │ │ ├── jump_i386_sysv_elf_gas.S │ │ │ ├── jump_i386_sysv_macho_gas.S │ │ │ ├── jump_i386_x86_64_sysv_macho_gas.S │ │ │ ├── jump_mips32_o32_elf_gas.S │ │ │ ├── jump_mips64_n64_elf_gas.S │ │ │ ├── jump_ppc32_ppc64_sysv_macho_gas.S │ │ │ ├── jump_ppc32_sysv_elf_gas.S │ │ │ ├── jump_ppc32_sysv_macho_gas.S │ │ │ ├── jump_ppc32_sysv_xcoff_gas.S │ │ │ ├── jump_ppc64_sysv_elf_gas.S │ │ │ ├── jump_ppc64_sysv_macho_gas.S │ │ │ ├── jump_ppc64_sysv_xcoff_gas.S │ │ │ ├── jump_riscv64_sysv_elf_gas.S │ │ │ ├── jump_s390x_sysv_elf_gas.S │ │ │ ├── jump_x86_64_ms_pe_gas.asm │ │ │ ├── jump_x86_64_ms_pe_masm.asm │ │ │ ├── jump_x86_64_sysv_elf_gas.S │ │ │ ├── jump_x86_64_sysv_macho_gas.S │ │ │ ├── make_arm64_aapcs_elf_gas.S │ │ │ ├── make_arm64_aapcs_macho_gas.S │ │ │ ├── make_arm_aapcs_elf_gas.S │ │ │ ├── make_arm_aapcs_macho_gas.S │ │ │ ├── make_arm_aapcs_pe_armasm.asm │ │ │ ├── make_combined_sysv_macho_gas.S │ │ │ ├── make_gas.S │ │ │ ├── make_i386_ms_pe_gas.asm │ │ │ ├── make_i386_ms_pe_masm.asm │ │ │ ├── make_i386_sysv_elf_gas.S │ │ │ ├── make_i386_sysv_macho_gas.S │ │ │ ├── make_i386_x86_64_sysv_macho_gas.S │ │ │ ├── make_mips32_o32_elf_gas.S │ │ │ ├── make_mips64_n64_elf_gas.S │ │ │ ├── make_ppc32_ppc64_sysv_macho_gas.S │ │ │ ├── make_ppc32_sysv_elf_gas.S │ │ │ ├── make_ppc32_sysv_macho_gas.S │ │ │ ├── make_ppc32_sysv_xcoff_gas.S │ │ │ ├── make_ppc64_sysv_elf_gas.S │ │ │ ├── make_ppc64_sysv_macho_gas.S │ │ │ ├── make_ppc64_sysv_xcoff_gas.S │ │ │ ├── make_riscv64_sysv_elf_gas.S │ │ │ ├── make_s390x_sysv_elf_gas.S │ │ │ ├── make_x86_64_ms_pe_gas.asm │ │ │ ├── make_x86_64_ms_pe_masm.asm │ │ │ ├── make_x86_64_sysv_elf_gas.S │ │ │ ├── make_x86_64_sysv_macho_gas.S │ │ │ ├── ontop_arm64_aapcs_elf_gas.S │ │ │ ├── ontop_arm64_aapcs_macho_gas.S │ │ │ ├── ontop_arm_aapcs_elf_gas.S │ │ │ ├── ontop_arm_aapcs_macho_gas.S │ │ │ ├── ontop_arm_aapcs_pe_armasm.asm │ │ │ ├── ontop_combined_sysv_macho_gas.S │ │ │ ├── ontop_i386_ms_pe_gas.asm │ │ │ ├── ontop_i386_ms_pe_masm.asm │ │ │ ├── ontop_i386_sysv_elf_gas.S │ │ │ ├── ontop_i386_sysv_macho_gas.S │ │ │ ├── ontop_i386_x86_64_sysv_macho_gas.S │ │ │ ├── ontop_mips32_o32_elf_gas.S │ │ │ ├── ontop_mips64_n64_elf_gas.S │ │ │ ├── ontop_ppc32_ppc64_sysv_macho_gas.S │ │ │ ├── ontop_ppc32_sysv_elf_gas.S │ │ │ ├── ontop_ppc32_sysv_macho_gas.S │ │ │ ├── ontop_ppc32_sysv_xcoff_gas.S │ │ │ ├── ontop_ppc64_sysv_elf_gas.S │ │ │ ├── ontop_ppc64_sysv_macho_gas.S │ │ │ ├── ontop_ppc64_sysv_xcoff_gas.S │ │ │ ├── ontop_riscv64_sysv_elf_gas.S │ │ │ ├── ontop_s390x_sysv_elf_gas.S │ │ │ ├── ontop_x86_64_ms_pe_gas.asm │ │ │ ├── ontop_x86_64_ms_pe_masm.asm │ │ │ ├── ontop_x86_64_sysv_elf_gas.S │ │ │ └── ontop_x86_64_sysv_macho_gas.S │ │ ├── boost_jmp.h │ │ ├── exp │ │ │ ├── setjmp.S │ │ │ ├── setjmp_aarch64.S │ │ │ ├── setjmp_arm.S │ │ │ ├── setjmp_i386.S │ │ │ ├── setjmp_mips.S │ │ │ ├── setjmp_ppc.S │ │ │ ├── setjmp_rv64g.S │ │ │ ├── setjmp_s390x.S │ │ │ ├── setjmp_sparc64.S │ │ │ └── setjmp_x86_64.S │ │ ├── exp_jmp.h │ │ ├── fiber_unix.c │ │ ├── fiber_win.c │ │ └── x86_jmp.h │ ├── fiber_io.c │ ├── file_event.c │ ├── hook │ │ ├── epoll.c │ │ ├── fcntl.c │ │ ├── fiber_read.c │ │ ├── fiber_write.c │ │ ├── file.c │ │ ├── getaddrinfo.c │ │ ├── gethostbyname.c │ │ ├── hook.c │ │ ├── hook.h │ │ ├── io.c │ │ ├── io.h │ │ ├── poll.c │ │ ├── select.c │ │ └── socket.c │ ├── stdafx.c │ ├── stdafx.h │ └── sync │ │ ├── channel.c │ │ ├── fiber_cond.c │ │ ├── fiber_event.c │ │ ├── fiber_lock.c │ │ ├── fiber_mutex.c │ │ ├── fiber_sem.c │ │ ├── sync_timer.c │ │ ├── sync_timer.h │ │ ├── sync_type.c │ │ ├── sync_type.h │ │ ├── sync_waiter.c │ │ └── sync_waiter.h └── xmake.lua ├── changes.txt ├── cpp ├── CMakeLists.txt ├── Makefile ├── include │ └── fiber │ │ ├── channel.hpp │ │ ├── fiber.hpp │ │ ├── fiber_cond.hpp │ │ ├── fiber_cpp_define.hpp │ │ ├── fiber_event.hpp │ │ ├── fiber_lock.hpp │ │ ├── fiber_mutex.hpp │ │ ├── fiber_mutex_stat.hpp │ │ ├── fiber_pool.hpp │ │ ├── fiber_sem.hpp │ │ ├── fiber_tbox.hpp │ │ ├── fiber_tbox2.hpp │ │ ├── go_fiber.hpp │ │ ├── libfiber.hpp │ │ └── wait_group.hpp ├── libfiber_cpp.rc ├── libfiber_cpp_vc2012.vcxproj ├── libfiber_cpp_vc2012.vcxproj.filters ├── libfiber_cpp_vc2013.vcxproj ├── libfiber_cpp_vc2013.vcxproj.filters ├── libfiber_cpp_vc2019.vcxproj ├── libfiber_cpp_vc2019.vcxproj.filters ├── resource.h ├── src │ ├── channel.cpp │ ├── detours │ │ ├── creatwth.cpp │ │ ├── deps │ │ │ └── uimports.cpp │ │ ├── detours.cpp │ │ ├── detours.h │ │ ├── detver.h │ │ ├── disasm.cpp │ │ ├── image.cpp │ │ ├── modules.cpp │ │ └── uimports.cpp │ ├── fiber.cpp │ ├── fiber_cond.cpp │ ├── fiber_event.cpp │ ├── fiber_lock.cpp │ ├── fiber_mutex.cpp │ ├── fiber_mutex_stat.cpp │ ├── fiber_pool.cpp │ ├── fiber_sem.cpp │ ├── stdafx.cpp │ ├── stdafx.hpp │ ├── wait_group.cpp │ ├── winapi_hook.cpp │ └── winapi_hook.hpp └── xmake.lua ├── doc ├── benchmark.pptx └── benchmark.txt ├── fiber.xcodeproj └── project.pbxproj ├── fiber.xcworkspace └── contents.xcworkspacedata ├── fiber_cpp.xcodeproj └── project.pbxproj ├── libfiber_vc2019.sln ├── res ├── benchmark.png └── winecho.png └── samples ├── Makefile ├── c ├── Makefile ├── Makefile.in ├── WinEchod │ ├── Client.cpp │ ├── Client.h │ ├── Connect.cpp │ ├── Connect.h │ ├── Listener.cpp │ ├── Listener.h │ ├── ReadMe.txt │ ├── Sleep.cpp │ ├── Sleep.h │ ├── WinEchod.cpp │ ├── WinEchod.h │ ├── WinEchod.rc │ ├── WinEchod.vcxproj │ ├── WinEchod.vcxproj.filters │ ├── WinEchodDlg.cpp │ ├── WinEchodDlg.h │ ├── WinEchod_vc2013.vcxproj │ ├── WinEchod_vc2013.vcxproj.filters │ ├── WinEchod_vc2015.vcxproj │ ├── WinEchod_vc2015.vcxproj.filters │ ├── res │ │ ├── WinEchod.ico │ │ └── WinEchod.rc2 │ ├── resource.h │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h ├── client │ ├── Makefile │ ├── client_vc2012.vcxproj │ ├── client_vc2012.vcxproj.filters │ ├── client_vc2013.vcxproj │ ├── client_vc2013.vcxproj.filters │ ├── client_vc2015.vcxproj │ ├── client_vc2015.vcxproj.filters │ ├── main.c │ └── valgrind.sh ├── dns │ ├── Makefile │ ├── main.c │ └── t.sh ├── event │ ├── Makefile │ └── main.c ├── fiber │ ├── Makefile │ └── main.c ├── getaddrinfo │ ├── Makefile │ └── main.c ├── getopt.c ├── patch.c ├── patch.cpp ├── patch.h ├── poll │ ├── Makefile │ └── main.c ├── server │ ├── Makefile │ ├── main.c │ ├── server_vc2012.vcxproj │ ├── server_vc2012.vcxproj.filters │ ├── server_vc2013.vcxproj │ ├── server_vc2013.vcxproj.filters │ ├── server_vc2015.vcxproj │ ├── server_vc2015.vcxproj.filters │ └── valgrind.sh ├── sleep │ ├── Makefile │ └── main.c ├── stamp.h ├── threads │ ├── Makefile │ └── main.c ├── util.c └── util.h ├── cpp ├── Makefile ├── Makefile.in ├── client │ ├── Makefile │ └── main.cpp ├── fiber │ ├── Makefile │ └── main.cpp ├── patch.cpp ├── patch.h ├── server │ ├── Makefile │ └── main.cpp ├── util.cpp ├── util.h └── waiter │ ├── Makefile │ └── main.cpp ├── cxx ├── Makefile ├── Makefile.in ├── client │ ├── Makefile │ └── main.cpp ├── fiber │ ├── Makefile │ └── main.cpp ├── fiber_pool │ ├── CMakeLists.txt │ ├── Makefile │ ├── main.cpp │ ├── stdafx.cpp │ └── stdafx.h ├── fiber_tbox │ ├── Makefile │ └── main.cpp ├── fiber_tbox2 │ ├── Makefile │ └── main.cpp ├── mutex │ ├── Makefile │ └── main.cpp ├── patch.cpp ├── patch.h ├── server │ ├── Makefile │ └── main.cpp ├── shared_stack │ ├── Makefile │ └── main.cpp ├── util.cpp ├── util.h ├── waite_group │ ├── Makefile │ └── main.cpp └── waiter │ ├── Makefile │ └── main.cpp ├── gui ├── EchoServer │ ├── EchoServer.cpp │ ├── EchoServer.h │ ├── EchoServer.rc │ ├── EchoServer.vcxproj │ ├── EchoServer.vcxproj.filters │ ├── EchoServer.vcxproj.user │ ├── EchoServerDlg.cpp │ ├── EchoServerDlg.h │ ├── FiberClient.cpp │ ├── FiberClient.h │ ├── FiberConnect.cpp │ ├── FiberConnect.h │ ├── FiberServer.cpp │ ├── FiberServer.h │ ├── framework.h │ ├── pch.cpp │ ├── pch.h │ ├── res │ │ ├── EchoServer.ico │ │ └── EchoServer.rc2 │ ├── resource.h │ └── targetver.h └── SimpleWin │ ├── FiberClient.cpp │ ├── FiberClient.h │ ├── FiberConnect.cpp │ ├── FiberConnect.h │ ├── FiberServer.cpp │ ├── FiberServer.h │ ├── Resource.h │ ├── SimpleWin.cpp │ ├── SimpleWin.h │ ├── SimpleWin.ico │ ├── SimpleWin.rc │ ├── SimpleWin.vcxproj │ ├── SimpleWin.vcxproj.filters │ ├── framework.h │ ├── pch.cpp │ ├── pch.h │ ├── small.ico │ └── targetver.h └── xcode └── fiber_server ├── fiber_server.xcodeproj └── project.pbxproj ├── fiber_server ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── FiberClient.cpp ├── FiberClient.hpp ├── FiberServer.cpp ├── FiberServer.hpp ├── FiberTest.h ├── FiberTest.mm ├── FiberThread.cpp ├── FiberThread.hpp ├── Info.plist ├── SceneDelegate.h ├── SceneDelegate.m ├── ViewController.h ├── ViewController.m └── main.m └── fiber_serverUITests ├── Info.plist └── fiber_serverUITests.m /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .xmake 3 | build 4 | debug 5 | package 6 | *.a 7 | .vs/ 8 | *.VC.db 9 | *.VC.opendb 10 | ipch/ 11 | x64/ 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY = all clean install 2 | all: 3 | @(cd c; make) 4 | @(cd cpp; make) 5 | clean cl: 6 | @(cd c; make clean) 7 | @(cd cpp; make clean) 8 | install: 9 | @(cd c; make install) 10 | @(cd cpp; make install) 11 | -------------------------------------------------------------------------------- /benchmark/libco/Makefile: -------------------------------------------------------------------------------- 1 | libco_server: libco_server.cpp 2 | g++ -o libco_server libco_server.cpp ../patch.cpp \ 3 | -lcolib -ldl -lpthread 4 | clean: 5 | @(rm -f libco_server) 6 | -------------------------------------------------------------------------------- /benchmark/libgo/Makefile: -------------------------------------------------------------------------------- 1 | libgo_server: libgo_server.cpp 2 | g++ -std=c++11 -o libgo_server libgo_server.cpp ../patch.cpp \ 3 | -DBOOST_COROUTINES_NO_DEPRECATION_WARNING \ 4 | -I../../../download/fiber/libgo/libgo/linux \ 5 | -I../../../download/fiber/libgo \ 6 | -L../../../download/fiber/libgo/build -llibgo \ 7 | -Wl,-rpath,../../../download/fiber/libgo/build \ 8 | -lboost_coroutine -lboost_thread -lboost_system \ 9 | -ldl -Wl,-rpath,/usr/local/lib -lpthread 10 | clean: 11 | @(rm -f libgo_server) 12 | -------------------------------------------------------------------------------- /benchmark/libgo/libgo_server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../patch.h" 8 | #include "libgo/libgo.h" 9 | 10 | static void doit(SOCKET s) 11 | { 12 | char buf[8192]; 13 | int sz; 14 | 15 | while (1) { 16 | sz = read(s, buf, sizeof(buf) - 1); 17 | if (sz == 0) { 18 | break; 19 | } else if (sz < 0) { 20 | if (errno == EAGAIN || errno == EINTR) { 21 | continue; 22 | } 23 | break; 24 | } 25 | 26 | buf[sz] = 0; 27 | if (write(s, buf, sz) != sz) { 28 | break; 29 | } 30 | } 31 | 32 | close(s); 33 | } 34 | 35 | static void do_server(SOCKET ls) 36 | { 37 | while (1) { 38 | SOCKET s = socket_accept(ls); 39 | printf("accept one %d\r\n", s); 40 | if (s != INVALID_SOCKET) { 41 | go [=] { doit(s); }; 42 | } else { 43 | printf("accept error %s\r\n", strerror(errno)); 44 | break; 45 | } 46 | } 47 | 48 | close(ls); 49 | } 50 | 51 | static void usage(const char *procname) 52 | { 53 | printf("usage: %s -h[help] -s ip -p port\r\n", procname); 54 | } 55 | 56 | int main(int argc, char *argv[]) 57 | { 58 | char ip[128]; 59 | int port = 9001, ch; 60 | 61 | snprintf(ip, sizeof(ip), "127.0.0.1"); 62 | 63 | while ((ch = getopt(argc, argv, "hs:p:")) > 0) { 64 | switch (ch) { 65 | case 'h': 66 | usage(argv[0]); 67 | return 0; 68 | case 's': 69 | snprintf(ip, sizeof(ip), "%s", optarg); 70 | break; 71 | case 'p': 72 | port = atoi(optarg); 73 | break; 74 | default: 75 | break; 76 | } 77 | } 78 | 79 | SOCKET ls = socket_listen(ip, port); 80 | if (ls == INVALID_SOCKET) { 81 | printf("tcplisten error %s\r\n", strerror(errno)); 82 | return 1; 83 | } 84 | printf("listen %s:%d ok\r\n", ip, port); 85 | 86 | go[=] { do_server(ls); }; 87 | 88 | g_Scheduler.RunUntilNoTask(); 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /benchmark/libmill/Makefile: -------------------------------------------------------------------------------- 1 | libmill_server: libmill_server.c 2 | gcc -o libmill_server libmill_server.c -lmill 3 | clean: 4 | @(rm -f libmill_server) 5 | -------------------------------------------------------------------------------- /benchmark/libmill/libmill_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "libmill.h" 6 | 7 | static coroutine void doit(tcpsock as) 8 | { 9 | int64_t deadline = now() + 10000; 10 | char buf[8192]; 11 | size_t sz; 12 | 13 | deadline = -1; 14 | while (1) { 15 | sz = tcprecvuntil(as, buf, sizeof(buf) - 1, "\n", 1, deadline); 16 | if (sz == 0) { 17 | break; 18 | } else if (errno != 0) { 19 | break; 20 | } 21 | 22 | buf[sz] = 0; 23 | if (tcpsend(as, buf, sz, deadline) == 0) { 24 | break; 25 | } 26 | if (errno != 0) { 27 | break; 28 | } 29 | tcpflush(as, deadline); 30 | if (errno != 0) { 31 | break; 32 | } 33 | } 34 | 35 | tcpclose(as); 36 | } 37 | 38 | static void usage(const char *procname) 39 | { 40 | printf("usage: %s -h[help] -s ip -p port\r\n", procname); 41 | } 42 | 43 | int main(int argc, char *argv[]) 44 | { 45 | char ip[128]; 46 | int port = 9001, ch; 47 | 48 | snprintf(ip, sizeof(ip), "127.0.0.1"); 49 | 50 | while ((ch = getopt(argc, argv, "hs:p:")) > 0) { 51 | switch (ch) { 52 | case 'h': 53 | usage(argv[0]); 54 | return 0; 55 | case 's': 56 | snprintf(ip, sizeof(ip), "%s", optarg); 57 | break; 58 | case 'p': 59 | port = atoi(optarg); 60 | break; 61 | default: 62 | break; 63 | } 64 | } 65 | 66 | ipaddr addr = iplocal(ip, port, 0); 67 | tcpsock ls = tcplisten(addr, 10); 68 | if (!ls) { 69 | printf("tcplisten error %s\r\n", strerror(errno)); 70 | return 1; 71 | } 72 | 73 | printf("listen %s:%d ok\r\n", ip, port); 74 | 75 | while (1) { 76 | tcpsock as = tcpaccept(ls, -1); 77 | if (as) { 78 | go(doit(as)); 79 | } else { 80 | printf("tcpaccept error %s\r\n", strerror(errno)); 81 | break; 82 | } 83 | } 84 | 85 | tcpclose(ls); 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /benchmark/patch.h: -------------------------------------------------------------------------------- 1 | #ifndef __WIN_PATCH_INCLUDE_H__ 2 | #define __WIN_PATCH_INCLUDE_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #if defined(_WIN32) || defined(_WIN64) 9 | # include 10 | # define HAVE_NO_GETOPT 11 | # define snprintf _snprintf 12 | extern int optind; 13 | extern char *optarg; 14 | int getopt(int argc, char * const argv[], char *opts); 15 | #else 16 | # define SOCKET int 17 | # define INVALID_SOCKET -1 18 | #endif 19 | 20 | void socket_init(void); 21 | void socket_end(void); 22 | void socket_close(SOCKET fd); 23 | SOCKET socket_listen(const char *ip, int port); 24 | SOCKET socket_accept(SOCKET fd); 25 | SOCKET socket_connect(const char *ip, int port); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /benchmark/tbox/Makefile: -------------------------------------------------------------------------------- 1 | tbox_server: tbox_server.c 2 | gcc -o tbox_server tbox_server.c \ 3 | -ltbox -ldl -lpthread -lz -lm 4 | clean: 5 | @(rm -f tbox_server) 6 | -------------------------------------------------------------------------------- /c/include/fiber/fiber_cond.h: -------------------------------------------------------------------------------- 1 | #ifndef FIBER_COND_INCLUDE_H 2 | #define FIBER_COND_INCLUDE_H 3 | 4 | #include "fiber_define.h" 5 | #include "fiber_mutex.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | /* fiber_cond.h */ 12 | 13 | /** 14 | * Fiber_cond object look like pthread_cond_t which is used between threads 15 | * and fibers 16 | */ 17 | typedef struct ACL_FIBER_COND ACL_FIBER_COND; 18 | 19 | /** 20 | * Create fiber cond which can be used in fibers more or threads mode 21 | * @param flag {unsigned} current not used, just for the future extend 22 | * @return {ACL_FIBER_COND *} 23 | */ 24 | FIBER_API ACL_FIBER_COND *acl_fiber_cond_create(unsigned flag); 25 | 26 | /** 27 | * Free cond created by acl_fiber_cond_create 28 | * @param cond {ACL_FIBER_COND *} 29 | */ 30 | FIBER_API void acl_fiber_cond_free(ACL_FIBER_COND *cond); 31 | 32 | /** 33 | * Wait for cond event to be signaled 34 | * @param cond {ACL_FIBER_COND *} 35 | * @param mutex {ACL_FIBER_MUTEX *} must be owned by the current caller 36 | * @return {int} return 0 if ok or return error value 37 | */ 38 | FIBER_API int acl_fiber_cond_wait(ACL_FIBER_COND *cond, ACL_FIBER_MUTEX *mutex); 39 | 40 | /** 41 | * Wait for cond event to be signaled with the specified timeout 42 | * @param cond {ACL_FIBER_COND *} 43 | * @param mutex {ACL_FIBER_MUTEX *} must be owned by the current caller 44 | * @param delay_ms {int} 45 | * @return {int} return 0 if ok or return error value, when timeout ETIMEDOUT 46 | * will be returned 47 | */ 48 | FIBER_API int acl_fiber_cond_timedwait(ACL_FIBER_COND *cond, 49 | ACL_FIBER_MUTEX *mutex, int delay_ms); 50 | 51 | /** 52 | * Signal the cond which will wakeup one waiter for the cond to be signaled 53 | * @param cond {ACL_FIBER_COND *} 54 | * @return {int} return 0 if ok or return error value 55 | */ 56 | FIBER_API int acl_fiber_cond_signal(ACL_FIBER_COND *cond); 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif // !defined(_WIN32) && !defined(_WIN64) 63 | 64 | -------------------------------------------------------------------------------- /c/include/fiber/fiber_event.h: -------------------------------------------------------------------------------- 1 | #ifndef FIBER_EVENT_INCLUDE_H 2 | #define FIBER_EVENT_INCLUDE_H 3 | 4 | #include "fiber_define.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /* fiber_event.c */ 11 | 12 | /** 13 | * Fiber event mutex object based on IO event, which is thread safety. That's 14 | * to say one event object can used in different threads 15 | */ 16 | typedef struct ACL_FIBER_EVENT ACL_FIBER_EVENT; 17 | 18 | /** 19 | * When the fiber_event is used in multiple threads for sync, if there are 20 | * many threads, the flag FIBER_FLAG_USE_MUTEX should be set to avoid internal 21 | * thundering herd which maybe happen by using atomic; if the threads' number 22 | * is less than one hundred, the flag FIBER_FLAG_USE_MUTEX needn't be set 23 | */ 24 | #define FIBER_FLAG_USE_MUTEX (1 << 0) 25 | 26 | /** 27 | * If this flag is set, msg_fatal will be used other msg_error when error 28 | * happened, this flag is optional for users 29 | */ 30 | #define FIBER_FLAG_USE_FATAL (1 << 1) 31 | 32 | /** 33 | * Create fiber event mutex which can be used in fibers mode or threads mode 34 | * @param flag {unsigned} define as FIBER_FLAG_XXX above 35 | * @return {ACL_FIBER_EVENT *} 36 | */ 37 | FIBER_API ACL_FIBER_EVENT *acl_fiber_event_create(unsigned flag); 38 | 39 | /** 40 | * Free event mutex returned by acl_fiber_event_create 41 | * @param {ACL_FIBER_EVENT *} 42 | */ 43 | FIBER_API void acl_fiber_event_free(ACL_FIBER_EVENT *event); 44 | 45 | /** 46 | * Wait for event can be available 47 | * @param {ACL_FIBER_EVENT *} 48 | * @return {int} 0 returned if successful, or -1 if error happened 49 | */ 50 | FIBER_API int acl_fiber_event_wait(ACL_FIBER_EVENT *event); 51 | 52 | /** 53 | * Try to wait for event can be available 54 | * @param {ACL_FIBER_EVENT *} 55 | * @return {int} 0 returned if successful, or -1 if the event been locked 56 | */ 57 | FIBER_API int acl_fiber_event_trywait(ACL_FIBER_EVENT *event); 58 | 59 | /** 60 | * The event's owner notify the waiters that the event mutex can be available, 61 | * and the waiter will get the event mutex 62 | * @param {ACL_FIBER_EVENT *} 63 | * @return {int} 0 returned if successful, or -1 if error happened 64 | */ 65 | FIBER_API int acl_fiber_event_notify(ACL_FIBER_EVENT *event); 66 | 67 | #ifdef __cplusplus 68 | } 69 | #endif 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /c/include/fiber/fiber_mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef FIBER_MUTEX_INCLUDE_H 2 | #define FIBER_MUTEX_INCLUDE_H 3 | 4 | #include "fiber_define.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | typedef struct ACL_FIBER_MUTEX ACL_FIBER_MUTEX; 11 | 12 | #define FIBER_MUTEX_F_LOCK_TRY (1 << 0) 13 | #define FIBER_MUTEX_F_LOCK_ONCE (1 << 1) 14 | #define FIBER_MUTEX_F_CHECK_DEADLOCK (1 << 2) 15 | 16 | FIBER_API ACL_FIBER_MUTEX *acl_fiber_mutex_create(unsigned flag); 17 | FIBER_API void acl_fiber_mutex_free(ACL_FIBER_MUTEX *mutex); 18 | FIBER_API int acl_fiber_mutex_lock(ACL_FIBER_MUTEX *mutex); 19 | FIBER_API int acl_fiber_mutex_trylock(ACL_FIBER_MUTEX *mutex); 20 | FIBER_API int acl_fiber_mutex_unlock(ACL_FIBER_MUTEX *mutex); 21 | 22 | typedef struct ACL_FIBER_MUTEX_STAT { 23 | ACL_FIBER *fiber; // The fiber with the stat object. 24 | ACL_FIBER_MUTEX *waiting; // The mutex been waited by the fiber. 25 | ACL_FIBER_MUTEX **holding; // The mutexes held by the fiber. 26 | size_t count; // The holding's count. 27 | } ACL_FIBER_MUTEX_STAT; 28 | 29 | typedef struct ACL_FIBER_MUTEX_STATS { 30 | ACL_FIBER_MUTEX_STAT *stats; // The array holding the stats above. 31 | size_t count; // The stats array's size. 32 | } ACL_FIBER_MUTEX_STATS; 33 | 34 | 35 | FIBER_API void acl_fiber_mutex_profile(void); 36 | FIBER_API ACL_FIBER_MUTEX_STATS *acl_fiber_mutex_deadlock(void); 37 | FIBER_API void acl_fiber_mutex_stats_free(ACL_FIBER_MUTEX_STATS *stats); 38 | FIBER_API void acl_fiber_mutex_stats_show(const ACL_FIBER_MUTEX_STATS *stats); 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /c/include/fiber/lib_fiber.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_FIBER_INCLUDE_H 2 | #define LIB_FIBER_INCLUDE_H 3 | 4 | #include "libfiber.h" 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /c/include/fiber/libfiber.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBFIBER_INCLUDE_H 2 | #define LIBFIBER_INCLUDE_H 3 | 4 | #include "fiber_base.h" 5 | #include "fiber_lock.h" 6 | #include "fiber_mutex.h" 7 | #include "fiber_event.h" 8 | #include "fiber_cond.h" 9 | #include "fiber_sem.h" 10 | #include "fiber_hook.h" 11 | #include "fiber_channel.h" 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /c/libfiber.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/libfiber.rc -------------------------------------------------------------------------------- /c/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/resource.h -------------------------------------------------------------------------------- /c/src/common.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_INCLUDE_H__ 2 | #define __COMMON_INCLUDE_H__ 3 | 4 | #include "common/init.h" 5 | #include "common/memory.h" 6 | #include "common/ring.h" 7 | #include "common/msg.h" 8 | #include "common/atomic.h" 9 | #include "common/iostuff.h" 10 | #include "common/array.h" 11 | #include "common/argv.h" 12 | #include "common/htable.h" 13 | #include "common/iterator.h" 14 | #include "common/strops.h" 15 | #include "common/pthread_patch.h" 16 | #include "common/memory.h" 17 | #include "common/sane_socket.h" 18 | #include "common/avl.h" 19 | #include "common/timer_cache.h" 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /c/src/common/argv.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/argv.h -------------------------------------------------------------------------------- /c/src/common/array.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/array.h -------------------------------------------------------------------------------- /c/src/common/atomic.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/atomic.h -------------------------------------------------------------------------------- /c/src/common/close_on_exec.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include 3 | 4 | /* Utility library. */ 5 | 6 | #include "msg.h" 7 | #include "iostuff.h" 8 | 9 | #define PATTERN FD_CLOEXEC 10 | 11 | /* close_on_exec - set/clear close-on-exec flag */ 12 | 13 | int close_on_exec(int fd, int on) 14 | { 15 | #ifdef SYS_UNIX 16 | int flags; 17 | 18 | if ((flags = fcntl(fd, F_GETFD, 0)) < 0) { 19 | msg_fatal("fcntl: get flags: %s", last_serror()); 20 | } 21 | if (fcntl(fd, F_SETFD, on ? flags | PATTERN : flags & ~PATTERN) < 0) { 22 | msg_fatal("fcntl: set close-on-exec flag %s: %s", 23 | on ? "on" : "off", last_serror()); 24 | } 25 | 26 | return ((flags & PATTERN) != 0); 27 | #else 28 | (void) fd; 29 | (void) on; 30 | return 0; 31 | #endif 32 | } 33 | -------------------------------------------------------------------------------- /c/src/common/doze.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "fiber/libfiber.h" 3 | #include "msg.h" 4 | #include "iostuff.h" 5 | 6 | /* doze - sleep a while */ 7 | 8 | #ifdef SYS_WIN 9 | void doze(unsigned delay) { 10 | Sleep(delay); 11 | } 12 | #else 13 | void doze(unsigned delay) 14 | { 15 | struct timeval tv; 16 | 17 | tv.tv_sec = delay / 1000; 18 | tv.tv_usec = (suseconds_t) (delay - tv.tv_sec * 1000) * 1000; 19 | 20 | while (select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv) < 0) { 21 | if (acl_fiber_last_error() != FIBER_EINTR) { 22 | msg_fatal("doze: select: %s", last_serror()); 23 | } 24 | } 25 | } 26 | #endif 27 | -------------------------------------------------------------------------------- /c/src/common/fifo.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/fifo.h -------------------------------------------------------------------------------- /c/src/common/gettimeofday.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/gettimeofday.c -------------------------------------------------------------------------------- /c/src/common/gettimeofday.h: -------------------------------------------------------------------------------- 1 | #ifndef __GETTIMEOFDAY_HEAD_H__ 2 | #define __GETTIMEOFDAY_HEAD_H__ 3 | 4 | #include "define.h" 5 | 6 | #ifdef SYS_WIN 7 | int gettimeofday(struct timeval *tv, struct timezone *tz); 8 | #endif 9 | 10 | #if defined(USE_FAST_TIME) 11 | void set_time_metric(int ms); 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /c/src/common/htable.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/htable.h -------------------------------------------------------------------------------- /c/src/common/init.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "pthread_patch.h" 3 | #include "init.h" 4 | 5 | static long var_main_tid = (unsigned long) -1; 6 | 7 | #ifdef __GNUC__ 8 | void lib_init(void) __attribute__ ((constructor)); 9 | #endif 10 | 11 | void lib_init(void) 12 | { 13 | static int __have_inited = 0; 14 | 15 | if (__have_inited) { 16 | return; 17 | } 18 | __have_inited = 1; 19 | var_main_tid = thread_self(); 20 | } 21 | 22 | long main_thread_self(void) 23 | { 24 | return var_main_tid; 25 | } 26 | -------------------------------------------------------------------------------- /c/src/common/init.h: -------------------------------------------------------------------------------- 1 | #ifndef __INIT_H__ 2 | #define __INIT_H__ 3 | 4 | void lib_init(void); 5 | long main_thread_self(void); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /c/src/common/iostuff.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/iostuff.h -------------------------------------------------------------------------------- /c/src/common/iterator.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/iterator.h -------------------------------------------------------------------------------- /c/src/common/mbox.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/mbox.h -------------------------------------------------------------------------------- /c/src/common/msg.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/msg.h -------------------------------------------------------------------------------- /c/src/common/non_blocking.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "fiber/fiber_base.h" 3 | 4 | #include "msg.h" 5 | #include "iostuff.h" 6 | 7 | #ifdef SYS_WIN 8 | 9 | int non_blocking(socket_t fd, int on) 10 | { 11 | unsigned long n = on; 12 | int flags = 0; 13 | 14 | if (ioctlsocket(fd, FIONBIO, &n) < 0) { 15 | msg_error("ioctlsocket(fd,FIONBIO) failed"); 16 | return -1; 17 | } 18 | return flags; 19 | } 20 | 21 | static __thread __is_non_blocking = 0; 22 | 23 | void acl_fiber_set_non_blocking(int yes) 24 | { 25 | __is_non_blocking = yes; 26 | } 27 | 28 | int is_non_blocking(socket_t fd) 29 | { 30 | return __is_non_blocking; 31 | } 32 | 33 | 34 | #elif defined(SYS_UNIX) 35 | 36 | # ifndef O_NONBLOCK 37 | # define PATTERN FNDELAY 38 | # else 39 | # define PATTERN O_NONBLOCK 40 | # endif 41 | 42 | int non_blocking(socket_t fd, int on) 43 | { 44 | int flags; 45 | int nonb = PATTERN; 46 | 47 | /* 48 | ** NOTE: consult ALL your relevant manual pages *BEFORE* changing 49 | ** these ioctl's. There are quite a few variations on them, 50 | ** as can be seen by the PCS one. They are *NOT* all the same. 51 | ** Heed this well. - Avalon. 52 | */ 53 | #ifdef NBLOCK_POSIX 54 | nonb |= O_NONBLOCK; 55 | #endif 56 | #ifdef NBLOCK_BSD 57 | nonb |= O_NDELAY; 58 | #endif 59 | 60 | if ((flags = fcntl(fd, F_GETFL)) == -1) { 61 | msg_error("%s(%d), %s: fcntl(%d, F_GETFL) error: %s", 62 | __FILE__, __LINE__, __FUNCTION__, fd, last_serror()); 63 | return -1; 64 | } 65 | if (fcntl(fd, F_SETFL, on ? flags | nonb : flags & ~nonb) < 0) { 66 | msg_error("%s(%d), %s: fcntl(%d, F_SETL, nonb) error: %s", 67 | __FILE__, __LINE__, __FUNCTION__, fd, last_serror()); 68 | return -1; 69 | } 70 | 71 | return (flags & PATTERN) ? 1 : 0; 72 | } 73 | 74 | int is_non_blocking(socket_t fd) 75 | { 76 | int flags; 77 | 78 | if ((flags = fcntl(fd, F_GETFL)) == -1) { 79 | msg_error("%s(%d), %s: fcntl(%d, F_GETFL) error: %s", 80 | __FILE__, __LINE__, __FUNCTION__, 81 | fd, last_serror()); 82 | return 0; 83 | } 84 | 85 | return (flags & PATTERN) ? 1 : 0; 86 | } 87 | 88 | void acl_fiber_set_non_blocking(int yes) 89 | { 90 | (void) yes; 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /c/src/common/pthread_patch.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/pthread_patch.c -------------------------------------------------------------------------------- /c/src/common/pthread_patch.h: -------------------------------------------------------------------------------- 1 | #ifndef PTHREAD_INCLUDE_H 2 | #define PTHREAD_INCLUDE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #if defined(_WIN32) || defined(_WIN64) 9 | #include 10 | #include "fiber/fiber_define.h" 11 | 12 | #define __thread __declspec(thread) 13 | 14 | //#define TLS_OUT_OF_INDEXES 0xffffffff 15 | #define PTHREAD_KEYS_MAX 1024 16 | #define PTHREAD_ONCE_INIT 0 17 | typedef unsigned long pthread_t; 18 | typedef struct pthread_mutex_t pthread_mutex_t; 19 | typedef struct pthread_mutexattr_t pthread_mutexattr_t; 20 | typedef int pthread_key_t; 21 | typedef int pthread_once_t; 22 | 23 | struct pthread_mutex_t { 24 | HANDLE id; 25 | char dynamic; 26 | }; 27 | 28 | struct pthread_mutexattr_t { 29 | SECURITY_ATTRIBUTES attr; 30 | }; 31 | 32 | FIBER_API int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); 33 | int pthread_key_create(pthread_key_t *key_ptr, void (*destructor)(void*)); 34 | 35 | void *pthread_getspecific(pthread_key_t key); 36 | int pthread_setspecific(pthread_key_t key, void *value); 37 | 38 | int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mattr); 39 | int pthread_mutex_destroy(pthread_mutex_t *mutex); 40 | int pthread_mutex_lock(pthread_mutex_t *mutex); 41 | int pthread_mutex_trylock(pthread_mutex_t *mutex); 42 | int pthread_mutex_unlock(pthread_mutex_t *mutex); 43 | 44 | #endif // _WIN32 || _WIN64 45 | 46 | long thread_self(void); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /c/src/common/queue.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/queue.h -------------------------------------------------------------------------------- /c/src/common/read_wait.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "fiber/fiber_define.h" 3 | #include "fiber.h" 4 | #include "msg.h" 5 | #include "iostuff.h" 6 | 7 | int read_wait(socket_t fd, int delay) 8 | { 9 | struct pollfd fds; 10 | 11 | fds.events = POLLIN; 12 | fds.fd = fd; 13 | 14 | for (;;) { 15 | switch (acl_fiber_poll(&fds, 1, delay)) { 16 | #ifdef SYS_WIN 17 | case SOCKET_ERROR: 18 | #else 19 | case -1: 20 | #endif 21 | if (acl_fiber_last_error() == FIBER_EINTR) { 22 | continue; 23 | } 24 | return -1; 25 | case 0: 26 | acl_fiber_set_error(FIBER_ETIME); 27 | return -1; 28 | default: 29 | if ((fds.revents & POLLIN)) { 30 | return 0; 31 | } 32 | if (fds.revents & (POLLHUP | POLLERR | POLLNVAL)) { 33 | return 0; 34 | } 35 | 36 | return -1; 37 | } 38 | } 39 | } 40 | 41 | static int readable(socket_t fd) 42 | { 43 | struct pollfd fds; 44 | int delay = 0; 45 | 46 | fds.fd = fd; 47 | #ifdef SYS_WINDOWS 48 | fds.events = POLLIN /* | POLLHUP | POLLERR */; 49 | #else 50 | fds.events = POLLIN | POLLHUP | POLLERR | POLLPRI; 51 | #endif 52 | fds.revents = 0; 53 | 54 | for (;;) { 55 | switch (acl_fiber_poll(&fds, 1, delay)) { 56 | #ifdef SYS_WINDOWS 57 | case SOCKET_ERROR: 58 | #else 59 | case -1: 60 | #endif 61 | if (acl_fiber_last_error() == FIBER_EINTR) { 62 | continue; 63 | } 64 | 65 | return -1; 66 | case 0: 67 | return 0; 68 | default: 69 | if ((fds.revents & POLLIN)) { 70 | return 1; 71 | } else if (fds.revents & (POLLHUP | POLLERR)) { 72 | return 1; 73 | } else { 74 | return 0; 75 | } 76 | } 77 | } 78 | } 79 | 80 | int socket_alive(socket_t fd) 81 | { 82 | char buf[16]; 83 | int ret = readable(fd); 84 | 85 | if (ret == -1) { 86 | return 0; 87 | } 88 | 89 | if (ret == 0) { 90 | return 1; 91 | } 92 | 93 | ret = (int) acl_fiber_recv(fd, buf, sizeof(buf), MSG_PEEK); 94 | 95 | if (ret == 0) { 96 | return 0; 97 | } 98 | 99 | if (ret < 0 && acl_fiber_last_error() != FIBER_EWOULDBLOCK) { 100 | return 0; 101 | } 102 | 103 | return 1; 104 | } 105 | -------------------------------------------------------------------------------- /c/src/common/ring.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "ring.h" 4 | 5 | #ifndef USE_FAST_RING 6 | 7 | /* ring_init - initialize ring head */ 8 | void ring_init(RING *ring) 9 | { 10 | ring->pred = ring->succ = ring; 11 | ring->parent = ring; 12 | ring->len = 0; 13 | } 14 | 15 | /* ring_size - the entry number in the ring */ 16 | 17 | int ring_size(const RING *ring) 18 | { 19 | return ring->len; 20 | } 21 | 22 | /* ring_append - insert entry after ring head */ 23 | 24 | void ring_append(RING *ring, RING *entry) 25 | { 26 | entry->succ = ring->succ; 27 | entry->pred = ring; 28 | entry->parent = ring->parent; 29 | ring->succ->pred = entry; 30 | ring->succ = entry; 31 | ring->parent->len++; 32 | } 33 | 34 | /* ring_prepend - insert new entry before ring head */ 35 | 36 | void ring_prepend(RING *ring, RING *entry) 37 | { 38 | entry->pred = ring->pred; 39 | entry->succ = ring; 40 | entry->parent = ring->parent; 41 | ring->pred->succ = entry; 42 | ring->pred = entry; 43 | ring->parent->len++; 44 | } 45 | 46 | /* ring_detach - remove entry from ring */ 47 | 48 | void ring_detach(RING *entry) 49 | { 50 | RING *succ, *pred; 51 | 52 | if (entry->parent != entry) { 53 | succ = entry->succ; 54 | pred = entry->pred; 55 | if (succ && pred) { 56 | pred->succ = succ; 57 | succ->pred = pred; 58 | 59 | entry->parent->len--; 60 | entry->succ = entry->pred = entry; 61 | entry->parent = entry; 62 | entry->len = 0; 63 | } 64 | } 65 | } 66 | 67 | /* ring_pop_head - pop ring's head entry out from ring */ 68 | 69 | RING *ring_pop_head(RING *ring) 70 | { 71 | RING *succ; 72 | 73 | succ = ring->succ; 74 | if (succ == ring) { 75 | return NULL; 76 | } 77 | 78 | ring_detach(succ); 79 | return succ; 80 | } 81 | 82 | /* ring_pop_tail - pop ring's tail entry out from ring */ 83 | 84 | RING *ring_pop_tail(RING *ring) 85 | { 86 | RING *pred; 87 | 88 | pred = ring->pred; 89 | if (pred == ring) { 90 | return NULL; 91 | } 92 | 93 | ring_detach(pred); 94 | return pred; 95 | } 96 | 97 | #endif /* USE_FAST_RING */ 98 | -------------------------------------------------------------------------------- /c/src/common/ring.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/ring.h -------------------------------------------------------------------------------- /c/src/common/sane_socket.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "fiber/libfiber.h" 3 | #include "msg.h" 4 | #include "sane_socket.h" 5 | 6 | int is_listen_socket(socket_t fd) 7 | { 8 | int val, ret; 9 | #ifdef SYS_WIN 10 | int len = sizeof(val); 11 | #else 12 | socklen_t len = sizeof(val); 13 | #endif 14 | 15 | ret = getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, (char*) &val, &len); 16 | if (ret == -1) { 17 | return 0; 18 | } else if (val) { 19 | return 1; 20 | } else { 21 | return 0; 22 | } 23 | } 24 | 25 | int getsockfamily(socket_t fd) 26 | { 27 | SOCK_ADDR addr; 28 | struct sockaddr *sa = (struct sockaddr*) &addr; 29 | socklen_t len = sizeof(addr); 30 | 31 | if (fd == INVALID_SOCKET) { 32 | return -1; 33 | } 34 | 35 | if (getsockname(fd, sa, &len) == -1) { 36 | return -1; 37 | } 38 | 39 | #ifndef SYS_WIN 40 | if (sa->sa_family == AF_UNIX) { 41 | return AF_UNIX; 42 | } 43 | #endif 44 | #ifdef AF_INET6 45 | if (sa->sa_family == AF_INET || sa->sa_family == AF_INET6) { 46 | #else 47 | if (sa->sa_family == AF_INET) { 48 | #endif 49 | return sa->sa_family; 50 | } 51 | 52 | return -1; 53 | } 54 | 55 | int getsocktype(socket_t fd) 56 | { 57 | int type; 58 | socklen_t len = sizeof(len); 59 | 60 | if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void*) &type, &len) == -1) { 61 | return -1; 62 | } 63 | 64 | return type; 65 | } 66 | 67 | void tcp_so_linger(socket_t fd, int onoff, int timeout) 68 | { 69 | const char *myname = "tcp_so_linger"; 70 | struct linger l; 71 | int n = getsockfamily(fd); 72 | 73 | #ifdef AF_INET6 74 | if (n != AF_INET && n != AF_INET6) { 75 | #else 76 | if (n != AF_INET) { 77 | #endif 78 | return; 79 | } 80 | 81 | l.l_onoff = onoff ? 1 : 0; 82 | l.l_linger = timeout >= 0 ? timeout : 0; 83 | if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &l, sizeof(l)) < 0) { 84 | msg_error("%s(%d): setsockopt(SO_LINGER) error(%s)," 85 | " onoff(%d), timeout(%d)", myname, __LINE__, 86 | last_serror(), onoff, timeout); 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /c/src/common/sane_socket.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/common/sane_socket.h -------------------------------------------------------------------------------- /c/src/common/strops.h: -------------------------------------------------------------------------------- 1 | #ifndef __STROPS_HEADER_H__ 2 | #define __STROPS_HEADER_H__ 3 | 4 | #include "define.h" 5 | 6 | #ifndef SAFE_STRNCPY 7 | #define SAFE_STRNCPY(_obj, _src, _size) do { \ 8 | if (_size > 0) { \ 9 | size_t _n = strlen(_src); \ 10 | _n = _n > (size_t ) _size - 1? (size_t) _size - 1 : _n; \ 11 | memcpy(_obj, _src, _n); \ 12 | _obj[_n] = 0; \ 13 | } \ 14 | } while (0) 15 | #endif 16 | 17 | #ifdef SYS_WIN 18 | int strncasecmp(const char *s1, const char *s2, size_t n); 19 | #endif 20 | 21 | char *mystrtok(char **src, const char *sep); 22 | char *lowercase(char *s); 23 | int alldig(const char *s); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /c/src/common/tcp_nodelay.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "msg.h" 4 | #include "sane_socket.h" 5 | #include "iostuff.h" 6 | 7 | void tcp_nodelay(socket_t fd, int onoff) 8 | { 9 | const char *myname = "tcp_nodelay"; 10 | int on = onoff ? 1 : 0; 11 | int n = getsockfamily(fd); 12 | 13 | if (n != AF_INET && n != AF_INET6) { 14 | return; 15 | } 16 | 17 | if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, 18 | (char *) &on, sizeof(on)) < 0) { 19 | 20 | msg_error("%s(%d): set nodelay error(%s), onoff(%d)", 21 | myname, __LINE__, last_serror(), onoff); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /c/src/common/timer_cache.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMER_CACHE_INCLUDE_H 2 | #define TIMER_CACHE_INCLUDE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "ring.h" 9 | #include "array.h" 10 | #include "avl.h" 11 | 12 | typedef struct TIMER_CACHE_NODE TIMER_CACHE_NODE; 13 | typedef struct TIMER_CACHE TIMER_CACHE; 14 | 15 | struct TIMER_CACHE_NODE { 16 | RING ring; 17 | fiber_avl_node_t node; 18 | long long expire; 19 | }; 20 | 21 | struct TIMER_CACHE { 22 | fiber_avl_tree_t tree; 23 | RING caches; // Caching the TIMER_CACHE_NODE memory 24 | int cache_max; 25 | ARRAY *objs; // Holding any object temporarily. 26 | ARRAY *objs2; // Holding any object temporarily. 27 | }; 28 | 29 | TIMER_CACHE *timer_cache_create(void); 30 | unsigned timer_cache_size(TIMER_CACHE *cache); 31 | void timer_cache_free(TIMER_CACHE *cache); 32 | void timer_cache_add(TIMER_CACHE *cache, long long expire, RING *entry); 33 | int timer_cache_remove(TIMER_CACHE *cache, long long expire, RING *entry); 34 | void timer_cache_free_node(TIMER_CACHE *cache, TIMER_CACHE_NODE *node); 35 | int timer_cache_remove_exist(TIMER_CACHE *cache, long long expire, RING *entry); 36 | int timer_cache_exist(TIMER_CACHE *cache, long long expire, RING *entry); 37 | 38 | #define TIMER_FIRST(cache) ((TIMER_CACHE_NODE*) fiber_avl_first(&(cache)->tree)) 39 | #define TIMER_NEXT(cache, curr) ((TIMER_CACHE_NODE*) AVL_NEXT(&(cache)->tree, (curr))) 40 | 41 | #ifdef __cplusplus 42 | } 43 | #endif 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /c/src/common/ypipe.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "atomic.h" 4 | #include "yqueue.h" 5 | #include "ypipe.h" 6 | 7 | struct YPIPE { 8 | YQUEUE *queue; 9 | void **w; 10 | void **r; 11 | void **f; 12 | ATOMIC *c; 13 | unsigned long reads; 14 | unsigned long writes; 15 | }; 16 | 17 | YPIPE *ypipe_new(void) 18 | { 19 | YPIPE *self = (YPIPE *) calloc(1, sizeof(YPIPE)); 20 | void **item; 21 | 22 | self->queue = yqueue_new(); 23 | yqueue_push(self->queue); 24 | item = yqueue_back(self->queue);; 25 | self->w = item; 26 | self->f = item; 27 | self->r = item; 28 | self->c = atomic_new(); 29 | atomic_set(self->c, item); 30 | 31 | return self; 32 | } 33 | void ypipe_free(YPIPE *self, void(*free_data_fun)(void*)) 34 | { 35 | yqueue_free(self->queue, free_data_fun); 36 | atomic_free(self->c); 37 | free(self); 38 | } 39 | 40 | void *ypipe_read(YPIPE *self) 41 | { 42 | void *value; 43 | 44 | if (!ypipe_check_read(self)) { 45 | return NULL; 46 | } 47 | 48 | value = *yqueue_front(self->queue); 49 | yqueue_pop(self->queue); 50 | self->reads++; 51 | 52 | return value; 53 | } 54 | 55 | void ypipe_write(YPIPE *self, void *data) 56 | { 57 | *yqueue_back(self->queue) = data; 58 | yqueue_push(self->queue); 59 | self->f = yqueue_back(self->queue); 60 | self->writes++; 61 | } 62 | 63 | int ypipe_flush(YPIPE *self) 64 | { 65 | if (self->w == self->f) { 66 | return 0; 67 | } 68 | 69 | if (atomic_cas(self->c, self->w, self->f) != self->w) { 70 | atomic_set(self->c, self->f); 71 | self->w = self->f; 72 | return 1; 73 | } 74 | 75 | self->w = self->f; 76 | return 0; 77 | } 78 | 79 | int ypipe_check_read(YPIPE *self) 80 | { 81 | void **front = yqueue_front(self->queue); 82 | 83 | if (front != self->r && self->r && *self->r) { 84 | return 1; 85 | } 86 | 87 | self->r = (void **) atomic_cas(self->c, front, NULL); 88 | 89 | if (front == self->r || !(self->r)) { 90 | return 0; 91 | } 92 | 93 | return 1; 94 | } 95 | -------------------------------------------------------------------------------- /c/src/common/ypipe.h: -------------------------------------------------------------------------------- 1 | #ifndef _YPIPI_CINLUDE_H 2 | #define _YPIPI_CINLUDE_H 3 | 4 | typedef struct YPIPE YPIPE; 5 | 6 | YPIPE *ypipe_new(void); 7 | int ypipe_check_read(YPIPE *self); 8 | void *ypipe_read(YPIPE *self); 9 | void ypipe_write(YPIPE *self, void *data); 10 | int ypipe_flush(YPIPE *self); 11 | void ypipe_free(YPIPE *self, void(*free_fun)(void*)); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /c/src/common/yqueue.h: -------------------------------------------------------------------------------- 1 | #ifndef _YQUEUE_INCLUDE_H 2 | #define _YQUEUE_INCLUDE_H 3 | 4 | typedef struct YQUEUE YQUEUE; 5 | 6 | YQUEUE* yqueue_new(void); 7 | void yqueue_free(YQUEUE *yqueue, void(*free_fn)(void*)); 8 | void **yqueue_front(YQUEUE *yqueue); 9 | void **yqueue_back(YQUEUE *yqueue); 10 | void yqueue_push(YQUEUE *yqueue); 11 | void yqueue_pop(YQUEUE *yqueue); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /c/src/dns/resolver.h: -------------------------------------------------------------------------------- 1 | #ifndef __RESOLVER_INCLUDE_H__ 2 | #define __RESOLVER_INCLUDE_H__ 3 | 4 | #include "common/argv.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | typedef struct HOST_LOCAL { 11 | char ipv4[64]; 12 | char ipv6[64]; 13 | } HOST_LOCAL; 14 | 15 | typedef struct SERVICE_PORT { 16 | char name[128]; 17 | unsigned short port; 18 | ARGV *transports; 19 | } SERVICE_PORT; 20 | 21 | void resolver_init_once(void); 22 | struct addrinfo *resolver_getaddrinfo(const char *name, const char *service, 23 | const struct addrinfo* hints); 24 | void resolver_freeaddrinfo(struct addrinfo *res); 25 | struct addrinfo *resolver_addrinfo_alloc(const struct sockaddr *sa); 26 | 27 | unsigned short get_service_port(const char *name); 28 | const HOST_LOCAL *find_from_localhost(const char *name); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /c/src/dns/sane_inet.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/dns/sane_inet.h -------------------------------------------------------------------------------- /c/src/dns/valid_hostname.h: -------------------------------------------------------------------------------- 1 | #ifndef __VALID_HOSTNAME_INCLUDE_H__ 2 | #define __VALID_HOSTNAME_INCLUDE_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | /* External interface */ 9 | 10 | #define VALID_HOSTNAME_LEN 255 /* RFC 1035 */ 11 | #define VALID_LABEL_LEN 63 /* RFC 1035 */ 12 | 13 | #define DONT_GRIPE 0 14 | #define DO_GRIPE 1 15 | 16 | int valid_hostname(const char *, int); 17 | int valid_hostaddr(const char *, int); 18 | int valid_ipv4_hostaddr(const char *, int); 19 | int valid_ipv6_hostaddr(const char *, int); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /c/src/event/event_epoll.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_EPOLL_INCLUDE_H 2 | #define EVENT_EPOLL_INCLUDE_H 3 | 4 | #include "event.h" 5 | 6 | #ifdef HAS_EPOLL 7 | 8 | EVENT *event_epoll_create(int setsize); 9 | 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /c/src/event/event_io_uring.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_IO_URING_INCLUDE_H 2 | #define EVENT_IO_URING_INCLUDE_H 3 | 4 | #include "event.h" 5 | 6 | #ifdef HAS_IO_URING 7 | 8 | EVENT *event_io_uring_create(int size); 9 | 10 | void event_uring_file_close(EVENT *ev, FILE_EVENT *fe); 11 | void event_uring_file_cancel(EVENT *ev, FILE_EVENT *fe_orig, FILE_EVENT *fe); 12 | void event_uring_file_openat(EVENT* ev, FILE_EVENT *fe, int dirfd, 13 | const char* pathname, int flags, mode_t mode); 14 | void event_uring_file_unlink(EVENT *ev, FILE_EVENT *fe, const char *pathname); 15 | 16 | # ifdef HAS_STATX 17 | void event_uring_file_statx(EVENT *ev, FILE_EVENT *fe, int dirfd, 18 | const char *pathname, int flags, unsigned int mask, 19 | struct statx *statxbuf); 20 | # endif 21 | 22 | # ifdef HAS_RENAMEAT2 23 | void event_uring_file_renameat2(EVENT *ev, FILE_EVENT *fe, int olddirfd, 24 | const char *oldpath, int newdirfd, const char *newpath, unsigned flags); 25 | # endif 26 | 27 | void event_uring_mkdirat(EVENT *ev, FILE_EVENT *fe, int dirfd, 28 | const char *pathname, mode_t mode); 29 | void event_uring_splice(EVENT *ev, FILE_EVENT *fe, int fd_in, loff_t off_in, 30 | int fd_out, loff_t off_out, size_t len, unsigned int splice_flags, 31 | unsigned int sqe_flags, __u8 opcode); 32 | 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /c/src/event/event_iocp.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENTS_IOCP_INCLUDE_H 2 | #define EVENTS_IOCP_INCLUDE_H 3 | 4 | #include "event.h" 5 | 6 | #ifdef HAS_IOCP 7 | 8 | EVENT *event_iocp_create(int setsize); 9 | 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /c/src/event/event_kqueue.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_KQUEUE_INCLUDE_H 2 | #define EVENT_KQUEUE_INCLUDE_H 3 | 4 | #include "event.h" 5 | 6 | #ifdef HAS_KQUEUE 7 | 8 | EVENT *event_kqueue_create(int setsize); 9 | 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /c/src/event/event_poll.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_POLL_INCLUDE_H 2 | #define EVENT_POLL_INCLUDE_H 3 | 4 | #include "event.h" 5 | 6 | #ifdef HAS_POLL 7 | 8 | EVENT *event_poll_create(int setsize); 9 | 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /c/src/event/event_select.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_SELECT_INCLUDE_H 2 | #define EVENT_SELECT_INCLUDE_H 3 | 4 | #include "event.h" 5 | 6 | #ifdef HAS_SELECT 7 | 8 | EVENT *event_select_create(int setsize); 9 | 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /c/src/event/event_wmsg.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_WMSG_INCLUDE_H 2 | #define EVENT_WMSG_INCLUDE_H 3 | 4 | #include "event.h" 5 | 6 | #ifdef HAS_WMSG 7 | 8 | EVENT *event_wmsg_create(int setsize); 9 | 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /c/src/fiber/boost/jump_combined_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__i386__) 11 | #include "jump_i386_sysv_macho_gas.S" 12 | #elif defined(__x86_64__) 13 | #include "jump_x86_64_sysv_macho_gas.S" 14 | #elif defined(__ppc__) 15 | #include "jump_ppc32_sysv_macho_gas.S" 16 | #elif defined(__ppc64__) 17 | #include "jump_ppc64_sysv_macho_gas.S" 18 | #else 19 | #error "No arch's" 20 | #endif 21 | -------------------------------------------------------------------------------- /c/src/fiber/boost/jump_gas.S: -------------------------------------------------------------------------------- 1 | // Stub file for universal binary 2 | 3 | #if defined(__APPLE__) 4 | #include "jump_combined_sysv_macho_gas.S" 5 | #elif defined(_WIN32) || defined(__MINGW32__) || defined(__MINGW64__) || defined(__CYGWIN__) || defined(__MSYS__) 6 | #if defined(__x86_64__) 7 | #include "jump_x86_64_ms_pe_gas.asm" 8 | #elif defined(__i386__) 9 | #include "jump_i386_ms_pe_gas.asm" 10 | #endif 11 | #elif defined(__x86_64__) 12 | #include "jump_x86_64_sysv_elf_gas.S" 13 | #elif defined(__i386__) 14 | #include "jump_i386_sysv_elf_gas.S" 15 | #elif defined(__ppc64__) 16 | #include "jump_ppc64_sysv_elf_gas.S" 17 | #elif defined(__ppc__) 18 | #include "jump_ppc32_sysv_elf_gas.S" 19 | #elif defined(__aarch64__) 20 | #include "jump_arm64_aapcs_elf_gas.S" 21 | #elif defined(__arm__) 22 | #include "jump_arm_aapcs_elf_gas.S" 23 | #elif defined(__mips64) 24 | #include "jump_mips64_n64_elf_gas.S" 25 | #elif defined(__mips__) 26 | #include "jump_mips32_o32_elf_gas.S" 27 | #elif defined(__riscv) 28 | #include "jump_riscv64_sysv_elf_gas.S" 29 | #elif defined(__s390x__) 30 | #include "jump_s390x_sysv_elf_gas.S" 31 | #else 32 | #error "No arch's" 33 | #endif 34 | -------------------------------------------------------------------------------- /c/src/fiber/boost/jump_i386_x86_64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__i386__) 11 | #include "jump_i386_sysv_macho_gas.S" 12 | #elif defined(__x86_64__) 13 | #include "jump_x86_64_sysv_macho_gas.S" 14 | #else 15 | #error "No arch's" 16 | #endif 17 | -------------------------------------------------------------------------------- /c/src/fiber/boost/jump_ppc32_ppc64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__ppc__) 11 | #include "jump_ppc32_sysv_macho_gas.S" 12 | #elif defined(__ppc64__) 13 | #include "jump_ppc64_sysv_macho_gas.S" 14 | #else 15 | #error "No arch's" 16 | #endif 17 | -------------------------------------------------------------------------------- /c/src/fiber/boost/jump_ppc64_sysv_xcoff_gas.S: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Copyright Oliver Kowalke 2009. 4 | Distributed under the Boost Software License, Version 1.0. 5 | (See accompanying file LICENSE_1_0.txt or copy at 6 | http://www.boost.org/LICENSE_1_0.txt) 7 | */ 8 | 9 | .align 2 10 | .globl .jump_fcontext 11 | .jump_fcontext: 12 | # reserve space on stack 13 | subi 1, 1, 184 14 | 15 | std 13, 0(1) # save R13 16 | std 14, 8(1) # save R14 17 | std 15, 16(1) # save R15 18 | std 16, 24(1) # save R16 19 | std 17, 32(1) # save R17 20 | std 18, 40(1) # save R18 21 | std 19, 48(1) # save R19 22 | std 20, 56(1) # save R20 23 | std 21, 64(1) # save R21 24 | std 22, 72(1) # save R22 25 | std 23, 80(1) # save R23 26 | std 24, 88(1) # save R24 27 | std 25, 96(1) # save R25 28 | std 26, 104(1) # save R26 29 | std 27, 112(1) # save R27 30 | std 29, 120(1) # save R28 31 | std 29, 128(1) # save R29 32 | std 30, 136(1) # save R30 33 | std 31, 144(1) # save R31 34 | std 3, 152(1) # save hidden 35 | 36 | # save CR 37 | mfcr 0 38 | std 0, 160(1) 39 | # save LR 40 | mflr 0 41 | std 0, 168(1) 42 | # save LR as PC 43 | std 0, 176(1) 44 | 45 | # store RSP (pointing to context-data) in R6 46 | mr 6, 1 47 | 48 | # restore RSP (pointing to context-data) from R4 49 | mr 1, 4 50 | 51 | ld 13, 0(1) # restore R13 52 | ld 14, 8(1) # restore R14 53 | ld 15, 16(1) # restore R15 54 | ld 16, 24(1) # restore R16 55 | ld 17, 32(1) # restore R17 56 | ld 18, 40(1) # restore R18 57 | ld 19, 48(1) # restore R19 58 | ld 20, 56(1) # restore R20 59 | ld 21, 64(1) # restore R21 60 | ld 22, 72(1) # restore R22 61 | ld 23, 80(1) # restore R23 62 | ld 24, 88(1) # restore R24 63 | ld 25, 96(1) # restore R25 64 | ld 26, 104(1) # restore R26 65 | ld 27, 112(1) # restore R27 66 | ld 28, 120(1) # restore R28 67 | ld 29, 128(1) # restore R29 68 | ld 30, 136(1) # restore R30 69 | ld 31, 144(1) # restore R31 70 | ld 3, 152(1) # restore hidden 71 | 72 | # restore CR 73 | ld 0, 160(1) 74 | mtcr 0 75 | # restore LR 76 | ld 0, 168(1) 77 | mtlr 0 78 | 79 | # load PC 80 | ld 0, 176(1) 81 | # restore CTR 82 | mtctr 0 83 | 84 | # adjust stack 85 | addi 1, 1, 184 86 | 87 | # return transfer_t 88 | std 6, 0(3) 89 | std 5, 8(3) 90 | 91 | # jump to context 92 | bctr 93 | -------------------------------------------------------------------------------- /c/src/fiber/boost/make_combined_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__i386__) 11 | #include "make_i386_sysv_macho_gas.S" 12 | #elif defined(__x86_64__) 13 | #include "make_x86_64_sysv_macho_gas.S" 14 | #elif defined(__ppc__) 15 | #include "make_ppc32_sysv_macho_gas.S" 16 | #elif defined(__ppc64__) 17 | #include "make_ppc64_sysv_macho_gas.S" 18 | #else 19 | #error "No arch's" 20 | #endif 21 | -------------------------------------------------------------------------------- /c/src/fiber/boost/make_gas.S: -------------------------------------------------------------------------------- 1 | // Stub file for universal binary 2 | 3 | #if defined(__APPLE__) 4 | #include "make_combined_sysv_macho_gas.S" 5 | #elif defined(_WIN32) || defined(__MINGW32__) || defined(__MINGW64__) || defined(__CYGWIN__) || defined(__MSYS__) 6 | #if defined(__x86_64__) 7 | #include "make_x86_64_ms_pe_gas.asm" 8 | #elif defined(__i386__) 9 | #include "make_i386_ms_pe_gas.asm" 10 | #endif 11 | #elif defined(__x86_64__) 12 | #include "make_x86_64_sysv_elf_gas.S" 13 | #elif defined(__i386__) 14 | #include "make_i386_sysv_elf_gas.S" 15 | #elif defined(__ppc64__) 16 | #include "make_ppc64_sysv_elf_gas.S" 17 | #elif defined(__ppc__) 18 | #include "make_ppc32_sysv_elf_gas.S" 19 | #elif defined(__aarch64__) 20 | #include "make_arm64_aapcs_elf_gas.S" 21 | #elif defined(__arm__) 22 | #include "make_arm_aapcs_elf_gas.S" 23 | #elif defined(__mips64) 24 | #include "make_mips64_n64_elf_gas.S" 25 | #elif defined(__mips__) 26 | #include "make_mips32_o32_elf_gas.S" 27 | #elif defined(__riscv) 28 | #include "make_riscv64_sysv_elf_gas.S" 29 | #elif defined(__s390x__) 30 | #include "make_s390x_sysv_elf_gas.S" 31 | #else 32 | #error "No arch's" 33 | #endif 34 | -------------------------------------------------------------------------------- /c/src/fiber/boost/make_i386_x86_64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__i386__) 11 | #include "make_i386_sysv_macho_gas.S" 12 | #elif defined(__x86_64__) 13 | #include "make_x86_64_sysv_macho_gas.S" 14 | #else 15 | #error "No arch's" 16 | #endif 17 | -------------------------------------------------------------------------------- /c/src/fiber/boost/make_ppc32_ppc64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__ppc__) 11 | #include "make_ppc32_sysv_macho_gas.S" 12 | #elif defined(__ppc64__) 13 | #include "make_ppc64_sysv_macho_gas.S" 14 | #else 15 | #error "No arch's" 16 | #endif 17 | -------------------------------------------------------------------------------- /c/src/fiber/boost/make_ppc64_sysv_xcoff_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | .globl make_fcontext[DS] 8 | .globl .make_fcontext[PR] 9 | .align 2 10 | .csect .make_fcontext[PR], 3 11 | .globl _make_fcontext 12 | #._make_fcontext: 13 | # save return address into R6 14 | mflr 6 15 | 16 | # first arg of make_fcontext() == top address of context-function 17 | # shift address in R3 to lower 16 byte boundary 18 | clrrwi 3, 3, 4 19 | 20 | # reserve space for context-data on context-stack 21 | # including 64 byte of linkage + parameter area (R1 % 16 == 0) 22 | subi 3, 3, 248 23 | 24 | # third arg of make_fcontext() == address of context-function 25 | stw 5, 176(3) 26 | 27 | # set back-chain to zero 28 | li 0, 0 29 | std 0, 184(3) 30 | 31 | # compute address of returned transfer_t 32 | addi 0, 3, 232 33 | mr 4, 0 34 | std 4, 152(3) 35 | 36 | # load LR 37 | mflr 0 38 | # jump to label 1 39 | bl .Label 40 | .Label: 41 | # load LR into R4 42 | mflr 4 43 | # compute abs address of label .L_finish 44 | addi 4, 4, .L_finish - .Label 45 | # restore LR 46 | mtlr 0 47 | # save address of finish as return-address for context-function 48 | # will be entered after context-function returns 49 | stw 4, 168(3) 50 | 51 | # restore return address from R6 52 | mtlr 6 53 | 54 | blr # return pointer to context-data 55 | 56 | .L_finish: 57 | # save return address into R0 58 | mflr 0 59 | # save return address on stack, set up stack frame 60 | stw 0, 8(1) 61 | # allocate stack space, R1 % 16 == 0 62 | stwu 1, -32(1) 63 | 64 | # exit code is zero 65 | li 3, 0 66 | # exit application 67 | bl ._exit 68 | nop 69 | -------------------------------------------------------------------------------- /c/src/fiber/boost/ontop_combined_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__i386__) 11 | #include "ontop_i386_sysv_macho_gas.S" 12 | #elif defined(__x86_64__) 13 | #include "ontop_x86_64_sysv_macho_gas.S" 14 | #elif defined(__ppc__) 15 | #include "ontop_ppc32_sysv_macho_gas.S" 16 | #elif defined(__ppc64__) 17 | #include "ontop_ppc64_sysv_macho_gas.S" 18 | #else 19 | #error "No arch's" 20 | #endif 21 | -------------------------------------------------------------------------------- /c/src/fiber/boost/ontop_i386_x86_64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__i386__) 11 | #include "ontop_i386_sysv_macho_gas.S" 12 | #elif defined(__x86_64__) 13 | #include "ontop_x86_64_sysv_macho_gas.S" 14 | #else 15 | #error "No arch's" 16 | #endif 17 | -------------------------------------------------------------------------------- /c/src/fiber/boost/ontop_ppc32_ppc64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__ppc__) 11 | #include "ontop_ppc32_sysv_macho_gas.S" 12 | #elif defined(__ppc64__) 13 | #include "ontop_ppc64_sysv_macho_gas.S" 14 | #else 15 | #error "No arch's" 16 | #endif 17 | -------------------------------------------------------------------------------- /c/src/fiber/boost/ontop_ppc64_sysv_xcoff_gas.S: -------------------------------------------------------------------------------- 1 | .align 2 2 | .globl .ontop_fcontext 3 | .ontop_fcontext: 4 | # reserve space on stack 5 | subi 1, 1, 184 6 | 7 | std 13, 0(1) # save R13 8 | std 14, 8(1) # save R14 9 | std 15, 16(1) # save R15 10 | std 16, 24(1) # save R16 11 | std 17, 32(1) # save R17 12 | std 18, 40(1) # save R18 13 | std 19, 48(1) # save R19 14 | std 20, 56(1) # save R20 15 | std 21, 64(1) # save R21 16 | std 22, 72(1) # save R22 17 | std 23, 80(1) # save R23 18 | std 24, 88(1) # save R24 19 | std 25, 96(1) # save R25 20 | std 26, 104(1) # save R26 21 | std 27, 112(1) # save R27 22 | std 29, 120(1) # save R28 23 | std 29, 128(1) # save R29 24 | std 30, 136(1) # save R30 25 | std 31, 144(1) # save R31 26 | std 3, 152(1) # save hidden 27 | 28 | # save CR 29 | mfcr 0 30 | std 0, 160(1) 31 | # save LR 32 | mflr 0 33 | std 0, 168(1) 34 | # save LR as PC 35 | std 0, 176(1) 36 | 37 | # store RSP (pointing to context-data) in R7 38 | mr 7, 1 39 | 40 | # restore RSP (pointing to context-data) from R4 41 | mr 1, 4 42 | 43 | ld 13, 0(1) # restore R13 44 | ld 14, 8(1) # restore R14 45 | ld 15, 16(1) # restore R15 46 | ld 16, 24(1) # restore R16 47 | ld 17, 32(1) # restore R17 48 | ld 18, 40(1) # restore R18 49 | ld 19, 48(1) # restore R19 50 | ld 20, 56(1) # restore R20 51 | ld 21, 64(1) # restore R21 52 | ld 22, 72(1) # restore R22 53 | ld 23, 80(1) # restore R23 54 | ld 24, 88(1) # restore R24 55 | ld 25, 96(1) # restore R25 56 | ld 26, 104(1) # restore R26 57 | ld 27, 112(1) # restore R27 58 | ld 28, 120(1) # restore R28 59 | ld 29, 128(1) # restore R29 60 | ld 30, 136(1) # restore R30 61 | ld 31, 144(1) # restore R31 62 | ld 4, 152(1) # restore hidden 63 | 64 | # restore CR 65 | ld 0, 160(1) 66 | mtcr 0 67 | # restore LR 68 | ld 0, 168(1) 69 | mtlr 0 70 | # ignore PC 71 | 72 | # adjust stack 73 | addi 1, 1, 184 74 | 75 | # return transfer_t 76 | std 7, 0(4) 77 | std 5, 8(4) 78 | 79 | # restore CTR 80 | mtctr 6 81 | 82 | # jump to context 83 | bctr 84 | -------------------------------------------------------------------------------- /c/src/fiber/boost_jmp.h: -------------------------------------------------------------------------------- 1 | #ifndef __BOOST_JUMP_INCLUDE_H__ 2 | #define __BOOST_JUMP_INCLUDE_H__ 3 | 4 | typedef void* fcontext_t; 5 | 6 | typedef struct { 7 | fcontext_t fctx; 8 | void *data; 9 | } transfer_t; 10 | 11 | extern transfer_t jump_fcontext(fcontext_t const to, void *vp); 12 | extern fcontext_t make_fcontext(void *sp, size_t size, void (*fn)(transfer_t)); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /c/src/fiber/exp/setjmp.S: -------------------------------------------------------------------------------- 1 | #if defined(__x86_64__) 2 | #include "setjmp_x86_64.S" 3 | #elif defined(__i386__) 4 | #include "setjmp_i386.S" 5 | #elif defined(__aarch64__) 6 | #include "setjmp_aarch64.S" 7 | #elif defined(__arm__) 8 | #include "setjmp_arm.S" 9 | #elif defined(__sparc__) && defined(__arch64__) 10 | #include "setjmp_sparc64.S" 11 | #elif defined(__powerpc__) 12 | #include "setjmp_ppc.S" 13 | #elif defined(__mips__) 14 | #include "setjmp_mips.S" 15 | #elif defined(__s390x__) 16 | #include "setjmp_s390x.S" 17 | #elif defined(__riscv) 18 | #include "setjmp_rv64g.S" 19 | #endif 20 | -------------------------------------------------------------------------------- /c/src/fiber/exp/setjmp_i386.S: -------------------------------------------------------------------------------- 1 | /* 2 | * CDDL HEADER START 3 | * 4 | * The contents of this file are subject to the terms of the 5 | * Common Development and Distribution License (the "License"). 6 | * You may not use this file except in compliance with the License. 7 | * 8 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 | * or http://www.opensolaris.org/os/licensing. 10 | * See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | * 13 | * When distributing Covered Code, include this CDDL HEADER in each 14 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 | * If applicable, add the following below this CDDL HEADER, with the 16 | * fields enclosed by brackets "[]" replaced with your own identifying 17 | * information: Portions Copyright [yyyy] [name of copyright owner] 18 | * 19 | * CDDL HEADER END 20 | */ 21 | 22 | /* 23 | * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. 24 | */ 25 | 26 | #define ENTRY(x) \ 27 | .text; \ 28 | .align 8; \ 29 | .globl x; \ 30 | .type x, @function; \ 31 | x: 32 | 33 | #define SET_SIZE(x) \ 34 | .size x, [.-x] 35 | 36 | /* 37 | * Setjmp and longjmp implement non-local gotos using state vectors 38 | * type label_t. 39 | */ 40 | #ifdef __i386__ 41 | 42 | ENTRY(SETJMP) /* save area is passed in eax */ 43 | movl %ebp, 0(%eax) /* save ebp */ 44 | movl %ebx, 4(%eax) /* save ebx */ 45 | movl %esi, 8(%eax) /* save esi */ 46 | movl %edi, 12(%eax) /* save edi */ 47 | movl %esp, 16(%eax) /* save esp */ 48 | movl (%esp), %ecx /* %eip (return address) */ 49 | movl %ecx, 20(%eax) /* save eip */ 50 | subl %eax, %eax /* return 0 */ 51 | ret 52 | SET_SIZE(SETJMP) 53 | 54 | ENTRY(LONGJMP) /* save area is passed in eax */ 55 | movl 0(%eax), %ebp /* restore ebp */ 56 | movl 4(%eax), %ebx /* restore ebx */ 57 | movl 8(%eax), %esi /* restore esi */ 58 | movl 12(%eax), %edi /* restore edi */ 59 | movl 16(%eax), %esp /* restore esp */ 60 | movl 20(%eax), %ecx /* %eip (return address) */ 61 | addl $4, %esp /* pop ret adr */ 62 | jmp *%ecx /* indirect jump */ 63 | SET_SIZE(LONGJMP) 64 | 65 | #ifdef __ELF__ 66 | .section .note.GNU-stack,"",%progbits 67 | #endif 68 | 69 | #endif /* __i386__ */ 70 | -------------------------------------------------------------------------------- /c/src/fiber/exp/setjmp_s390x.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2014 Rich Felker, et al. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | .global SETJMP 25 | .type SETJMP,@function 26 | SETJMP: 27 | stmg %r6, %r15, 0(%r2) 28 | 29 | std %f8, 10*8(%r2) 30 | std %f9, 11*8(%r2) 31 | std %f10, 12*8(%r2) 32 | std %f11, 13*8(%r2) 33 | std %f12, 14*8(%r2) 34 | std %f13, 15*8(%r2) 35 | std %f14, 16*8(%r2) 36 | std %f15, 17*8(%r2) 37 | 38 | lghi %r2, 0 39 | br %r14 40 | 41 | .global LONGJMP 42 | .type LONGJMP,@function 43 | LONGJMP: 44 | 45 | 1: 46 | lmg %r6, %r15, 0(%r2) 47 | 48 | ld %f8, 10*8(%r2) 49 | ld %f9, 11*8(%r2) 50 | ld %f10, 12*8(%r2) 51 | ld %f11, 13*8(%r2) 52 | ld %f12, 14*8(%r2) 53 | ld %f13, 15*8(%r2) 54 | ld %f14, 16*8(%r2) 55 | ld %f15, 17*8(%r2) 56 | 57 | ltgr %r2, %r3 58 | bnzr %r14 59 | lhi %r2, 1 60 | br %r14 61 | 62 | #ifdef __ELF__ 63 | .section .note.GNU-stack,"",%progbits 64 | #endif 65 | -------------------------------------------------------------------------------- /c/src/fiber/exp/setjmp_x86_64.S: -------------------------------------------------------------------------------- 1 | /* 2 | * CDDL HEADER START 3 | * 4 | * The contents of this file are subject to the terms of the 5 | * Common Development and Distribution License (the "License"). 6 | * You may not use this file except in compliance with the License. 7 | * 8 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 | * or http://www.opensolaris.org/os/licensing. 10 | * See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | * 13 | * When distributing Covered Code, include this CDDL HEADER in each 14 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 | * If applicable, add the following below this CDDL HEADER, with the 16 | * fields enclosed by brackets "[]" replaced with your own identifying 17 | * information: Portions Copyright [yyyy] [name of copyright owner] 18 | * 19 | * CDDL HEADER END 20 | */ 21 | 22 | /* 23 | * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. 24 | */ 25 | 26 | 27 | #define ENTRY(x) \ 28 | .text; \ 29 | .align 8; \ 30 | .globl x; \ 31 | .type x, @function; \ 32 | x: 33 | 34 | #define SET_SIZE(x) \ 35 | .size x, [.-x] 36 | 37 | 38 | /* 39 | * Setjmp and longjmp implement non-local gotos using state vectors 40 | * type label_t. 41 | */ 42 | #ifdef __x86_64__ 43 | 44 | ENTRY(SETJMP) 45 | movq %rsp, 0(%rdi) 46 | movq %rbp, 8(%rdi) 47 | movq %rbx, 16(%rdi) 48 | movq %r12, 24(%rdi) 49 | movq %r13, 32(%rdi) 50 | movq %r14, 40(%rdi) 51 | movq %r15, 48(%rdi) 52 | movq 0(%rsp), %rdx /* return address */ 53 | movq %rdx, 56(%rdi) /* rip */ 54 | xorl %eax, %eax /* return 0 */ 55 | ret 56 | SET_SIZE(SETJMP) 57 | 58 | ENTRY(LONGJMP) 59 | movq 0(%rdi), %rsp 60 | movq 8(%rdi), %rbp 61 | movq 16(%rdi), %rbx 62 | movq 24(%rdi), %r12 63 | movq 32(%rdi), %r13 64 | movq 40(%rdi), %r14 65 | movq 48(%rdi), %r15 66 | movq 56(%rdi), %rdx /* return address */ 67 | movq %rdx, 0(%rsp) 68 | xorl %eax, %eax 69 | incl %eax /* return 1 */ 70 | ret 71 | SET_SIZE(LONGJMP) 72 | 73 | #ifdef __ELF__ 74 | .section .note.GNU-stack,"",%progbits 75 | #endif 76 | 77 | #endif /* __x86_64__ */ 78 | -------------------------------------------------------------------------------- /c/src/fiber/exp_jmp.h: -------------------------------------------------------------------------------- 1 | #ifndef __JMP_INCLUDE_H__ 2 | #define __JMP_INCLUDE_H__ 3 | 4 | #ifdef __linux__ 5 | 6 | # if defined(__i386__) 7 | # define JMP_BUF_CNT 6 8 | # elif defined(__x86_64__) 9 | # define JMP_BUF_CNT 8 10 | # elif defined(__sparc__) && defined(__arch64__) 11 | # define JMP_BUF_CNT 6 12 | # elif defined(__powerpc__) 13 | # define JMP_BUF_CNT 26 14 | # elif defined(__aarch64__) 15 | # define JMP_BUF_CNT 64 16 | # elif defined(__arm__) 17 | # define JMP_BUF_CNT 65 18 | # elif defined(__mips__) 19 | # define JMP_BUF_CNT 12 20 | # elif defined(__s390x__) 21 | # define JMP_BUF_CNT 18 22 | # elif defined(__riscv) 23 | # define JMP_BUF_CNT 64 24 | # else 25 | # define JMP_BUF_CNT 1 26 | # endif 27 | 28 | typedef struct _label_t { long long unsigned val[JMP_BUF_CNT]; } label_t; 29 | extern int SETJMP(label_t *) __attribute__ ((__nothrow__)); 30 | extern void LONGJMP(label_t *) __attribute__((__noreturn__)); 31 | 32 | #endif // __linux__ 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /c/src/fiber/x86_jmp.h: -------------------------------------------------------------------------------- 1 | #ifndef __JMP_DEF_INCLUDE_H__ 2 | #define __JMP_DEF_INCLUDE_H__ 3 | 4 | # if defined(__x86_64__) 5 | # if defined(__AVX__) 6 | # define CLOBBER \ 7 | , "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", \ 8 | "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" 9 | # else 10 | # define CLOBBER 11 | # endif 12 | 13 | // asm(".cfi_undefined rip;\r\n") 14 | # define SETJMP(ctx) ({\ 15 | int ret; \ 16 | asm("lea LJMPRET%=(%%rip), %%rcx\n\t"\ 17 | "xor %%rax, %%rax\n\t"\ 18 | "mov %%rbx, (%%rdx)\n\t"\ 19 | "mov %%rbp, 8(%%rdx)\n\t"\ 20 | "mov %%r12, 16(%%rdx)\n\t"\ 21 | "mov %%rsp, 24(%%rdx)\n\t"\ 22 | "mov %%r13, 32(%%rdx)\n\t"\ 23 | "mov %%r14, 40(%%rdx)\n\t"\ 24 | "mov %%r15, 48(%%rdx)\n\t"\ 25 | "mov %%rcx, 56(%%rdx)\n\t"\ 26 | "mov %%rdi, 64(%%rdx)\n\t"\ 27 | "mov %%rsi, 72(%%rdx)\n\t"\ 28 | "LJMPRET%=:\n\t"\ 29 | : "=a" (ret)\ 30 | : "d" (ctx)\ 31 | : "memory", "rcx", "r8", "r9", "r10", "r11", \ 32 | "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", \ 33 | "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"\ 34 | CLOBBER\ 35 | ); \ 36 | ret; \ 37 | }) 38 | 39 | # define LONGJMP(ctx) \ 40 | asm("movq (%%rax), %%rbx\n\t"\ 41 | "movq 8(%%rax), %%rbp\n\t"\ 42 | "movq 16(%%rax), %%r12\n\t"\ 43 | "movq 24(%%rax), %%rdx\n\t"\ 44 | "movq 32(%%rax), %%r13\n\t"\ 45 | "movq 40(%%rax), %%r14\n\t"\ 46 | "mov %%rdx, %%rsp\n\t"\ 47 | "movq 48(%%rax), %%r15\n\t"\ 48 | "movq 56(%%rax), %%rdx\n\t"\ 49 | "movq 64(%%rax), %%rdi\n\t"\ 50 | "movq 72(%%rax), %%rsi\n\t"\ 51 | "jmp *%%rdx\n\t"\ 52 | : : "a" (ctx) : "rdx" \ 53 | ) 54 | 55 | # elif defined(__i386__) 56 | 57 | # define SETJMP(ctx) ({\ 58 | int ret; \ 59 | asm("movl $LJMPRET%=, %%eax\n\t"\ 60 | "movl %%eax, (%%edx)\n\t"\ 61 | "movl %%ebx, 4(%%edx)\n\t"\ 62 | "movl %%esi, 8(%%edx)\n\t"\ 63 | "movl %%edi, 12(%%edx)\n\t"\ 64 | "movl %%ebp, 16(%%edx)\n\t"\ 65 | "movl %%esp, 20(%%edx)\n\t"\ 66 | "xorl %%eax, %%eax\n\t"\ 67 | "LJMPRET%=:\n\t"\ 68 | : "=a" (ret) : "d" (ctx) : "memory"); \ 69 | ret; \ 70 | }) 71 | 72 | # define LONGJMP(ctx) \ 73 | asm("movl (%%eax), %%edx\n\t"\ 74 | "movl 4(%%eax), %%ebx\n\t"\ 75 | "movl 8(%%eax), %%esi\n\t"\ 76 | "movl 12(%%eax), %%edi\n\t"\ 77 | "movl 16(%%eax), %%ebp\n\t"\ 78 | "movl 20(%%eax), %%esp\n\t"\ 79 | "jmp *%%edx\n\t"\ 80 | : : "a" (ctx) : "edx" \ 81 | ) 82 | 83 | # endif 84 | #endif 85 | -------------------------------------------------------------------------------- /c/src/file_event.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "common.h" 3 | 4 | #include "fiber/libfiber.h" 5 | #include "event.h" 6 | 7 | void file_event_init(FILE_EVENT *fe, socket_t fd) 8 | { 9 | ring_init(&fe->me); 10 | 11 | // XXX: don't set fiber_r/fiber_w here! 12 | // fe->fiber_r = acl_fiber_running(); 13 | // fe->fiber_w = acl_fiber_running(); 14 | 15 | fe->fd = fd; 16 | fe->id = -1; 17 | fe->status = STATUS_NONE; 18 | fe->type = TYPE_NONE; 19 | fe->oper = 0; 20 | fe->mask = 0; 21 | fe->r_proc = NULL; 22 | fe->w_proc = NULL; 23 | 24 | #ifdef HAS_POLL 25 | ring_init(&fe->pfds); 26 | #endif 27 | 28 | #ifdef HAS_IO_URING 29 | memset(&fe->in, 0, sizeof(fe->in)); 30 | memset(&fe->out, 0, sizeof(fe->out)); 31 | memset(&fe->var, 0, sizeof(fe->var)); 32 | memset(&fe->reader_ctx, 0, sizeof(fe->reader_ctx)); 33 | memset(&fe->writer_ctx, 0, sizeof(fe->writer_ctx)); 34 | #endif 35 | fe->r_timeout = -1; 36 | fe->w_timeout = -1; 37 | 38 | #ifdef HAS_IOCP 39 | fe->rbuf = NULL; 40 | fe->rsize = 0; 41 | fe->res = 0; 42 | fe->h_iocp = NULL; 43 | fe->reader = NULL; 44 | fe->writer = NULL; 45 | fe->poller_read = NULL; 46 | fe->poller_write = NULL; 47 | fe->iocp_sock = INVALID_SOCKET; 48 | fe->sock_type = getsocktype(fd); 49 | memset(&fe->var, 0, sizeof(fe->var)); 50 | #endif 51 | 52 | fe->refer = 1; 53 | fe->busy = 0; 54 | } 55 | 56 | FILE_EVENT *file_event_alloc(socket_t fd) 57 | { 58 | FILE_EVENT *fe = (FILE_EVENT *) mem_calloc(1, sizeof(FILE_EVENT)); 59 | file_event_init(fe, fd); 60 | return fe; 61 | } 62 | 63 | static void file_event_free(FILE_EVENT *fe) 64 | { 65 | if (fe->mbox_wsem) { 66 | acl_fiber_sem_free(fe->mbox_wsem); 67 | } 68 | 69 | memset(fe, 0, sizeof(*fe)); 70 | mem_free(fe); 71 | } 72 | 73 | int file_event_refer(FILE_EVENT *fe) 74 | { 75 | return ++fe->refer; 76 | } 77 | 78 | int file_event_unrefer(FILE_EVENT *fe) 79 | { 80 | if (--fe->refer <= 0) { 81 | file_event_free(fe); 82 | return 0; 83 | } else { 84 | return fe->refer; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /c/src/hook/io.h: -------------------------------------------------------------------------------- 1 | #ifndef __FIBER_IO_INCLUDE_H__ 2 | #define __FIBER_IO_INCLUDE_H__ 3 | 4 | #include "fiber/fiber_define.h" 5 | #include "../event.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // in fiber_read.c 12 | ssize_t fiber_recvmsg(FILE_EVENT *fe, struct msghdr *msg, int flags); 13 | ssize_t fiber_recv(FILE_EVENT *fe, void *buf, size_t len, int flags); 14 | ssize_t fiber_recvfrom(FILE_EVENT *fe, void *buf, size_t len, 15 | int flags, struct sockaddr *src_addr, socklen_t *addrlen); 16 | 17 | // in fiber_write.c 18 | ssize_t fiber_send(FILE_EVENT *fe, const void *buf, size_t len, int flags); 19 | ssize_t fiber_sendto(FILE_EVENT *fe, const void *buf, size_t len, 20 | int flags, const struct sockaddr *dest_addr, socklen_t addrlen); 21 | ssize_t fiber_sendmsg(FILE_EVENT *fe, const struct msghdr *msg, int flags); 22 | 23 | #if defined(__linux__) || defined(LINUX2) || defined(__APPLE__) || defined(__FreeBSD__) || defined(MINGW) // SYS_UNIX 24 | 25 | // in fiber_read.c 26 | int fiber_iocp_read(FILE_EVENT *fe, char *buf, int len); 27 | 28 | ssize_t fiber_read(FILE_EVENT *fe, void *buf, size_t count); 29 | ssize_t fiber_readv(FILE_EVENT *fe, const struct iovec *iov, int iovcnt); 30 | 31 | # ifdef HAS_MMSG 32 | ssize_t fiber_recvmmsg(FILE_EVENT *fe, struct mmsghdr *msgvec, 33 | unsigned int vlen, int flags, const struct timespec *timeout); 34 | # endif 35 | 36 | // in fiber_write.c 37 | int fiber_uring_write(FILE_EVENT *fe, const char *buf, int len); 38 | 39 | ssize_t fiber_write(FILE_EVENT *fe, const void *buf, size_t count); 40 | ssize_t fiber_writev(FILE_EVENT *fe, const struct iovec *iov, int iovcnt); 41 | 42 | # ifdef HAS_MMSG 43 | int fiber_sendmmsg(FILE_EVENT *fe, struct mmsghdr *msgvec, unsigned int vlen, 44 | int flags); 45 | # endif 46 | 47 | # if defined(__USE_LARGEFILE64) && !defined(DISABLE_HOOK) 48 | ssize_t fiber_sendfile64(socket_t out_fd, int in_fd, off64_t *offset, size_t count); 49 | # endif 50 | 51 | # ifdef HAS_IO_URING 52 | // in file.c 53 | extern int file_close(EVENT *ev, FILE_EVENT *fe); 54 | 55 | # define CANCEL_NONE 0 56 | # define CANCEL_IO_READ 1 57 | # define CANCEL_IO_WRITE 2 58 | extern int file_cancel(EVENT *ev, FILE_EVENT *fe, int iotype); 59 | extern ssize_t file_sendfile(socket_t out_fd, int in_fd, off64_t *off, size_t cnt); 60 | # endif // HAS_IO_URING 61 | 62 | #endif // SYS_UNIX 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /c/src/hook/socket.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/c/src/hook/socket.c -------------------------------------------------------------------------------- /c/src/stdafx.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | -------------------------------------------------------------------------------- /c/src/sync/sync_timer.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYNC_TIMER_INCLUDE_H__ 2 | #define __SYNC_TIMER_INCLUDE_H__ 3 | 4 | #include "sync_type.h" 5 | 6 | // In sync_timer.c 7 | SYNC_TIMER *sync_timer_get(void); 8 | void sync_timer_wakeup(SYNC_TIMER *waiter, SYNC_OBJ *obj); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /c/src/sync/sync_type.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "common.h" 3 | 4 | #include "fiber.h" 5 | #include "sync_type.h" 6 | 7 | SYNC_OBJ *sync_obj_alloc(int shared) 8 | { 9 | SYNC_OBJ *obj = (SYNC_OBJ*) mem_calloc(1, sizeof(SYNC_OBJ)); 10 | 11 | ring_init(&obj->me); 12 | if (shared) { 13 | obj->atomic = atomic_new(); 14 | atomic_set(obj->atomic, &obj->atomic_value); 15 | atomic_int64_set(obj->atomic, 1); 16 | } 17 | return obj; 18 | } 19 | 20 | static void sync_obj_free(SYNC_OBJ *obj) 21 | { 22 | if (obj->atomic) { 23 | atomic_free(obj->atomic); 24 | } 25 | if (obj->base) { 26 | fbase_event_close(obj->base); 27 | fbase_free(obj->base); 28 | } 29 | mem_free(obj); 30 | } 31 | 32 | unsigned sync_obj_refer(SYNC_OBJ *obj) 33 | { 34 | if (obj->atomic) { 35 | return (unsigned) atomic_int64_add_fetch(obj->atomic, 1); 36 | } 37 | return 1; 38 | } 39 | 40 | unsigned sync_obj_unrefer(SYNC_OBJ *obj) 41 | { 42 | if (obj->atomic) { 43 | long long n; 44 | 45 | if ((n = atomic_int64_add_fetch(obj->atomic, -1)) == 0) { 46 | sync_obj_free(obj); 47 | return 0; 48 | } 49 | return (unsigned) n; 50 | } 51 | 52 | sync_obj_free(obj); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /c/src/sync/sync_type.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYNC_TYPE_INCLUDE_H__ 2 | #define __SYNC_TYPE_INCLUDE_H__ 3 | 4 | typedef struct SYNC_TIMER SYNC_TIMER; 5 | typedef struct SYNC_WAITER SYNC_WAITER; 6 | 7 | struct ACL_FIBER_MUTEX { 8 | RING me; 9 | long owner; 10 | ACL_FIBER *fiber; 11 | unsigned flags; 12 | ARRAY *waiters; 13 | ARRAY *waiting_threads; 14 | pthread_mutex_t lock; 15 | pthread_mutex_t thread_lock; 16 | }; 17 | 18 | struct ACL_FIBER_COND { 19 | RING me; 20 | ARRAY *waiters; 21 | pthread_mutex_t mutex; 22 | }; 23 | 24 | typedef struct SYNC_OBJ { 25 | RING me; 26 | SYNC_TIMER *timer; 27 | ACL_FIBER *fb; 28 | ACL_FIBER_COND *cond; 29 | 30 | int type; 31 | #define SYNC_OBJ_T_FIBER 1 32 | #define SYNC_OBJ_T_THREAD 2 33 | 34 | long tid; 35 | FIBER_BASE *base; 36 | ATOMIC *atomic; 37 | long long atomic_value; 38 | 39 | long long expire; 40 | int delay; 41 | 42 | int status; 43 | #define SYNC_STATUS_TIMEOUT (1 << 0) 44 | } SYNC_OBJ; 45 | 46 | typedef struct SYNC_MSG { 47 | SYNC_OBJ *obj; 48 | 49 | int action; 50 | #define SYNC_ACTION_AWAIT 1 51 | #define SYNC_ACTION_WAKEUP 2 52 | } SYNC_MSG; 53 | 54 | SYNC_OBJ *sync_obj_alloc(int shared); 55 | unsigned sync_obj_refer(SYNC_OBJ *obj); 56 | unsigned sync_obj_unrefer(SYNC_OBJ *obj); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /c/src/sync/sync_waiter.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYNC_WAITER_INCLUDE_H__ 2 | #define __SYNC_WAITER_INCLUDE_H__ 3 | 4 | #include "sync_type.h" 5 | 6 | // In sync_waiter.c 7 | SYNC_WAITER *sync_waiter_get(void); 8 | void sync_waiter_wakeup(SYNC_WAITER *waiter, ACL_FIBER *fb); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /c/xmake.lua: -------------------------------------------------------------------------------- 1 | -- define target: fiber 2 | target("fiber") 3 | 4 | -- set kind: static/shared 5 | set_kind("$(kind)") 6 | 7 | -- add source files 8 | add_files("src/**.c") 9 | 10 | -- add include directories 11 | add_includedirs("src") 12 | add_includedirs("include", {public = true}) 13 | 14 | -- add headers 15 | add_headerfiles("include/(**.h)") 16 | 17 | -- add flags 18 | add_cxflags("-std=gnu99") 19 | add_defines("DUSE_BOOST_JMP") 20 | 21 | -------------------------------------------------------------------------------- /changes.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/changes.txt -------------------------------------------------------------------------------- /cpp/include/fiber/channel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "fiber_cpp_define.hpp" 4 | 5 | struct ACL_CHANNEL; 6 | 7 | namespace acl { 8 | 9 | ACL_CHANNEL *channel_create(int elemsize, int bufsize); 10 | void channel_free(ACL_CHANNEL *c); 11 | int channel_send(ACL_CHANNEL *c, void *v); 12 | int channel_recv(ACL_CHANNEL *c, void *v); 13 | 14 | template 15 | class channel { 16 | public: 17 | channel() { 18 | chan_ = channel_create(sizeof(T), 100); 19 | } 20 | 21 | ~channel() { 22 | channel_free(chan_); 23 | } 24 | 25 | channel& operator << (T& t) { 26 | return put(t); 27 | } 28 | 29 | channel& put(T& t) { 30 | channel_send(chan_, &t); 31 | return *this; 32 | } 33 | 34 | void pop(T& t) { 35 | channel_recv(chan_, &t); 36 | } 37 | 38 | private: 39 | ACL_CHANNEL* chan_; 40 | 41 | channel(const channel&); 42 | void operator=(const channel&); 43 | }; 44 | 45 | } // namespace acl 46 | -------------------------------------------------------------------------------- /cpp/include/fiber/fiber_cond.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "fiber_cpp_define.hpp" 3 | 4 | struct ACL_FIBER_COND; 5 | 6 | namespace acl { 7 | 8 | class fiber_mutex; 9 | 10 | /** 11 | * Conditional variables that can be used between coroutines, threads, and 12 | * between coroutines and threads. 13 | */ 14 | class FIBER_CPP_API fiber_cond { 15 | public: 16 | fiber_cond(); 17 | ~fiber_cond(); 18 | 19 | /** 20 | * Wait for the conditional variable be available. 21 | * @param mutex {fiber_mutex&} 22 | * @param timeout {int} The waiting timeout in milliseconds. 23 | * @return {bool} Return true if avaialbe or return false if timeout. 24 | */ 25 | bool wait(fiber_mutex& mutex, int timeout = -1); 26 | 27 | /** 28 | * Wake up the waiter on the condition variable, and if there are no 29 | * waiters, return directly. The running behavior is similar to that 30 | * of thread condition variables. 31 | * @return {bool} Return true if successful or return false if error. 32 | */ 33 | bool notify(); 34 | 35 | public: 36 | /** 37 | * Return the C object conditional variable. 38 | * @return {ACL_FIBER_COND*} 39 | */ 40 | ACL_FIBER_COND* get_cond() const { 41 | return cond_; 42 | } 43 | 44 | private: 45 | ACL_FIBER_COND* cond_; 46 | 47 | fiber_cond(const fiber_cond&); 48 | void operator=(const fiber_cond&); 49 | }; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /cpp/include/fiber/fiber_cpp_define.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(_WIN32) || defined (_WIN64) 4 | /* typedef intptr_t ssize_t; */ 5 | # ifndef HAS_SSIZE_T 6 | # define HAS_SSIZE_T 7 | /* typedef intptr_t ssize_t; */ 8 | # if defined(_WIN64) 9 | typedef __int64 ssize_t; 10 | # elif defined(_WIN32) 11 | typedef int ssize_t; 12 | # else 13 | typedef long ssize_t; 14 | # endif 15 | # endif 16 | #else 17 | #include 18 | #include 19 | #endif 20 | 21 | #ifdef FIBER_CPP_LIB 22 | # ifndef FIBER_CPP_API 23 | # define FIBER_CPP_API 24 | # endif 25 | #elif defined(FIBER_CPP_DLL) // || defined(_WINDLL) 26 | # if defined(FIBER_CPP_EXPORTS) || defined(fibercpp_EXPORTS) 27 | # ifndef FIBER_CPP_API 28 | # define FIBER_CPP_API __declspec(dllexport) 29 | # endif 30 | # elif !defined(FIBER_CPP_API) 31 | # define FIBER_CPP_API __declspec(dllimport) 32 | # endif 33 | #elif !defined(FIBER_CPP_API) 34 | # define FIBER_CPP_API 35 | #endif 36 | -------------------------------------------------------------------------------- /cpp/include/fiber/fiber_event.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "fiber_cpp_define.hpp" 3 | 4 | struct ACL_FIBER_EVENT; 5 | 6 | namespace acl { 7 | 8 | /** 9 | * An event-mixed lock that can be used between coroutines, between threads, 10 | * and between coroutines and threads to synchronize through event 11 | * waiting/notification. 12 | */ 13 | class FIBER_CPP_API fiber_event { 14 | public: 15 | /** 16 | * The constructor. 17 | * @param use_mutex {bool} When used for event synchronization between 18 | * multiple threads, if the number of threads started is large 19 | * (hundreds or thousands of threads), this flag should be set to true 20 | * so that the internal mutex lock is used for protection when 21 | * synchronizing internal objects to avoid the herd phenomenon. If the 22 | * number of threads started is large but the flag is false, the internal 23 | * atomic number is used for synchronization protection, which can easily 24 | * cause the herd problem. When the number of threads started is large 25 | * (about dozens of threads), this parameter can be set to false to tell 26 | * the internal atomic number to be used for synchronization protection. 27 | * @param fatal_on_error {bool} Whether to crash directly when an internal 28 | * error occurs to facilitate error debugging by developers. 29 | */ 30 | fiber_event(bool use_mutex = true, bool fatal_on_error = true); 31 | ~fiber_event(); 32 | 33 | /** 34 | * Waiting for event lock. 35 | * @return {bool} Return true if locking successfully, otherwise it 36 | * indicates an internal error. 37 | */ 38 | bool wait(); 39 | 40 | /** 41 | * Try waiting for the event lock. 42 | * @return {bool} Return true if locking successfully, otherwise it means 43 | * the lock is currently in use. 44 | */ 45 | bool trywait(); 46 | 47 | /** 48 | * The event lock owner releases the event lock and notifies the waiter. 49 | * @return {bool} Return true if the notification is successful, otherwise 50 | * it indicates an internal error. 51 | */ 52 | bool notify(); 53 | 54 | public: 55 | /** 56 | * Returns the the event object of C version. 57 | * @return {ACL_FIBER_EVENT*} 58 | */ 59 | ACL_FIBER_EVENT* get_event() const { 60 | return event_; 61 | } 62 | 63 | private: 64 | ACL_FIBER_EVENT* event_; 65 | 66 | fiber_event(const fiber_event&); 67 | void operator=(const fiber_event&); 68 | }; 69 | 70 | } // namespace acl 71 | 72 | -------------------------------------------------------------------------------- /cpp/include/fiber/fiber_lock.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "fiber_cpp_define.hpp" 3 | 4 | struct ACL_FIBER_LOCK; 5 | struct ACL_FIBER_RWLOCK; 6 | 7 | namespace acl { 8 | 9 | /** 10 | * mutex lock that can only be used for mutual exclusion between coroutines 11 | * within the same thread. 12 | */ 13 | class FIBER_CPP_API fiber_lock { 14 | public: 15 | fiber_lock(); 16 | ~fiber_lock(); 17 | 18 | /** 19 | * Lock the mutex. 20 | * @return {bool} If lock successfully, return true, or return false. 21 | */ 22 | bool lock(); 23 | 24 | /** 25 | * Try to lock the mutex. 26 | * @return {bool} If lock successfully, return true, or return false 27 | * if the mutex is locked by other coroutine. 28 | */ 29 | bool trylock(); 30 | 31 | /** 32 | * Unlock the mutex and wakeup the waiter. 33 | * @return {bool} If unlock successfully, return true, or return false. 34 | */ 35 | bool unlock(); 36 | 37 | private: 38 | ACL_FIBER_LOCK* lock_; 39 | 40 | fiber_lock(const fiber_lock&); 41 | void operator=(const fiber_lock&); 42 | }; 43 | 44 | /** 45 | * Read/write lock that can only be used for mutual exclusion between 46 | * coroutines within the same thread. 47 | */ 48 | class FIBER_CPP_API fiber_rwlock { 49 | public: 50 | fiber_rwlock(); 51 | ~fiber_rwlock(); 52 | 53 | /** 54 | * Lock in read mode. 55 | */ 56 | void rlock(); 57 | 58 | /** 59 | * Try to lock in read mode. 60 | * @return {bool} If lock successfully, return true, or return false 61 | * if the mutex is locked by other coroutine. 62 | */ 63 | bool tryrlock(); 64 | 65 | /** 66 | * Unlock read mode. 67 | */ 68 | void runlock(); 69 | 70 | /** 71 | * Lock in write mode. 72 | */ 73 | void wlock(); 74 | 75 | /** 76 | * Try to lock in write mode. 77 | * @return {bool} If lock successfully, return true, or return false 78 | * if the mutex is locked by other coroutine. 79 | */ 80 | bool trywlock(); 81 | 82 | /** 83 | * Unlock write mode. 84 | */ 85 | void wunlock(); 86 | 87 | private: 88 | ACL_FIBER_RWLOCK* rwlk_; 89 | 90 | fiber_rwlock(const fiber_rwlock&); 91 | void operator=(const fiber_rwlock&); 92 | }; 93 | 94 | } // namespace acl 95 | -------------------------------------------------------------------------------- /cpp/include/fiber/fiber_mutex_stat.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct ACL_FIBER_MUTEX; 4 | 5 | namespace acl { 6 | 7 | class fiber; 8 | 9 | struct FIBER_CPP_API fiber_mutex_stat { 10 | fiber_mutex_stat() : fb(NULL), waiting(NULL) {} 11 | ~fiber_mutex_stat() {} 12 | 13 | fiber *fb; 14 | ACL_FIBER_MUTEX *waiting; 15 | std::vector holding; 16 | }; 17 | 18 | struct FIBER_CPP_API fiber_mutex_stats { 19 | fiber_mutex_stats() {} 20 | ~fiber_mutex_stats(); 21 | 22 | std::vector stats; 23 | }; 24 | 25 | } // namespace acl 26 | -------------------------------------------------------------------------------- /cpp/include/fiber/fiber_pool.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "fiber_cpp_define.hpp" 3 | 4 | #if defined(USE_CPP11) || __cplusplus >= 201103L 5 | 6 | #include 7 | #include 8 | #include 9 | #include "fiber.hpp" 10 | #include "fiber_sem.hpp" 11 | 12 | namespace acl { 13 | 14 | using task_fn = std::function; 15 | 16 | template 17 | class task_box { 18 | public: 19 | explicit task_box(fiber_sbox2* bx) : box(bx) {} 20 | ~task_box() { delete box; } 21 | 22 | std::shared_ptr fb; 23 | fiber_sbox2 *box = nullptr; 24 | int idx = -1; 25 | int idle = -1; 26 | }; 27 | 28 | class wait_group; 29 | 30 | using fibers_set = std::set, std::owner_less>>; 31 | 32 | class fiber_pool { 33 | public: 34 | fiber_pool(size_t min, size_t max, int idle_ms = -1, size_t box_buf = 500, 35 | size_t stack_size = 128000, bool stack_share = false); 36 | ~fiber_pool(); 37 | 38 | fiber_pool(const fiber_pool&) = delete; 39 | fiber_pool& operator=(const fiber_pool&) = delete; 40 | 41 | template 42 | void exec(Fn&& fn, Args&&... args) { 43 | auto obj = std::bind(std::forward(fn), std::forward(args)...); 44 | task_box* box; 45 | if (box_idle_ > 0) { 46 | box = boxes_idle_[box_idle_ - 1]; 47 | } else { 48 | box = boxes_[next_box_++ % box_count_]; 49 | } 50 | 51 | box->box->push(obj, true); 52 | if (box_buf_ > 0 && box->box->size() >= (size_t) box_buf_) { 53 | fiber::yield(); 54 | } 55 | } 56 | 57 | void stop(); 58 | 59 | public: 60 | size_t get_box_min() const { 61 | return box_min_; 62 | } 63 | 64 | size_t get_box_max() const { 65 | return box_max_; 66 | } 67 | 68 | size_t get_box_count() const { 69 | return box_count_; 70 | } 71 | 72 | size_t get_box_idle() const { 73 | return box_idle_; 74 | } 75 | 76 | size_t get_box_buf() const { 77 | return box_buf_; 78 | } 79 | 80 | private: 81 | wait_group* wg_; 82 | int idle_ms_; 83 | size_t box_buf_; 84 | size_t stack_size_; 85 | bool stack_share_; 86 | 87 | size_t box_min_; 88 | size_t box_max_; 89 | 90 | size_t box_count_ = 0; 91 | size_t next_box_ = 0; 92 | ssize_t box_idle_ = 0; 93 | 94 | task_box **boxes_; 95 | task_box **boxes_idle_; 96 | fibers_set fibers_; 97 | 98 | void fiber_create(size_t count); 99 | void fiber_run(task_box* box); 100 | void running(task_box* box); 101 | }; 102 | 103 | } // namespace acl 104 | 105 | #endif // __cplusplus >= 201103L 106 | -------------------------------------------------------------------------------- /cpp/include/fiber/libfiber.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "fiber.hpp" 4 | #include "fiber_lock.hpp" 5 | #include "fiber_event.hpp" 6 | #include "fiber_mutex.hpp" 7 | #include "fiber_mutex_stat.hpp" 8 | #include "fiber_cond.hpp" 9 | #include "fiber_sem.hpp" 10 | #include "channel.hpp" 11 | #include "fiber_tbox.hpp" 12 | #include "fiber_tbox2.hpp" 13 | #include "go_fiber.hpp" 14 | #include "wait_group.hpp" 15 | #include "fiber_pool.hpp" 16 | -------------------------------------------------------------------------------- /cpp/include/fiber/wait_group.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "fiber_cpp_define.hpp" 3 | 4 | namespace acl { 5 | 6 | template class fiber_tbox; 7 | 8 | class FIBER_CPP_API wait_group { 9 | public: 10 | wait_group(); 11 | ~wait_group(); 12 | 13 | void add(int n); 14 | void done(); 15 | void wait(); 16 | 17 | private: 18 | void* state_; 19 | long long n_; 20 | fiber_tbox* box_; 21 | }; 22 | 23 | } // namespace acl 24 | -------------------------------------------------------------------------------- /cpp/libfiber_cpp.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/cpp/libfiber_cpp.rc -------------------------------------------------------------------------------- /cpp/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/cpp/resource.h -------------------------------------------------------------------------------- /cpp/src/channel.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.hpp" 2 | #include "fiber/channel.hpp" 3 | 4 | namespace acl 5 | { 6 | 7 | ACL_CHANNEL *channel_create(int elemsize, int bufsize) 8 | { 9 | return acl_channel_create(elemsize, bufsize); 10 | } 11 | 12 | void channel_free(ACL_CHANNEL *c) 13 | { 14 | return acl_channel_free(c); 15 | } 16 | 17 | int channel_send(ACL_CHANNEL *c, void *v) 18 | { 19 | return acl_channel_send(c, v); 20 | } 21 | 22 | int channel_recv(ACL_CHANNEL *c, void *v) 23 | { 24 | return acl_channel_recv(c, v); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /cpp/src/detours/detver.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Common version parameters. 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #define _USING_V110_SDK71_ 1 11 | #include "winver.h" 12 | #if 0 13 | #include 14 | #include 15 | #else 16 | #ifndef DETOURS_STRINGIFY 17 | #define DETOURS_STRINGIFY_(x) #x 18 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 19 | #endif 20 | 21 | #define VER_FILEFLAGSMASK 0x3fL 22 | #define VER_FILEFLAGS 0x0L 23 | #define VER_FILEOS 0x00040004L 24 | #define VER_FILETYPE 0x00000002L 25 | #define VER_FILESUBTYPE 0x00000000L 26 | #endif 27 | #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) 28 | -------------------------------------------------------------------------------- /cpp/src/fiber_cond.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.hpp" 2 | #include "fiber/fiber_mutex.hpp" 3 | #include "fiber/fiber_cond.hpp" 4 | 5 | namespace acl { 6 | 7 | fiber_cond::fiber_cond() 8 | { 9 | cond_ = acl_fiber_cond_create(0); 10 | } 11 | 12 | fiber_cond::~fiber_cond() 13 | { 14 | acl_fiber_cond_free(cond_); 15 | } 16 | 17 | bool fiber_cond::wait(fiber_mutex& mutex, int timeout /* = -1 */) 18 | { 19 | ACL_FIBER_MUTEX* m = mutex.get_mutex(); 20 | 21 | if (timeout < 0) { 22 | return acl_fiber_cond_wait(cond_, m) == 0; 23 | } 24 | 25 | if (acl_fiber_cond_timedwait(cond_, m, timeout) == 0) { 26 | return true; 27 | } else { 28 | return false; 29 | } 30 | } 31 | 32 | bool fiber_cond::notify() 33 | { 34 | return acl_fiber_cond_signal(cond_) == 0; 35 | } 36 | 37 | } // namespace acl 38 | 39 | -------------------------------------------------------------------------------- /cpp/src/fiber_event.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.hpp" 2 | #include "fiber/fiber_event.hpp" 3 | 4 | namespace acl { 5 | 6 | fiber_event::fiber_event(bool use_mutex /* = true */, 7 | bool fatal_on_error /* = true */) 8 | { 9 | unsigned flag = use_mutex ? FIBER_FLAG_USE_MUTEX : 0; 10 | if (fatal_on_error) { 11 | flag |= FIBER_FLAG_USE_FATAL; 12 | } 13 | 14 | event_ = acl_fiber_event_create(flag); 15 | } 16 | 17 | fiber_event::~fiber_event() 18 | { 19 | acl_fiber_event_free(event_); 20 | } 21 | 22 | bool fiber_event::wait() 23 | { 24 | return acl_fiber_event_wait(event_) == 0; 25 | } 26 | 27 | bool fiber_event::trywait() 28 | { 29 | return acl_fiber_event_trywait(event_) == 0; 30 | } 31 | 32 | bool fiber_event::notify() 33 | { 34 | return acl_fiber_event_notify(event_) == 0; 35 | } 36 | 37 | } // namespace acl 38 | 39 | -------------------------------------------------------------------------------- /cpp/src/fiber_lock.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.hpp" 2 | #include "fiber/fiber_lock.hpp" 3 | 4 | namespace acl { 5 | 6 | fiber_lock::fiber_lock() 7 | { 8 | lock_ = acl_fiber_lock_create(); 9 | } 10 | 11 | fiber_lock::~fiber_lock() 12 | { 13 | acl_fiber_lock_free(lock_); 14 | } 15 | 16 | bool fiber_lock::lock() 17 | { 18 | acl_fiber_lock_lock(lock_); 19 | return true; 20 | } 21 | 22 | bool fiber_lock::trylock() 23 | { 24 | return acl_fiber_lock_trylock(lock_) == 0; 25 | } 26 | 27 | bool fiber_lock::unlock() 28 | { 29 | acl_fiber_lock_unlock(lock_); 30 | return true; 31 | } 32 | 33 | ////////////////////////////////////////////////////////////////////////////// 34 | 35 | fiber_rwlock::fiber_rwlock() 36 | { 37 | rwlk_ = acl_fiber_rwlock_create(); 38 | } 39 | 40 | fiber_rwlock::~fiber_rwlock() 41 | { 42 | acl_fiber_rwlock_free(rwlk_); 43 | } 44 | 45 | void fiber_rwlock::rlock() 46 | { 47 | acl_fiber_rwlock_rlock(rwlk_); 48 | } 49 | 50 | bool fiber_rwlock::tryrlock() 51 | { 52 | return acl_fiber_rwlock_tryrlock(rwlk_) == 0; 53 | } 54 | 55 | void fiber_rwlock::runlock() 56 | { 57 | acl_fiber_rwlock_runlock(rwlk_); 58 | } 59 | 60 | void fiber_rwlock::wlock() 61 | { 62 | acl_fiber_rwlock_wlock(rwlk_); 63 | } 64 | 65 | bool fiber_rwlock::trywlock() 66 | { 67 | return acl_fiber_rwlock_trywlock(rwlk_) == 0; 68 | } 69 | 70 | void fiber_rwlock::wunlock() 71 | { 72 | acl_fiber_rwlock_wunlock(rwlk_); 73 | } 74 | 75 | } // namespace acl 76 | -------------------------------------------------------------------------------- /cpp/src/fiber_mutex.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.hpp" 2 | #include "fiber/fiber.hpp" 3 | #include "fiber/fiber_mutex.hpp" 4 | 5 | namespace acl { 6 | 7 | fiber_mutex::fiber_mutex(ACL_FIBER_MUTEX *mutex /* NULL */) 8 | { 9 | if (mutex) { 10 | mutex_ = mutex; 11 | mutex_internal_ = NULL; 12 | } else { 13 | mutex_internal_ = mutex_ = acl_fiber_mutex_create(0); 14 | } 15 | } 16 | 17 | fiber_mutex::~fiber_mutex() 18 | { 19 | if (mutex_internal_) { 20 | acl_fiber_mutex_free(mutex_internal_); 21 | } 22 | } 23 | 24 | bool fiber_mutex::lock() 25 | { 26 | acl_fiber_mutex_lock(mutex_); 27 | return true; 28 | } 29 | 30 | bool fiber_mutex::trylock() 31 | { 32 | return acl_fiber_mutex_trylock(mutex_) == 0; 33 | } 34 | 35 | bool fiber_mutex::unlock() 36 | { 37 | acl_fiber_mutex_unlock(mutex_); 38 | return true; 39 | } 40 | 41 | bool fiber_mutex::deadlock(fiber_mutex_stats& out) 42 | { 43 | ACL_FIBER_MUTEX_STATS *stats = acl_fiber_mutex_deadlock(); 44 | 45 | if (stats == NULL) { 46 | return false; 47 | } 48 | 49 | for (size_t i = 0; i < stats->count; i++) { 50 | fiber_mutex_stat stat; 51 | stat.fb = new fiber(stats->stats[i].fiber); 52 | stat.waiting = stats->stats[i].waiting; 53 | 54 | for (size_t j = 0; j < stats->stats[i].count; j++) { 55 | ACL_FIBER_MUTEX* mutex = stats->stats[i].holding[j]; 56 | stat.holding.push_back(mutex); 57 | } 58 | 59 | out.stats.push_back(stat); 60 | } 61 | 62 | acl_fiber_mutex_stats_free(stats); 63 | return true; 64 | } 65 | 66 | static void show(const fiber_mutex_stat& s) 67 | { 68 | printf("fiber-%d:\r\n", fiber::fiber_id(*s.fb)); 69 | fiber::stackshow(*s.fb); 70 | 71 | for (std::vector::const_iterator 72 | cit = s.holding.begin(); cit != s.holding.end(); ++cit) { 73 | printf("Holding mutex=%p\r\n", *cit); 74 | } 75 | printf("Waiting for mutex=%p\r\n", s.waiting); 76 | } 77 | 78 | static void show(const fiber_mutex_stats& ss) 79 | { 80 | for (std::vector::const_iterator 81 | cit = ss.stats.begin(); cit != ss.stats.end(); ++cit) { 82 | 83 | show(*cit); 84 | printf("\r\n"); 85 | } 86 | } 87 | 88 | void fiber_mutex::deadlock_show() 89 | { 90 | fiber_mutex_stats ss; 91 | if (!deadlock(ss)) { 92 | printf("No deadlock happened!\r\n"); 93 | return; 94 | } 95 | 96 | printf("Deadlock happened!\r\n"); 97 | show(ss); 98 | } 99 | 100 | } // namespace acl 101 | -------------------------------------------------------------------------------- /cpp/src/fiber_mutex_stat.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.hpp" 2 | #include "fiber/fiber.hpp" 3 | #include "fiber/fiber_mutex.hpp" 4 | #include "fiber/fiber_mutex_stat.hpp" 5 | 6 | namespace acl { 7 | 8 | fiber_mutex_stats::~fiber_mutex_stats() 9 | { 10 | for (std::vector::iterator it = stats.begin(); 11 | it != stats.end(); ++it) { 12 | delete (*it).fb; 13 | } 14 | } 15 | 16 | } // namespace acl 17 | -------------------------------------------------------------------------------- /cpp/src/fiber_sem.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.hpp" 2 | #include "fiber/fiber_sem.hpp" 3 | 4 | namespace acl { 5 | 6 | fiber_sem::fiber_sem(size_t max, fiber_sem_attr_t attr) 7 | { 8 | unsigned flags = 0; 9 | 10 | if (attr & fiber_sem_t_async) { 11 | flags |= ACL_FIBER_SEM_F_ASYNC; 12 | } 13 | 14 | sem_ = acl_fiber_sem_create2((int) max, flags); 15 | } 16 | 17 | fiber_sem::fiber_sem(size_t max, size_t buf) 18 | { 19 | sem_ = acl_fiber_sem_create3((int) max, (int) buf, 0); 20 | } 21 | 22 | fiber_sem::~fiber_sem() 23 | { 24 | acl_fiber_sem_free(sem_); 25 | } 26 | 27 | int fiber_sem::wait(int ms) 28 | { 29 | return acl_fiber_sem_timed_wait(sem_, ms); 30 | } 31 | 32 | int fiber_sem::trywait() 33 | { 34 | return acl_fiber_sem_trywait(sem_); 35 | } 36 | 37 | int fiber_sem::post() 38 | { 39 | return acl_fiber_sem_post(sem_); 40 | } 41 | 42 | size_t fiber_sem::num() const 43 | { 44 | return (size_t) acl_fiber_sem_num(sem_); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /cpp/src/stdafx.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.hpp" 2 | -------------------------------------------------------------------------------- /cpp/src/stdafx.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "fiber/libfiber.h" 4 | #include "../../c/src/common/msg.h" 5 | 6 | #define FIBER_DEBUG_MIN 71 7 | #define FIBER_DEBUG_KEEPER (FIBER_DEBUG_MIN + 1) 8 | -------------------------------------------------------------------------------- /cpp/src/wait_group.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.hpp" 2 | #include 3 | #include "../../c/src/common/atomic.h" 4 | #include "fiber/fiber_tbox.hpp" 5 | #include "fiber/wait_group.hpp" 6 | 7 | namespace acl { 8 | 9 | wait_group::wait_group() 10 | { 11 | box_ = new acl::fiber_tbox; 12 | state_ = (void*) atomic_new(); 13 | n_ = 0; 14 | 15 | atomic_set((ATOMIC*) state_, &n_); 16 | atomic_int64_set((ATOMIC*) state_, n_); 17 | } 18 | 19 | wait_group::~wait_group() 20 | { 21 | delete box_; 22 | atomic_free((ATOMIC*) state_); 23 | } 24 | 25 | void wait_group::add(int n) 26 | { 27 | long long state = atomic_int64_add_fetch((ATOMIC*) state_, 28 | (long long) n << 32); 29 | 30 | // The high 32 bits store the number of tasks. 31 | int c = (int)(state >> 32); 32 | 33 | // The low 32 bits store the number of waiters. 34 | unsigned w = (unsigned) state; 35 | 36 | // count must be >= 0. 37 | if (c < 0){ 38 | msg_fatal("Negative wait_group counter"); 39 | } 40 | 41 | if (w != 0 && n > 0 && c == n){ 42 | msg_fatal("Add called concurrently with wait"); 43 | } 44 | 45 | if (c > 0 || w == 0) { 46 | return; 47 | } 48 | 49 | // Check if the state has been changed. 50 | if (atomic_int64_fetch_add((ATOMIC*) state_, 0) != state) { 51 | msg_fatal("Add called concurrently with wait"); 52 | } 53 | 54 | // The count should be zero, so clear state and wakeup all the waiters. 55 | atomic_int64_set((ATOMIC*) state_, 0); 56 | 57 | for (size_t i = 0; i < w; i++) { 58 | box_->push(NULL); 59 | } 60 | } 61 | 62 | void wait_group::done() 63 | { 64 | add(-1); 65 | } 66 | 67 | void wait_group::wait() 68 | { 69 | for(;;) { 70 | long long state = atomic_int64_fetch_add((ATOMIC*) state_, 0); 71 | int c = (int) (state >> 32); 72 | 73 | // Return if no tasks. 74 | if (c == 0) { 75 | return; 76 | } 77 | 78 | // Increase the number of waiters, or get state again if failed. 79 | if (atomic_int64_cas((ATOMIC*) state_, state, state + 1) == state) { 80 | bool found; 81 | (void) box_->pop(-1, &found); 82 | assert(found); 83 | if(atomic_int64_fetch_add((ATOMIC*) state_, 0) == 0) { 84 | return; 85 | } 86 | 87 | msg_fatal("Reused before previous wait has returned"); 88 | } 89 | } 90 | } 91 | 92 | } // namespace acl 93 | -------------------------------------------------------------------------------- /cpp/src/winapi_hook.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | bool winapi_hook(); 4 | 5 | -------------------------------------------------------------------------------- /cpp/xmake.lua: -------------------------------------------------------------------------------- 1 | -- define target: fiber_cpp 2 | target("fiber_cpp") 3 | 4 | -- set kind: static/shared 5 | set_kind("$(kind)") 6 | 7 | -- add deps: fiber, acl 8 | add_deps("fiber", "acl_cpp", "acl") 9 | 10 | -- add source files 11 | add_files("src/**.cpp") 12 | 13 | -- add include directories 14 | add_includedirs("src") 15 | add_includedirs("include", {public = true}) 16 | 17 | -- add headers 18 | add_headerfiles("include/(**.h)", "include/(**.hpp)") 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /doc/benchmark.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/doc/benchmark.pptx -------------------------------------------------------------------------------- /fiber.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /res/benchmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/res/benchmark.png -------------------------------------------------------------------------------- /res/winecho.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/res/winecho.png -------------------------------------------------------------------------------- /samples/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @(cd c; make) 3 | @(cd cpp; make) 4 | @(cd cxx; make) 5 | 6 | clean: 7 | @(cd c; make clean) 8 | @(cd cpp; make clean) 9 | @(cd cxx; make clean) 10 | -------------------------------------------------------------------------------- /samples/c/Makefile: -------------------------------------------------------------------------------- 1 | .PHONEY = all clean cl rebuild rb 2 | 3 | all: 4 | @(cd fiber; make) 5 | @(cd server; make) 6 | @(cd client; make) 7 | @(cd event; make) 8 | @(cd sleep; make) 9 | @(cd poll; make) 10 | @(cd threads; make) 11 | @(cd dns; make) 12 | 13 | clean cl: 14 | @(cd fiber; make clean) 15 | @(cd server; make clean) 16 | @(cd client; make clean) 17 | @(cd event; make clean) 18 | @(cd sleep; make clean) 19 | @(cd poll; make clean) 20 | @(cd threads; make clean) 21 | @(cd dns; make clean) 22 | 23 | rebuild rb: cl all 24 | -------------------------------------------------------------------------------- /samples/c/WinEchod/Client.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Client.h" 3 | 4 | CClient::CClient(socket_t sock) 5 | : m_sock(sock) 6 | { 7 | } 8 | 9 | CClient::~CClient(void) 10 | { 11 | acl_fiber_close(m_sock); 12 | } 13 | 14 | void CClient::Run(void) 15 | { 16 | char buf[1024]; 17 | int n = 0; 18 | 19 | while (true) 20 | { 21 | int ret = acl_fiber_recv(m_sock, buf, sizeof(buf) - 1, 0); 22 | if (ret <= 0) 23 | { 24 | int err = acl_fiber_last_error(); 25 | printf("recv error: %s, %d, n=%d\r\n", 26 | acl_fiber_last_serror(), err, n); 27 | break; 28 | } 29 | buf[ret] = 0; 30 | //printf("recv=%d, [%s]\r\n", ret, buf); 31 | if (acl_fiber_send(m_sock, buf, ret, 0) == -1) 32 | { 33 | int err = acl_fiber_last_error(); 34 | printf("write error %s, %d, n = %d\r\n", 35 | acl_fiber_last_serror(), err, n); 36 | break; 37 | } 38 | n++; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /samples/c/WinEchod/Client.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CClient 4 | { 5 | public: 6 | CClient(socket_t sock); 7 | ~CClient(void); 8 | 9 | void Run(void); 10 | 11 | private: 12 | socket_t m_sock; 13 | }; 14 | -------------------------------------------------------------------------------- /samples/c/WinEchod/Connect.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Resource.h" 3 | #include "WinEchodDlg.h" 4 | #include "afxdialogex.h" 5 | #include "Connect.h" 6 | 7 | CConnect::CConnect(CWinEchodDlg& hWin, const char* serverIP, 8 | int serverPort, int count) 9 | : m_hWin(hWin) 10 | , m_serverPort(serverPort) 11 | , m_count(count) 12 | { 13 | size_t len = strlen(serverIP); 14 | if (len > sizeof(m_serverIP) - 1) 15 | len = sizeof(m_serverIP) - 1; 16 | memcpy(m_serverIP, serverIP, len); 17 | m_serverIP[len] = 0; 18 | } 19 | 20 | CConnect::~CConnect(void) 21 | { 22 | } 23 | 24 | void CConnect::Run(void) 25 | { 26 | socket_t conn = socket_connect(m_serverIP, m_serverPort); 27 | 28 | if (conn == INVALID_SOCKET) 29 | printf("connect %s:%d error %s\r\n", 30 | m_serverIP, m_serverPort, acl_fiber_last_serror()); 31 | else 32 | { 33 | doEcho(conn); 34 | acl_fiber_close(conn); 35 | } 36 | 37 | m_hWin.OnFiberConnectExit(); 38 | } 39 | 40 | void CConnect::doEcho(socket_t sock) 41 | { 42 | char buf[1024]; 43 | const char* s = "hello world\r\n"; 44 | int i; 45 | for (i = 0; i < m_count; i++) 46 | { 47 | if (acl_fiber_send(sock, s, strlen(s), 0) < 0) 48 | { 49 | printf("send error %s\r\n", acl_fiber_last_serror()); 50 | break; 51 | } 52 | int n = acl_fiber_recv(sock, buf, sizeof(buf) - 1, 0); 53 | if (n <= 0) 54 | { 55 | printf("read error %s\r\n", acl_fiber_last_serror()); 56 | break; 57 | } 58 | //buf[n] = 0; 59 | //printf("%s\r\n", buf); 60 | } 61 | printf("Echo over, fd=%u, i=%d\r\n", sock, i); 62 | } 63 | -------------------------------------------------------------------------------- /samples/c/WinEchod/Connect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CWinEchodDlg; 4 | 5 | class CConnect 6 | { 7 | public: 8 | CConnect(CWinEchodDlg& hWin, const char* ip, int port, int count); 9 | ~CConnect(void); 10 | 11 | void Run(void); 12 | 13 | private: 14 | CWinEchodDlg& m_hWin; 15 | char m_serverIP[128]; 16 | int m_serverPort; 17 | int m_count; 18 | 19 | void doEcho(socket_t sock); 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /samples/c/WinEchod/Listener.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Client.h" 3 | #include "Listener.h" 4 | 5 | CListener::CListener(socket_t sock) 6 | : m_listenfd(sock) 7 | { 8 | } 9 | 10 | CListener::~CListener(void) 11 | { 12 | acl_fiber_close(m_listenfd); 13 | } 14 | 15 | static void fiber_client(ACL_FIBER* fb, void* ctx) 16 | { 17 | CClient* conn = (CClient*) ctx; 18 | conn->Run(); 19 | delete conn; 20 | } 21 | 22 | void CListener::Run(void) 23 | { 24 | printf("listener fiber run ...\r\n"); 25 | acl_fiber_delay(1000); 26 | printf("wakeup now\r\n"); 27 | 28 | int n = 0; 29 | while (true) 30 | { 31 | socket_t sock = acl_fiber_accept(m_listenfd, NULL, NULL); 32 | if (sock == INVALID_SOCKET) 33 | { 34 | printf("accept error %s\r\n", acl_fiber_last_serror()); 35 | break; 36 | } 37 | printf("accept one connection, sock=%d, n=%d\r\n", sock, ++n); 38 | CClient* conn = new CClient(sock); 39 | acl_fiber_create(fiber_client, conn, 128000); 40 | } 41 | 42 | printf("listening stopped!\r\n"); 43 | } 44 | -------------------------------------------------------------------------------- /samples/c/WinEchod/Listener.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CListener 4 | { 5 | public: 6 | CListener(socket_t sock); 7 | ~CListener(void); 8 | 9 | void Run(void); 10 | 11 | private: 12 | socket_t m_listenfd; 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /samples/c/WinEchod/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | MICROSOFT 基础类库 : WinEchod 项目概述 3 | =============================================================================== 4 | 5 | 应用程序向导已为您创建了此 WinEchod 应用程序。此应用程序不仅演示 Microsoft 基础类的基本使用方法,还可作为您编写应用程序的起点。 6 | 7 | 本文件概要介绍组成 WinEchod 应用程序的每个文件的内容。 8 | 9 | WinEchod.vcxproj 10 | 这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。 11 | 12 | WinEchod.vcxproj.filters 13 | 这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。 14 | 15 | WinEchod.h 16 | 这是应用程序的主头文件。 17 | 其中包括其他项目特定的标头(包括 Resource.h),并声明 CWinEchodApp 应用程序类。 18 | 19 | WinEchod.cpp 20 | 这是包含应用程序类 CWinEchodApp 的主应用程序源文件。 21 | 22 | WinEchod.rc 23 | 这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。此文件可以直接在 Microsoft Visual C++ 中进行编辑。项目资源包含在 2052 中。 24 | 25 | res\WinEchod.ico 26 | 这是用作应用程序图标的图标文件。此图标包括在主资源文件 WinEchod.rc 中。 27 | 28 | res\WinEchod.rc2 29 | 此文件包含不在 Microsoft Visual C++ 中进行编辑的资源。您应该将不可由资源编辑器编辑的所有资源放在此文件中。 30 | 31 | 32 | ///////////////////////////////////////////////////////////////////////////// 33 | 34 | 应用程序向导创建一个对话框类: 35 | 36 | WinEchodDlg.h、WinEchodDlg.cpp - 对话框 37 | 这些文件包含 CWinEchodDlg 类。此类定义应用程序的主对话框的行为。对话框模板包含在 WinEchod.rc 中,该文件可以在 Microsoft Visual C++ 中编辑。 38 | 39 | ///////////////////////////////////////////////////////////////////////////// 40 | 41 | 其他功能: 42 | 43 | Windows 套接字 44 | 应用程序包含对通过 TCP/IP 网络建立通信的支持。 45 | 46 | ///////////////////////////////////////////////////////////////////////////// 47 | 48 | 其他标准文件: 49 | 50 | StdAfx.h, StdAfx.cpp 51 | 这些文件用于生成名为 WinEchod.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。 52 | 53 | Resource.h 54 | 这是标准头文件,可用于定义新的资源 ID。Microsoft Visual C++ 将读取并更新此文件。 55 | 56 | WinEchod.manifest 57 | Windows XP 使用应用程序清单文件来描述特定版本的并行程序集的应用程序依赖项。加载程序使用这些信息来从程序集缓存中加载相应的程序集,并保护其不被应用程序访问。应用程序清单可能会包含在内,以作为与应用程序可执行文件安装在同一文件夹中的外部 .manifest 文件进行重新分发,它还可能以资源的形式包含在可执行文件中。 58 | ///////////////////////////////////////////////////////////////////////////// 59 | 60 | 其他注释: 61 | 62 | 应用程序向导使用“TODO:”来指示应添加或自定义的源代码部分。 63 | 64 | 如果应用程序使用共享 DLL 中的 MFC,您将需要重新分发 MFC DLL。如果应用程序所使用的语言与操作系统的区域设置不同,则还需要重新分发相应的本地化资源 mfc110XXX.DLL。 65 | 有关上述话题的更多信息,请参见 MSDN 文档中有关重新分发 Visual C++ 应用程序的部分。 66 | 67 | ///////////////////////////////////////////////////////////////////////////// 68 | -------------------------------------------------------------------------------- /samples/c/WinEchod/Sleep.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Sleep.h" 3 | 4 | CSleep::CSleep(void) 5 | { 6 | } 7 | 8 | CSleep::~CSleep(void) 9 | { 10 | } 11 | 12 | void CSleep::Run(void) 13 | { 14 | printf("timer fiber-%d created\r\n", acl_fiber_self()); 15 | for (int i = 0; i < 5; i++) 16 | { 17 | acl_fiber_delay(1000); 18 | printf("fiber-%d wakeup\r\n", acl_fiber_self()); 19 | } 20 | 21 | printf("sleep fiber exit now\r\n"); 22 | } 23 | -------------------------------------------------------------------------------- /samples/c/WinEchod/Sleep.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class CSleep 3 | { 4 | public: 5 | CSleep(void); 6 | ~CSleep(void); 7 | 8 | void Run(void); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /samples/c/WinEchod/WinEchod.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/c/WinEchod/WinEchod.cpp -------------------------------------------------------------------------------- /samples/c/WinEchod/WinEchod.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/c/WinEchod/WinEchod.h -------------------------------------------------------------------------------- /samples/c/WinEchod/WinEchod.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/c/WinEchod/WinEchod.rc -------------------------------------------------------------------------------- /samples/c/WinEchod/WinEchodDlg.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/c/WinEchod/WinEchodDlg.h -------------------------------------------------------------------------------- /samples/c/WinEchod/res/WinEchod.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/c/WinEchod/res/WinEchod.ico -------------------------------------------------------------------------------- /samples/c/WinEchod/res/WinEchod.rc2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/c/WinEchod/res/WinEchod.rc2 -------------------------------------------------------------------------------- /samples/c/WinEchod/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/c/WinEchod/resource.h -------------------------------------------------------------------------------- /samples/c/WinEchod/stdafx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/c/WinEchod/stdafx.cpp -------------------------------------------------------------------------------- /samples/c/WinEchod/stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/c/WinEchod/stdafx.h -------------------------------------------------------------------------------- /samples/c/WinEchod/targetver.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/c/WinEchod/targetver.h -------------------------------------------------------------------------------- /samples/c/client/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = client 3 | -------------------------------------------------------------------------------- /samples/c/client/client_vc2012.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 29 | 30 | 头文件 31 | 32 | 33 | 头文件 34 | 35 | 36 | -------------------------------------------------------------------------------- /samples/c/client/client_vc2013.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 29 | 30 | 头文件 31 | 32 | 33 | 头文件 34 | 35 | 36 | -------------------------------------------------------------------------------- /samples/c/client/client_vc2015.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 29 | 30 | 头文件 31 | 32 | 33 | 头文件 34 | 35 | 36 | -------------------------------------------------------------------------------- /samples/c/client/valgrind.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #valgrind --tool=memcheck --leak-check=yes --leak-check=full --show-reachable=yes --max-stackframe=3426305034400000 -v ./fiber -n 10 -m 20 4 | valgrind --tool=memcheck --leak-check=yes --leak-check=full --show-reachable=yes -v ./client -c 100 -n 100 5 | -------------------------------------------------------------------------------- /samples/c/dns/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = dns 3 | -------------------------------------------------------------------------------- /samples/c/dns/t.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./dns "www.qiyi.com" 4 | 5 | echo "" 6 | 7 | ./dns "m.mo.mm,aaa.aaa.aaa,abc.abc.a,www.ccc.ccc,www.263.net,www.baidu.com" 8 | 9 | echo "" 10 | sleep 1 11 | 12 | ./dns "m.mo.mm,aaa.aaa.aaa,abc.abc.a,www.ccc.ccc,www.263.net,www.baidu.com" 13 | -------------------------------------------------------------------------------- /samples/c/event/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = event 3 | -------------------------------------------------------------------------------- /samples/c/event/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "fiber/libfiber.h" 6 | 7 | static int __nthreads = 2; 8 | static int __nloop = 1000000; 9 | static int __delay = 0; 10 | 11 | static long long __counter = 0; 12 | 13 | static void *thread_main(void *ctx) 14 | { 15 | ACL_FIBER_EVENT *ev = (ACL_FIBER_EVENT *) ctx; 16 | int i; 17 | 18 | for (i = 0; i < __nloop; i++) { 19 | if (acl_fiber_event_wait(ev) == -1) 20 | abort(); 21 | if (__delay > 0) 22 | usleep(__delay * 1000); 23 | __counter++; 24 | if (acl_fiber_event_notify(ev) == -1) 25 | abort(); 26 | } 27 | 28 | return NULL; 29 | }; 30 | 31 | ////////////////////////////////////////////////////////////////////////////// 32 | 33 | static void usage(const char* procname) 34 | { 35 | printf("usage: %s -h [help]\r\n" 36 | " -t nthreads[default: 2]\r\n" 37 | " -n nloop[default: 1000000]\r\n" 38 | " -d delay[default: 100 ms]\r\n", 39 | procname); 40 | } 41 | 42 | int main(int argc, char *argv[]) 43 | { 44 | int ch, i; 45 | ACL_FIBER_EVENT *event = acl_fiber_event_create(FIBER_FLAG_USE_MUTEX); 46 | #define MAX_THREADS 100 47 | pthread_t threads[MAX_THREADS]; 48 | 49 | while ((ch = getopt(argc, argv, "ht:n:d:")) > 0) { 50 | switch (ch) { 51 | case 'h': 52 | usage(argv[0]); 53 | return 0; 54 | case 't': 55 | __nthreads = atoi(optarg); 56 | if (__nthreads > MAX_THREADS) 57 | __nthreads = MAX_THREADS; 58 | break; 59 | case 'n': 60 | __nloop = atoi(optarg); 61 | break; 62 | case 'd': 63 | __delay = atoi(optarg); 64 | break; 65 | default: 66 | break; 67 | } 68 | } 69 | 70 | for (i = 0; i < __nthreads; i++) { 71 | pthread_create(&threads[i], NULL, thread_main, event); 72 | } 73 | 74 | for (i = 0; i < __nthreads; i++) { 75 | pthread_join(threads[i], NULL); 76 | } 77 | 78 | acl_fiber_event_free(event); 79 | 80 | printf("all over, thread=%d, nloop=%d, counter=%lld\r\n", 81 | __nthreads, __nloop, __counter); 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /samples/c/fiber/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = fiber 3 | -------------------------------------------------------------------------------- /samples/c/fiber/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "fiber/libfiber.h" 5 | 6 | #include "../util.h" 7 | 8 | #define FIBER_STACK_SIZE 128000 9 | 10 | static void fiber1(ACL_FIBER *fb, void *ctx) { 11 | int i = *((int*) ctx); 12 | 13 | (void) fb; 14 | free(ctx); 15 | 16 | printf("fiber-%d running, i=%d\r\n", acl_fiber_self(), i); 17 | } 18 | 19 | static void schedule_one(void) { 20 | int i; 21 | for (i = 0; i < 10; i++) { 22 | int *ctx = malloc(sizeof(int)); 23 | *ctx = i; 24 | acl_fiber_create(fiber1, ctx, FIBER_STACK_SIZE); 25 | } 26 | 27 | acl_fiber_schedule(); 28 | } 29 | 30 | static void schedule_two(void) { 31 | int i; 32 | 33 | acl_fiber_schedule_init(1); 34 | 35 | for (i = 0; i < 10; i++) { 36 | int *ctx = malloc(sizeof(int)); 37 | *ctx = i; 38 | acl_fiber_create(fiber1, ctx, FIBER_STACK_SIZE); 39 | } 40 | } 41 | 42 | struct FIBER_CTX { 43 | int nloop; 44 | long long count; 45 | }; 46 | 47 | static void fiber2(ACL_FIBER *fb, void *ctx) { 48 | struct FIBER_CTX *fc = (struct FIBER_CTX *) ctx; 49 | int i; 50 | (void) fb; 51 | 52 | for (i = 0; i < fc->nloop; i++) { 53 | if (i < 5) { 54 | printf("fiber-%d, i=%d\r\n", acl_fiber_self(), i); 55 | } 56 | ++fc->count; 57 | acl_fiber_yield(); 58 | } 59 | } 60 | 61 | static void schedule_bench(int nfiber, int nloop) { 62 | struct timeval begin, end; 63 | struct FIBER_CTX fc; 64 | int i; 65 | 66 | fc.nloop = nloop; 67 | fc.count = 0; 68 | 69 | acl_fiber_schedule_init(0); 70 | gettimeofday(&begin, NULL); 71 | 72 | for (i = 0; i < nfiber; i++) { 73 | acl_fiber_create(fiber2, &fc, FIBER_STACK_SIZE); 74 | } 75 | 76 | acl_fiber_schedule(); 77 | 78 | gettimeofday(&end, NULL); 79 | 80 | show_speed(&begin, &end, fc.count); 81 | } 82 | 83 | static void usage(const char* procname) { 84 | printf("usage: %s -h [help] -c fibers -n loop\r\n", procname); 85 | } 86 | 87 | int main(int argc, char* argv[]) { 88 | int ch, nfiber = 10, nloop = 1000000; 89 | 90 | while ((ch = getopt(argc, argv, "hc:n:")) > 0) { 91 | switch (ch) { 92 | case 'h': 93 | usage(argv[0]); 94 | return 0; 95 | case 'c': 96 | nfiber = atoi(optarg); 97 | break; 98 | case 'n': 99 | nloop = atoi(optarg); 100 | break; 101 | default: 102 | break; 103 | } 104 | } 105 | 106 | printf("schedule one\r\n"); 107 | schedule_one(); 108 | 109 | printf("\r\n"); 110 | printf("schedule two\r\n"); 111 | schedule_two(); 112 | 113 | printf("\r\n"); 114 | schedule_bench(nfiber, nloop); 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /samples/c/getaddrinfo/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = getaddrinfo 3 | -------------------------------------------------------------------------------- /samples/c/getaddrinfo/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "fiber/libfiber.h" 8 | 9 | static void show(const char *name, const struct addrinfo *res) { 10 | printf("name=%s, canonname=%s\r\n", name, res->ai_canonname); 11 | 12 | for (; res != NULL; res = res->ai_next) { 13 | char ip[128]; 14 | const void *addr; 15 | 16 | if (res->ai_family == PF_INET) { 17 | const struct sockaddr_in *in = 18 | (const struct sockaddr_in *) res->ai_addr; 19 | addr = &in->sin_addr; 20 | 21 | } else if (res->ai_family == PF_INET6) { 22 | const struct sockaddr_in6 *in6 = 23 | (const struct sockaddr_in6 *) res->ai_addr; 24 | addr = &in6->sin6_addr; 25 | } else { 26 | continue; 27 | } 28 | 29 | if (inet_ntop(res->ai_family, addr, ip, sizeof(ip))) { 30 | printf(" ip=%s\r\n", ip); 31 | } 32 | } 33 | } 34 | 35 | static void lookup(ACL_FIBER *fiber, void *ctx) { 36 | char *name = (char *) ctx; 37 | struct addrinfo hints, *res; 38 | int ret; 39 | 40 | (void) fiber; // avoid compiler warning 41 | 42 | memset(&hints, 0, sizeof(hints)); 43 | hints.ai_family = PF_UNSPEC; 44 | hints.ai_socktype = SOCK_STREAM; 45 | hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; 46 | 47 | ret = getaddrinfo(name, "80", &hints, &res); 48 | 49 | if (ret != 0) { 50 | printf("getaddrinfo error %s, name=%s\r\n", 51 | gai_strerror(ret), name); 52 | } else { 53 | show(name, res); 54 | freeaddrinfo(res); 55 | } 56 | free(name); 57 | } 58 | 59 | int main(void) { 60 | char *name1 = strdup("www.iqiyi.com"); 61 | char *name2 = strdup("www.baidu.com"); 62 | 63 | acl_fiber_create(lookup, name1, 128000); 64 | acl_fiber_create(lookup, name2, 128000); 65 | 66 | acl_fiber_schedule(); 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /samples/c/getopt.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Newsgroups: mod.std.unix 4 | Subject: public domain AT&T getopt source 5 | Date: 3 Nov 85 19:34:15 GMT 6 | 7 | Here's something you've all been waiting for: the AT&T public domain 8 | source for getopt(3). It is the code which was given out at the 1985 9 | UNIFORUM conference in Dallas. I obtained it by electronic mail 10 | directly from AT&T. The people there assure me that it is indeed 11 | in the public domain. 12 | */ 13 | 14 | /*LINTLIBRARY*/ 15 | #include 16 | #include 17 | #include "patch.h" 18 | 19 | #ifdef HAVE_NO_GETOPT 20 | 21 | #define EOF (-1) 22 | #define ERR(s, c) \ 23 | if (opterr) { \ 24 | char errbuf[2]; \ 25 | errbuf[0] = c; errbuf[1] = '\n'; \ 26 | (void) printf("%s", argv[0]); \ 27 | (void) printf("%s", s); \ 28 | (void) printf("%s", errbuf); \ 29 | } 30 | 31 | 32 | int opterr; 33 | int optind; 34 | int optopt; 35 | char *optarg; 36 | 37 | int getopt(int argc, char * const argv[], char *opts) 38 | { 39 | static int sp = 1; 40 | register int c; 41 | register char *cp; 42 | static int call_first = 1; 43 | 44 | if (call_first) { 45 | opterr = 1; 46 | optind = 1; 47 | call_first = 0; 48 | } 49 | 50 | if(sp == 1) 51 | if(optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') 52 | return(EOF); 53 | else if(strcmp(argv[optind], "--") == 0) { 54 | optind++; 55 | return(EOF); 56 | } 57 | optopt = c = argv[optind][sp]; 58 | if(c == ':' || (cp=strchr(opts, c)) == NULL) { 59 | ERR(": illegal option -- ", c); 60 | if(argv[optind][++sp] == '\0') { 61 | optind++; 62 | sp = 1; 63 | } 64 | return('?'); 65 | } 66 | if(*++cp == ':') { 67 | if(argv[optind][sp+1] != '\0') 68 | optarg = &argv[optind++][sp+1]; 69 | else if(++optind >= argc) { 70 | ERR(": option requires an argument -- ", c); 71 | sp = 1; 72 | return('?'); 73 | } else 74 | optarg = argv[optind++]; 75 | sp = 1; 76 | } else { 77 | if(argv[optind][++sp] == '\0') { 78 | sp = 1; 79 | optind++; 80 | } 81 | optarg = NULL; 82 | } 83 | return(c); 84 | } 85 | #endif /* HAVE_NO_GETOPT */ 86 | -------------------------------------------------------------------------------- /samples/c/patch.h: -------------------------------------------------------------------------------- 1 | #ifndef __WIN_PATCH_INCLUDE_H__ 2 | #define __WIN_PATCH_INCLUDE_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #if defined(_WIN32) || defined(_WIN64) 9 | # include 10 | # define HAVE_NO_GETOPT 11 | # define snprintf _snprintf 12 | extern int optind; 13 | extern char *optarg; 14 | int getopt(int argc, char * const argv[], char *opts); 15 | #else 16 | # define SOCKET int 17 | # define INVALID_SOCKET -1 18 | #endif 19 | 20 | void socket_init(void); 21 | void socket_end(void); 22 | void socket_close(SOCKET fd); 23 | SOCKET socket_listen(const char *ip, int port); 24 | SOCKET socket_accept(SOCKET fd); 25 | SOCKET socket_connect(const char *ip, int port); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /samples/c/poll/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = poll 3 | -------------------------------------------------------------------------------- /samples/c/server/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = server 3 | -------------------------------------------------------------------------------- /samples/c/server/server_vc2012.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 29 | 30 | 头文件 31 | 32 | 33 | 头文件 34 | 35 | 36 | -------------------------------------------------------------------------------- /samples/c/server/server_vc2013.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 29 | 30 | 头文件 31 | 32 | 33 | 头文件 34 | 35 | 36 | -------------------------------------------------------------------------------- /samples/c/server/server_vc2015.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 29 | 30 | 头文件 31 | 32 | 33 | 头文件 34 | 35 | 36 | -------------------------------------------------------------------------------- /samples/c/server/valgrind.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #valgrind --tool=memcheck --leak-check=yes --leak-check=full --show-reachable=yes --max-stackframe=3426305034400000 -v ./fiber -n 10 -m 20 4 | #valgrind --tool=memcheck --leak-check=yes --leak-check=full --show-reachable=yes -v ./server -e poll 5 | valgrind --tool=memcheck --leak-check=yes --leak-check=full --show-reachable=yes -v ./server 6 | -------------------------------------------------------------------------------- /samples/c/sleep/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = sleep 3 | -------------------------------------------------------------------------------- /samples/c/sleep/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "fiber/libfiber.h" 7 | 8 | static int __fibers_count = 2; 9 | 10 | static void sleep_main(ACL_FIBER *fiber, void *ctx) 11 | { 12 | int *n = (int *) ctx; 13 | time_t last, now; 14 | 15 | while (1) { 16 | acl_fiber_sleep(1); 17 | printf("fiber-%d wakeup\r\n", acl_fiber_self()); 18 | } 19 | 20 | printf("fiber-%d: begin sleep %d\r\n", acl_fiber_id(fiber), *n); 21 | time(&last); 22 | *n = (int) acl_fiber_sleep(*n); 23 | time(&now); 24 | 25 | printf("fiber-%d: wakup, n: %d, sleep: %ld\r\n", 26 | acl_fiber_id(fiber), *n, (long) (now - last)); 27 | 28 | free(n); 29 | 30 | if (--__fibers_count == 0) { 31 | printf("All are over!\r\n"); 32 | } 33 | } 34 | 35 | static void usage(const char *procname) 36 | { 37 | printf("usage: %s -h [help] -c nfibers\r\n", procname); 38 | } 39 | 40 | int main(int argc, char *argv[]) 41 | { 42 | int ch, i; 43 | 44 | while ((ch = getopt(argc, argv, "hc:")) > 0) { 45 | switch (ch) { 46 | case 'h': 47 | usage(argv[0]); 48 | return 0; 49 | case 'c': 50 | __fibers_count = atoi(optarg); 51 | break; 52 | default: 53 | break; 54 | } 55 | } 56 | 57 | acl_fiber_msg_stdout_enable(1); 58 | 59 | printf("fibers: %d\r\n", __fibers_count); 60 | 61 | for (i = 1; i <= __fibers_count; i++) { 62 | int *n = (int *) malloc(sizeof(int)); 63 | *n = i; 64 | acl_fiber_create(sleep_main, n, 327680); 65 | } 66 | 67 | acl_fiber_schedule(); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /samples/c/stamp.h: -------------------------------------------------------------------------------- 1 | #ifndef __STAMP_INCLUDE_H__ 2 | #define __STAMP_INCLUDE_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | static double stamp_sub(const struct timeval *from, const struct timeval *sub) 9 | { 10 | struct timeval res; 11 | 12 | memcpy(&res, from, sizeof(struct timeval)); 13 | 14 | res.tv_usec -= sub->tv_usec; 15 | if (res.tv_usec < 0) { 16 | --res.tv_sec; 17 | res.tv_usec += 1000000; 18 | } 19 | res.tv_sec -= sub->tv_sec; 20 | 21 | return (res.tv_sec * 1000.0 + res.tv_usec/1000.0); 22 | } 23 | 24 | #ifdef __cplusplus 25 | } 26 | #endif 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /samples/c/threads/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = threads 3 | -------------------------------------------------------------------------------- /samples/c/threads/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "fiber/libfiber.h" 6 | 7 | static size_t __stack_size = 64000; 8 | static int __nthreads = 2; 9 | static int __nfibers = 1000; 10 | static int __nloop = 10000; 11 | 12 | static void fiber_main(ACL_FIBER *fb, void *ctx) 13 | { 14 | int i; 15 | 16 | (void) fb; 17 | (void) ctx; 18 | 19 | for (i = 0; i < __nloop; i++) { 20 | acl_fiber_yield(); 21 | } 22 | } 23 | 24 | static void *thread_main(void *ctx) 25 | { 26 | int i; 27 | 28 | for (i = 0; i < __nfibers; i++) { 29 | acl_fiber_create(fiber_main, ctx, __stack_size); 30 | } 31 | 32 | acl_fiber_schedule(); 33 | 34 | printf("thread-%lu: over now, nfibers=%d, nloop=%lld\r\n", 35 | (unsigned long) pthread_self(), __nfibers, 36 | ((long long) __nfibers) * ((long long) __nloop)); 37 | 38 | return NULL; 39 | }; 40 | 41 | ////////////////////////////////////////////////////////////////////////////// 42 | 43 | static void usage(const char* procname) 44 | { 45 | printf("usage: %s -h [help]\r\n" 46 | " -t nthreads [default: 2]\r\n" 47 | " -c nfibers [default: 1000]\r\n" 48 | " -z stack_size [default: 64000]\r\n" 49 | " -n nloop [default: 1000]\r\n", 50 | procname); 51 | } 52 | 53 | int main(int argc, char *argv[]) 54 | { 55 | int ch, i; 56 | #define MAX_THREADS 100 57 | pthread_t threads[MAX_THREADS]; 58 | 59 | while ((ch = getopt(argc, argv, "ht:c:z:n:")) > 0) { 60 | switch (ch) { 61 | case 'h': 62 | usage(argv[0]); 63 | return 0; 64 | case 't': 65 | __nthreads = atoi(optarg); 66 | if (__nthreads > MAX_THREADS) 67 | __nthreads = MAX_THREADS; 68 | break; 69 | case 'c': 70 | __nfibers = atoi(optarg); 71 | break; 72 | case 'z': 73 | __stack_size = atol(optarg); 74 | break; 75 | case 'n': 76 | __nloop = atoi(optarg); 77 | break; 78 | default: 79 | break; 80 | } 81 | } 82 | 83 | for (i = 0; i < __nthreads; i++) { 84 | pthread_create(&threads[i], NULL, thread_main, NULL); 85 | } 86 | 87 | for (i = 0; i < __nthreads; i++) { 88 | pthread_join(threads[i], NULL); 89 | } 90 | 91 | printf("all over, thread=%d, nloop=%d\r\n", __nthreads, __nloop); 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /samples/c/util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "util.h" 7 | 8 | double stamp_sub(const struct timeval *from, const struct timeval *sub) 9 | { 10 | struct timeval res; 11 | 12 | memcpy(&res, from, sizeof(struct timeval)); 13 | 14 | res.tv_usec -= sub->tv_usec; 15 | if (res.tv_usec < 0) { 16 | --res.tv_sec; 17 | res.tv_usec += 1000000; 18 | } 19 | 20 | res.tv_sec -= sub->tv_sec; 21 | return res.tv_sec * 1000.0 + res.tv_usec / 1000.0; 22 | } 23 | 24 | double compute_speed(long long n, double cost) 25 | { 26 | double speed; 27 | 28 | if (cost <= 0) { // xxxx ? 29 | cost = 0.001; 30 | } 31 | speed = (n * 1000) / cost; 32 | return speed; 33 | } 34 | 35 | void show_speed(const struct timeval *begin, const struct timeval *end, 36 | long long n) 37 | { 38 | double cost = stamp_sub(end, begin); 39 | double speed = compute_speed(n, cost); 40 | printf(">>total count=%lld, cost=%.2f, speed=%.2f\r\n", 41 | n, cost, speed); 42 | } 43 | -------------------------------------------------------------------------------- /samples/c/util.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTIL_H_INCLUDE_ 2 | #define __UTIL_H_INCLUDE_ 3 | 4 | #include 5 | 6 | double stamp_sub(const struct timeval* from, const struct timeval* sub); 7 | void show_speed(const struct timeval* begin, const struct timeval* end, long long n); 8 | double compute_speed(long long n, double cost); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /samples/cpp/Makefile: -------------------------------------------------------------------------------- 1 | .PHONEY = all clean cl rebuild rb 2 | 3 | all: 4 | @(cd fiber; make) 5 | @(cd server; make) 6 | @(cd client; make) 7 | @(cd waiter; make) 8 | 9 | clean cl: 10 | @(cd fiber; make clean) 11 | @(cd server; make clean) 12 | @(cd client; make clean) 13 | @(cd waiter; make clean) 14 | 15 | rebuild rb: cl all 16 | -------------------------------------------------------------------------------- /samples/cpp/client/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = client 3 | -------------------------------------------------------------------------------- /samples/cpp/fiber/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = fiber 3 | -------------------------------------------------------------------------------- /samples/cpp/patch.h: -------------------------------------------------------------------------------- 1 | #ifndef __WIN_PATCH_INCLUDE_H__ 2 | #define __WIN_PATCH_INCLUDE_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #if defined(_WIN32) || defined(_WIN64) 9 | # include 10 | # define HAVE_NO_GETOPT 11 | # define snprintf _snprintf 12 | extern int optind; 13 | extern char *optarg; 14 | int getopt(int argc, char * const argv[], char *opts); 15 | #else 16 | # define SOCKET int 17 | # define INVALID_SOCKET -1 18 | #endif 19 | 20 | void socket_init(void); 21 | void socket_end(void); 22 | void socket_close(SOCKET fd); 23 | SOCKET socket_listen(const char *ip, int port); 24 | SOCKET socket_accept(SOCKET fd); 25 | SOCKET socket_connect(const char *ip, int port); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /samples/cpp/server/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = server 3 | -------------------------------------------------------------------------------- /samples/cpp/util.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "util.h" 7 | 8 | double stamp_sub(const struct timeval& from, const struct timeval& sub) 9 | { 10 | struct timeval res; 11 | 12 | memcpy(&res, &from, sizeof(struct timeval)); 13 | 14 | res.tv_usec -= sub.tv_usec; 15 | if (res.tv_usec < 0) { 16 | --res.tv_sec; 17 | res.tv_usec += 1000000; 18 | } 19 | 20 | res.tv_sec -= sub.tv_sec; 21 | return res.tv_sec * 1000.0 + res.tv_usec / 1000.0; 22 | } 23 | 24 | double compute_speed(long long n, double cost) 25 | { 26 | if (cost <= 0) { // xxxx ? 27 | cost = 0.001; 28 | } 29 | double speed = (n * 1000) / cost; 30 | return speed; 31 | } 32 | 33 | void show_speed(const struct timeval& begin, const struct timeval& end, 34 | long long n) 35 | { 36 | double cost = stamp_sub(end, begin); 37 | double speed = compute_speed(n, cost); 38 | printf(">>total count=%lld, cost=%.2f, speed=%.2f\r\n", 39 | n, cost, speed); 40 | } 41 | -------------------------------------------------------------------------------- /samples/cpp/util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | double stamp_sub(const struct timeval& from, const struct timeval& sub); 6 | void show_speed(const struct timeval& begin, const struct timeval& end, long long n); 7 | double compute_speed(long long n, double cost); 8 | -------------------------------------------------------------------------------- /samples/cpp/waiter/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = waiter 3 | -------------------------------------------------------------------------------- /samples/cpp/waiter/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "fiber/libfiber.hpp" 6 | 7 | class myfiber : public acl::fiber { 8 | public: 9 | myfiber(int i) : i_(i) {} 10 | 11 | private: 12 | int i_; 13 | acl::fiber_tbox box_; 14 | 15 | ~myfiber(void) {} 16 | 17 | protected: 18 | // @override 19 | void run(void) { 20 | printf("fiber-%d, i=%d, thread is %ld\r\n", 21 | acl::fiber::self(), i_, (long) pthread_self()); 22 | 23 | pthread_attr_t attr; 24 | pthread_attr_init(&attr); 25 | pthread_attr_setdetachstate(&attr, 1); 26 | 27 | pthread_t tid; 28 | pthread_create(&tid, &attr, thread_main, this); 29 | 30 | // wait for message from thread 31 | (void) box_.pop(); 32 | 33 | // after thread return 34 | printf("ok, fiber-%d, i=%d, thread is %ld\r\n", 35 | acl::fiber::self(), i_, (long) pthread_self()); 36 | 37 | delete this; 38 | } 39 | 40 | private: 41 | static void* thread_main(void* ctx) { 42 | myfiber* fb = (myfiber*) ctx; 43 | 44 | // run in another thread 45 | printf("i=%d, current thread is %ld\r\n", 46 | fb->i_, (long) pthread_self()); 47 | fb->i_ += 100; // change the i's value 48 | usleep(10000); 49 | 50 | // notify the waiter 51 | fb->box_.push(NULL); 52 | 53 | return NULL; 54 | } 55 | }; 56 | 57 | static void test_run(void) { 58 | for (int i = 0; i < 10; i++) { 59 | acl::fiber* fb = new myfiber(i); 60 | fb->start(); 61 | } 62 | 63 | acl::fiber::schedule(); 64 | } 65 | 66 | int main(void) { 67 | test_run(); 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /samples/cxx/Makefile: -------------------------------------------------------------------------------- 1 | .PHONEY = all clean cl rebuild rb 2 | 3 | all: 4 | @(cd fiber; make) 5 | @(cd server; make) 6 | @(cd client; make) 7 | @(cd waiter; make) 8 | 9 | clean cl: 10 | @(cd fiber; make clean) 11 | @(cd server; make clean) 12 | @(cd client; make clean) 13 | @(cd waiter; make clean) 14 | 15 | rebuild rb: cl all 16 | -------------------------------------------------------------------------------- /samples/cxx/client/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = client 3 | -------------------------------------------------------------------------------- /samples/cxx/client/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "fiber/go_fiber.hpp" 9 | 10 | #include "../patch.h" 11 | #include "../util.h" 12 | 13 | static void fiber_client(const std::string& ip, int port, int n, long long& count) { 14 | SOCKET fd = socket_connect(ip.c_str(), port); 15 | if (fd == INVALID_SOCKET) { 16 | printf("connect %s %d error %s\r\n", ip.c_str(), port, 17 | acl::fiber::last_serror()); 18 | return; 19 | } 20 | 21 | printf("connect %s %d ok, fd=%d\r\n", ip.c_str(), port, fd); 22 | 23 | const char* s = "hello world!\r\n"; 24 | char buf[8192]; 25 | for (int i = 0; i < n; i++) { 26 | if (write(fd, s, strlen(s)) < 0) { 27 | printf("send error %s\r\n", acl::fiber::last_serror()); 28 | break; 29 | } 30 | 31 | int ret = read(fd, buf, sizeof(buf) - 1); 32 | if (ret == 0) { 33 | break; 34 | } 35 | if (ret == -1) { 36 | if (errno == EINTR) { 37 | continue; 38 | } 39 | printf("read error %s\r\n", acl::fiber::last_serror()); 40 | break; 41 | } 42 | count++; 43 | } 44 | 45 | printf("close fd=%d\r\n", fd); 46 | socket_close(fd); 47 | } 48 | 49 | static void usage(const char* procname) { 50 | printf("usage: %s -h [help] -s server_ip -p server_port\r\n", procname); 51 | } 52 | 53 | int main(int argc, char* argv[]) { 54 | std::string ip = "127.0.0.1"; 55 | int port = 8192, ch, nfiber = 100, nloop = 10000; 56 | 57 | while ((ch = getopt(argc, argv, "hs:p:c:n:")) > 0) { 58 | switch (ch) { 59 | case 'h': 60 | usage(argv[0]); 61 | return 0; 62 | case 's': 63 | ip = optarg; 64 | break; 65 | case 'p': 66 | port = atoi(optarg); 67 | break; 68 | case 'c': 69 | nfiber = atoi(optarg); 70 | break; 71 | case 'n': 72 | nloop = atoi(optarg); 73 | break; 74 | default: 75 | break; 76 | } 77 | } 78 | 79 | socket_init(); 80 | 81 | struct timeval begin; 82 | gettimeofday(&begin, NULL); 83 | long long count = 0; 84 | 85 | for (int i = 0; i < nfiber; i++) { 86 | go[&] { 87 | fiber_client(ip, port, nloop, count); 88 | }; 89 | } 90 | 91 | acl::fiber::schedule_with(acl::FIBER_EVENT_T_KERNEL); 92 | 93 | struct timeval end; 94 | gettimeofday(&end, NULL); 95 | 96 | show_speed(begin, end, count); 97 | socket_end(); 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /samples/cxx/fiber/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = fiber 3 | -------------------------------------------------------------------------------- /samples/cxx/fiber/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "fiber/go_fiber.hpp" 7 | 8 | #include "../util.h" 9 | 10 | static void fiber1(int i) { 11 | printf("fiber-%d running, i=%d\r\n", acl::fiber::self(), i); 12 | } 13 | 14 | static void schedule_one(void) { 15 | std::vector fibers; 16 | for (int i = 0; i < 10; i++) { 17 | go[&] { fiber1(i); }; 18 | } 19 | 20 | acl::fiber::schedule_with(acl::FIBER_EVENT_T_KERNEL); 21 | } 22 | 23 | static void schedule_two(void) { 24 | acl::fiber::init(acl::FIBER_EVENT_T_KERNEL, true); 25 | 26 | for (int i = 0; i < 10; i++) { 27 | go[&] { fiber1(i); }; 28 | } 29 | } 30 | 31 | static void fiber2(int n, long long& count) { 32 | for (int i = 0; i < n; i++) { 33 | if (i < 5) { 34 | printf("fiber-%d, i=%d\r\n", acl::fiber::self(), i); 35 | } 36 | ++count; 37 | acl::fiber::yield(); 38 | } 39 | } 40 | 41 | static void schedule_bench(int nfiber, int nloop) { 42 | acl::fiber::init(acl::FIBER_EVENT_T_KERNEL, false); 43 | 44 | struct timeval begin; 45 | gettimeofday(&begin, NULL); 46 | 47 | long long count = 0; 48 | for (int i = 0; i < nfiber; i++) { 49 | go[&] { fiber2(nloop, count); }; 50 | } 51 | 52 | acl::fiber::schedule(); 53 | 54 | struct timeval end; 55 | gettimeofday(&end, NULL); 56 | 57 | show_speed(begin, end, count); 58 | } 59 | 60 | static void usage(const char* procname) { 61 | printf("usage: %s -h [help] -c fibers -n loop\r\n", procname); 62 | } 63 | 64 | int main(int argc, char* argv[]) { 65 | int ch, nfiber = 10, nloop = 1000000; 66 | 67 | while ((ch = getopt(argc, argv, "hc:n:")) > 0) { 68 | switch (ch) { 69 | case 'h': 70 | usage(argv[0]); 71 | return 0; 72 | case 'c': 73 | nfiber = atoi(optarg); 74 | break; 75 | case 'n': 76 | nloop = atoi(optarg); 77 | break; 78 | default: 79 | break; 80 | } 81 | } 82 | 83 | printf("schedule one\r\n"); 84 | schedule_one(); 85 | 86 | printf("\r\n"); 87 | printf("schedule two\r\n"); 88 | schedule_two(); 89 | 90 | printf("\r\n"); 91 | printf("schedule benchmark\r\n"); 92 | schedule_bench(nfiber, nloop); 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /samples/cxx/fiber_pool/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @(mkdir -p build; cd build; cmake ..; make -j 4) 3 | 4 | clean cl: 5 | rm -rf build fiber_pool 6 | -------------------------------------------------------------------------------- /samples/cxx/fiber_pool/main.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static void task_run(acl::wait_group* wg, std::atomic_long* res, long long i) { 8 | (*res) += i; 9 | wg->done(); 10 | } 11 | 12 | static void test(long long count, size_t min, size_t max, size_t buf, 13 | int idle_ms, bool shared) { 14 | std::shared_ptr fibers = std::make_shared 15 | (min, max, idle_ms, buf, 64000, shared); 16 | 17 | std::shared_ptr wg(new acl::wait_group); 18 | std::shared_ptr result(new std::atomic_long(0)); 19 | 20 | wg->add(1); 21 | go[wg, fibers, count, result] { 22 | printf("Begin to add tasks...\r\n"); 23 | for (long long i = 0; i < count; i++) { 24 | wg->add(1); 25 | fibers->exec(task_run, wg.get(), result.get(), i); 26 | } 27 | printf("Add task end!\r\n"); 28 | wg->done(); 29 | }; 30 | 31 | go[wg, result, fibers, count] { 32 | struct timeval begin; 33 | gettimeofday(&begin, nullptr); 34 | 35 | printf("Begin to wait...\r\n"); 36 | wg->wait(); 37 | printf("All task finished!\r\n"); 38 | 39 | struct timeval end; 40 | gettimeofday(&end, nullptr); 41 | 42 | long long res = result->load(); 43 | 44 | double tc = (end.tv_sec - begin.tv_sec) * 1000 45 | + (end.tv_usec - begin.tv_usec) / 1000; 46 | 47 | double speed = (count * 1000) / (tc > 0 ? tc : 0.0000000001); 48 | printf("Result: %lld, count: %lld, tc: %.2f ms, speed: %.2f qps\r\n", 49 | res, count, tc, speed); 50 | 51 | fibers->stop(); 52 | }; 53 | 54 | acl::fiber::schedule(); 55 | } 56 | 57 | static void usage(const char* procname) { 58 | printf("usage: %s -h [help]\r\n" 59 | " -n count\r\n" 60 | " -b buf\r\n" 61 | " -t fiber_wait_timeout\r\n" 62 | " -S [if using shared stack]\r\n" 63 | , procname); 64 | } 65 | 66 | int main(int argc, char *argv[]) { 67 | int ch; 68 | size_t buf = 500; 69 | int idle_ms = -1; 70 | long long count = 100; 71 | bool shared = false; 72 | 73 | while ((ch = getopt(argc, argv, "hn:b:t:S")) > 0) { 74 | switch (ch) { 75 | case 'h': 76 | usage(argv[0]); 77 | return 0; 78 | case 'n': 79 | count = atoll(optarg); 80 | break; 81 | case 'b': 82 | buf = (size_t) atoi(optarg); 83 | break; 84 | case 't': 85 | idle_ms = atoi(optarg); 86 | break; 87 | case 'S': 88 | shared = true; 89 | break; 90 | default: 91 | break; 92 | } 93 | } 94 | 95 | test(count, 10, 100, buf, idle_ms, shared); 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /samples/cxx/fiber_pool/stdafx.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | -------------------------------------------------------------------------------- /samples/cxx/fiber_pool/stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/cxx/fiber_pool/stdafx.h -------------------------------------------------------------------------------- /samples/cxx/fiber_tbox/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = fiber_tbox 3 | -------------------------------------------------------------------------------- /samples/cxx/fiber_tbox/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "fiber/fiber_tbox.hpp" 8 | #include "fiber/go_fiber.hpp" 9 | 10 | class myobj { 11 | public: 12 | myobj() = default; 13 | ~myobj() = default; 14 | 15 | void run() { 16 | std::cout << "Thread: " << std::this_thread::get_id() << " hello world!\r\n"; 17 | } 18 | }; 19 | 20 | static void usage(const char* procname) { 21 | printf("usage: %s -h [help]\r\n", procname); 22 | } 23 | 24 | int main(int argc, char* argv[]) { 25 | int ch; 26 | 27 | while ((ch = getopt(argc, argv, "h")) > 0) { 28 | switch (ch) { 29 | case 'h': 30 | usage(argv[0]); 31 | return 0; 32 | default: 33 | break; 34 | } 35 | } 36 | 37 | std::shared_ptr> box(new acl::fiber_tbox); 38 | 39 | go[box] { 40 | myobj *o = box->pop(); 41 | o->run(); 42 | delete o; 43 | }; 44 | 45 | go[box] { 46 | myobj *o = new myobj; 47 | box->push(o); 48 | }; 49 | 50 | ////////////////////////////////////////////////////////////////////////// 51 | 52 | go[box] { 53 | myobj *o = new myobj; 54 | box->push(o); 55 | }; 56 | 57 | std::thread thread([box] { 58 | myobj *o = box->pop(); 59 | o->run(); 60 | delete o; 61 | }); 62 | 63 | acl::fiber::schedule(); 64 | thread.join(); 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /samples/cxx/fiber_tbox2/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = fiber_tbox2 3 | -------------------------------------------------------------------------------- /samples/cxx/fiber_tbox2/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "fiber/fiber_tbox2.hpp" 8 | #include "fiber/go_fiber.hpp" 9 | 10 | class myobj { 11 | public: 12 | myobj() { 13 | std::cout << "Thread: " << std::this_thread::get_id() << " myobj created!\r\n"; 14 | } 15 | 16 | ~myobj() { 17 | std::cout << "Thread: " << std::this_thread::get_id() << " myobj freed!\r\n"; 18 | } 19 | 20 | void run() { 21 | std::cout << "Thread: " << std::this_thread::get_id() << " hello world!\r\n"; 22 | } 23 | }; 24 | 25 | using shared_myobj = std::shared_ptr; 26 | using shared_tbox2 = std::shared_ptr>; 27 | 28 | static void usage(const char* procname) { 29 | printf("usage: %s -h [help]\r\n", procname); 30 | } 31 | 32 | int main(int argc, char* argv[]) { 33 | int ch; 34 | 35 | while ((ch = getopt(argc, argv, "h")) > 0) { 36 | switch (ch) { 37 | case 'h': 38 | usage(argv[0]); 39 | return 0; 40 | default: 41 | break; 42 | } 43 | } 44 | 45 | shared_tbox2 box(new acl::fiber_tbox2); 46 | 47 | go[box] { 48 | shared_myobj o; 49 | box->pop(o); 50 | o->run(); 51 | }; 52 | 53 | go[box] { 54 | shared_myobj o(new myobj); 55 | box->push(o); 56 | }; 57 | 58 | ////////////////////////////////////////////////////////////////////////// 59 | 60 | go[box] { 61 | shared_myobj o(new myobj); 62 | box->push(o); 63 | }; 64 | 65 | std::thread thread([box] { 66 | shared_myobj o; 67 | box->pop(o); 68 | o->run(); 69 | }); 70 | 71 | acl::fiber::schedule(); 72 | thread.join(); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /samples/cxx/mutex/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = mutex 3 | -------------------------------------------------------------------------------- /samples/cxx/mutex/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "fiber/go_fiber.hpp" 9 | 10 | int main() { 11 | std::shared_ptr mutex(new acl::fiber_mutex); 12 | 13 | for (int j = 0; j < 5; j++) { 14 | go[mutex] { 15 | for (int i = 0; i < 5; i++) { 16 | mutex->lock(); 17 | printf("fiber-%d: locked\r\n", acl::fiber::self()); 18 | ::sleep(1); 19 | mutex->unlock(); 20 | acl::fiber::yield(); 21 | } 22 | }; 23 | } 24 | 25 | std::vector threads; 26 | 27 | for (int i = 0; i < 5; i++) { 28 | threads.emplace_back(std::thread([mutex] { 29 | for (int j = 0; j < 5; j++) { 30 | mutex->lock(); 31 | std::cout << "Thread: " << std::this_thread::get_id() << " locked\r\n"; 32 | ::sleep(1); 33 | mutex->unlock(); 34 | ::sleep(1); 35 | } 36 | })); 37 | } 38 | 39 | std::thread([mutex] { 40 | mutex->lock(); 41 | std::cout << "One thread: " << std::this_thread::get_id() << " locked\r\n"; 42 | mutex->unlock(); 43 | }).detach(); 44 | 45 | std::thread([mutex] { 46 | go[mutex] { 47 | mutex->lock(); 48 | printf("One fiber in another thread locked\r\n"); 49 | ::sleep(1); 50 | mutex->unlock(); 51 | }; 52 | acl::fiber::schedule(); 53 | }).detach(); 54 | 55 | acl::fiber::schedule_with(acl::FIBER_EVENT_T_KERNEL); 56 | 57 | for (auto& thr : threads) { 58 | thr.join(); 59 | } 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /samples/cxx/patch.h: -------------------------------------------------------------------------------- 1 | #ifndef __WIN_PATCH_INCLUDE_H__ 2 | #define __WIN_PATCH_INCLUDE_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #if defined(_WIN32) || defined(_WIN64) 9 | # include 10 | # define HAVE_NO_GETOPT 11 | # define snprintf _snprintf 12 | extern int optind; 13 | extern char *optarg; 14 | int getopt(int argc, char * const argv[], char *opts); 15 | #else 16 | # define SOCKET int 17 | # define INVALID_SOCKET -1 18 | #endif 19 | 20 | void socket_init(void); 21 | void socket_end(void); 22 | void socket_close(SOCKET fd); 23 | SOCKET socket_listen(const char *ip, int port); 24 | SOCKET socket_accept(SOCKET fd); 25 | SOCKET socket_connect(const char *ip, int port); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /samples/cxx/server/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = server 3 | -------------------------------------------------------------------------------- /samples/cxx/server/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "fiber/go_fiber.hpp" 10 | 11 | #include "../patch.h" 12 | 13 | static void fiber_client(SOCKET fd) { 14 | char buf[8192]; 15 | 16 | while (true) { 17 | int ret = read(fd, buf, sizeof(buf) - 1); 18 | if (ret == 0) { 19 | break; 20 | } 21 | if (ret == -1) { 22 | if (errno == EINTR) { 23 | continue; 24 | } 25 | printf("read error %s\r\n", acl::fiber::last_serror()); 26 | break; 27 | } 28 | if (write(fd, buf, ret) < 0) { 29 | printf("send error %s\r\n", acl::fiber::last_serror()); 30 | break; 31 | } 32 | } 33 | 34 | socket_close(fd); 35 | } 36 | 37 | static void fiber_listen(SOCKET lfd) { 38 | while (true) { 39 | SOCKET cfd = socket_accept(lfd); 40 | if (cfd == -1) { 41 | printf("accept error %s\r\n", acl::fiber::last_serror()); 42 | break; 43 | } 44 | printf("accept one client fd=%d\r\n", cfd); 45 | 46 | go[=] { 47 | fiber_client(cfd); 48 | }; 49 | } 50 | 51 | socket_close(lfd); 52 | } 53 | 54 | static void usage(const char* procname) { 55 | printf("usage: %s -h [help] -s ip -p port\r\n", procname); 56 | } 57 | 58 | int main(int argc, char* argv[]) { 59 | std::string ip = "127.0.0.1"; 60 | int port = 8192, ch; 61 | 62 | while ((ch = getopt(argc, argv, "hs:p:")) > 0) { 63 | switch (ch) { 64 | case 'h': 65 | usage(argv[0]); 66 | return 0; 67 | case 's': 68 | ip = optarg; 69 | break; 70 | case 'p': 71 | port = atoi(optarg); 72 | break; 73 | default: 74 | break; 75 | } 76 | } 77 | 78 | socket_init(); 79 | 80 | SOCKET fd = socket_listen(ip.c_str(), port); 81 | if (fd == -1) { 82 | printf("listen %s %d error %s\r\n", 83 | ip.c_str(), port, acl::fiber::last_serror()); 84 | return 1; 85 | } 86 | 87 | printf("listen %s %d ok\r\n", ip.c_str(), port); 88 | 89 | go[=] { 90 | fiber_listen(fd); 91 | }; 92 | 93 | acl::fiber::schedule_with(acl::FIBER_EVENT_T_KERNEL); 94 | 95 | socket_end(); 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /samples/cxx/shared_stack/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = shared_stack 3 | -------------------------------------------------------------------------------- /samples/cxx/shared_stack/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "fiber/go_fiber.hpp" 5 | 6 | int main() { 7 | std::shared_ptr count(new int); 8 | 9 | for (int i = 0; i < 10; i++) { 10 | go_share(4096)[count] { 11 | printf("fiber-%d running\r\n", acl::fiber::self()); 12 | (*count)++; 13 | }; 14 | } 15 | 16 | acl::fiber::schedule(); 17 | 18 | printf("At last, count is %d\r\n", *count); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /samples/cxx/util.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "util.h" 7 | 8 | double stamp_sub(const struct timeval& from, const struct timeval& sub) 9 | { 10 | struct timeval res; 11 | 12 | memcpy(&res, &from, sizeof(struct timeval)); 13 | 14 | res.tv_usec -= sub.tv_usec; 15 | if (res.tv_usec < 0) { 16 | --res.tv_sec; 17 | res.tv_usec += 1000000; 18 | } 19 | 20 | res.tv_sec -= sub.tv_sec; 21 | return res.tv_sec * 1000.0 + res.tv_usec / 1000.0; 22 | } 23 | 24 | double compute_speed(long long n, double cost) 25 | { 26 | if (cost <= 0) { // xxxx ? 27 | cost = 0.001; 28 | } 29 | double speed = (n * 1000) / cost; 30 | return speed; 31 | } 32 | 33 | void show_speed(const struct timeval& begin, const struct timeval& end, 34 | long long n) 35 | { 36 | double cost = stamp_sub(end, begin); 37 | double speed = compute_speed(n, cost); 38 | printf(">>total count=%lld, cost=%.2f, speed=%.2f\r\n", 39 | n, cost, speed); 40 | } 41 | -------------------------------------------------------------------------------- /samples/cxx/util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | double stamp_sub(const struct timeval& from, const struct timeval& sub); 6 | void show_speed(const struct timeval& begin, const struct timeval& end, long long n); 7 | double compute_speed(long long n, double cost); 8 | -------------------------------------------------------------------------------- /samples/cxx/waite_group/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = waite_group 3 | CFLAGS += -std=c++11 4 | -------------------------------------------------------------------------------- /samples/cxx/waiter/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.in 2 | PROG = waiter 3 | -------------------------------------------------------------------------------- /samples/cxx/waiter/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "fiber/go_fiber.hpp" 6 | 7 | static void fiber_main(int i) { 8 | printf("fiber-%d, i=%d, thread is %ld\r\n", 9 | acl::fiber::self(), i, (long) pthread_self()); 10 | 11 | // wait for thread running 12 | go_wait[&] { 13 | // run in another thread 14 | printf("i=%d, current thread is %ld\r\n", i, (long) pthread_self()); 15 | i += 100; // change the i's value 16 | usleep(10000); 17 | }; 18 | 19 | // after thread return 20 | 21 | printf("ok, fiber-%d, i=%d, thread is %ld\r\n", 22 | acl::fiber::self(), i, (long) pthread_self()); 23 | } 24 | 25 | static void test_run(void) { 26 | for (int i = 0; i < 10; i++) { 27 | go[=] { fiber_main(i); }; 28 | } 29 | 30 | acl::fiber::schedule(); 31 | } 32 | 33 | int main(void) { 34 | test_run(); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/EchoServer.h: -------------------------------------------------------------------------------- 1 |  2 | // EchoServer.h: PROJECT_NAME 应用程序的主头文件 3 | // 4 | 5 | #pragma once 6 | 7 | #ifndef __AFXWIN_H__ 8 | #error "在包含此文件之前包含 'pch.h' 以生成 PCH" 9 | #endif 10 | 11 | #include "resource.h" // 主符号 12 | 13 | 14 | // CEchoServerApp: 15 | // 有关此类的实现,请参阅 EchoServer.cpp 16 | // 17 | 18 | class CEchoServerApp : public CWinApp 19 | { 20 | public: 21 | CEchoServerApp(); 22 | 23 | // 重写 24 | public: 25 | virtual BOOL InitInstance(); 26 | 27 | // 实现 28 | 29 | DECLARE_MESSAGE_MAP() 30 | }; 31 | 32 | extern CEchoServerApp theApp; 33 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/EchoServer.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/gui/EchoServer/EchoServer.rc -------------------------------------------------------------------------------- /samples/gui/EchoServer/EchoServer.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | EchoServer.rc 5 | 6 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/EchoServerDlg.h: -------------------------------------------------------------------------------- 1 |  2 | // EchoServerDlg.h: 头文件 3 | // 4 | 5 | #pragma once 6 | 7 | class CFiberServer; 8 | 9 | // CEchoServerDlg 对话框 10 | class CEchoServerDlg : public CDialogEx 11 | { 12 | // 构造 13 | public: 14 | CEchoServerDlg(CWnd* pParent = nullptr); // 标准构造函数 15 | 16 | // 对话框数据 17 | #ifdef AFX_DESIGN_TIME 18 | enum { IDD = IDD_ECHOSERVER_DIALOG }; 19 | #endif 20 | 21 | protected: 22 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 23 | 24 | 25 | // 实现 26 | protected: 27 | HICON m_hIcon; 28 | 29 | // 生成的消息映射函数 30 | virtual BOOL OnInitDialog(); 31 | afx_msg void OnSysCommand(UINT nID, LPARAM lParam); 32 | afx_msg void OnPaint(); 33 | afx_msg HCURSOR OnQueryDragIcon(); 34 | DECLARE_MESSAGE_MAP() 35 | 36 | private: 37 | UINT m_port; 38 | CIPAddressCtrl m_listenAddr; 39 | CFiberServer* m_listenFiber; 40 | int m_fiberCount; 41 | int m_ioCount; 42 | int m_ioCurrent; 43 | CProgressCtrl m_ioProgress; 44 | 45 | int m_fiberDone; 46 | int m_ioDone; 47 | 48 | void InitFiber(); 49 | void StopFiber(); 50 | 51 | public: 52 | void OnFiberIo(); 53 | void OnFiberConnectDone(); 54 | 55 | public: 56 | afx_msg void OnBnClickedListen(); 57 | afx_msg void OnBnClickedStopListen(); 58 | afx_msg void OnBnClickedOk(); 59 | afx_msg void OnBnClickedCancel(); 60 | afx_msg void OnBnClickedConnect(); 61 | }; 62 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/FiberClient.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FiberClient.h" 3 | 4 | CFiberClient::CFiberClient(SOCKET s) 5 | : m_sock(s) 6 | { 7 | } 8 | 9 | CFiberClient::~CFiberClient(void) 10 | { 11 | closesocket(m_sock); 12 | } 13 | 14 | void CFiberClient::run(void) 15 | { 16 | char buf[8192]; 17 | while (true) { 18 | int ret = recv(m_sock, buf, sizeof(buf), 0); 19 | if (ret <= 0) { 20 | break; 21 | } 22 | 23 | if (send(m_sock, buf, ret, 0) == -1) { 24 | break; 25 | } 26 | } 27 | 28 | delete this; 29 | } 30 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/FiberClient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CFiberClient : public acl::fiber 4 | { 5 | public: 6 | CFiberClient(SOCKET sock); 7 | 8 | private: 9 | ~CFiberClient(void); 10 | 11 | protected: 12 | void run(void); 13 | 14 | private: 15 | SOCKET m_sock; 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/FiberConnect.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "EchoServerDlg.h" 3 | #include "FiberConnect.h" 4 | 5 | CFiberConnect::CFiberConnect(CEchoServerDlg& dlg, const CString& ip, 6 | UINT port, int ioCount) 7 | : m_dlg(dlg) 8 | , m_ip(ip) 9 | , m_port(port) 10 | , m_ioCount(ioCount) 11 | { 12 | } 13 | 14 | CFiberConnect::~CFiberConnect(void) 15 | { 16 | } 17 | 18 | bool CFiberConnect::Start(void) 19 | { 20 | struct sockaddr_in in; 21 | in.sin_family = AF_INET; 22 | in.sin_port = htons(m_port); 23 | if (inet_pton(AF_INET, m_ip.GetString(), &in.sin_addr) == -1) { 24 | return false; 25 | } 26 | 27 | SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); 28 | if (sock == INVALID_SOCKET) { 29 | return false; 30 | } 31 | 32 | if (connect(sock, (const sockaddr*)&in, sizeof(in)) == -1) { 33 | closesocket(sock); 34 | return false; 35 | } 36 | 37 | const char data[] = "hello world!\r\n"; 38 | char buf[256]; 39 | int i; 40 | for (i = 0; i < m_ioCount; i++) { 41 | int ret = send(sock, data, sizeof(data) - 1, 0); 42 | if (ret == -1) { 43 | break; 44 | } 45 | ret = recv(sock, buf, sizeof(buf), 0); 46 | if (ret <= 0) { 47 | break; 48 | } 49 | m_dlg.OnFiberIo(); 50 | } 51 | 52 | closesocket(sock); 53 | m_dlg.OnFiberConnectDone(); 54 | return true; 55 | } 56 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/FiberConnect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CEchoServerDlg; 4 | 5 | class CFiberConnect 6 | { 7 | public: 8 | CFiberConnect(CEchoServerDlg& dlg, const CString& ip, 9 | UINT port, int ioCount); 10 | ~CFiberConnect(void); 11 | 12 | bool Start(void); 13 | 14 | private: 15 | CEchoServerDlg& m_dlg; 16 | CString m_ip; 17 | UINT m_port; 18 | int m_ioCount; 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/FiberServer.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FiberClient.h" 3 | #include "FiberServer.h" 4 | 5 | CFiberServer::CFiberServer(bool autoDestroy /* = true */) 6 | : m_sock(INVALID_SOCKET) 7 | , m_autoDestroy(autoDestroy) 8 | { 9 | } 10 | 11 | CFiberServer::~CFiberServer(void) 12 | { 13 | if (m_sock != INVALID_SOCKET) { 14 | closesocket(m_sock); 15 | } 16 | } 17 | 18 | bool CFiberServer::BindAndListen(UINT port, const CString& addr) 19 | { 20 | SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); 21 | if (sock == INVALID_SOCKET) { 22 | return false; 23 | } 24 | 25 | struct sockaddr_in in; 26 | in.sin_family = AF_INET; 27 | in.sin_port = htons(port); 28 | if (inet_pton(AF_INET, addr.GetString(), &in.sin_addr) == -1) { 29 | closesocket(sock); 30 | return false; 31 | } 32 | 33 | if (bind(sock, (const sockaddr*) &in, sizeof(in)) == -1) { 34 | closesocket(sock); 35 | return false; 36 | } 37 | 38 | if (listen(sock, 128) == -1) { 39 | return false; 40 | } 41 | 42 | m_sock = sock; 43 | return true; 44 | } 45 | 46 | void CFiberServer::run(void) 47 | { 48 | while (true) { 49 | SOCKET s = accept(m_sock, NULL, NULL); 50 | if (s == INVALID_SOCKET) { 51 | break; 52 | } 53 | 54 | acl::fiber* fb = new CFiberClient(s); 55 | fb->start(); 56 | } 57 | 58 | if (m_autoDestroy) { 59 | delete this; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/FiberServer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CFiberServer : public acl::fiber 4 | { 5 | public: 6 | CFiberServer(bool autoDestroy = true); 7 | ~CFiberServer(void); 8 | 9 | bool BindAndListen(UINT port, const CString& addr); 10 | 11 | protected: 12 | // @override 13 | void run(void); 14 | 15 | private: 16 | SOCKET m_sock; 17 | bool m_autoDestroy; 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef VC_EXTRALEAN 4 | #define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料 5 | #endif 6 | 7 | #include "targetver.h" 8 | 9 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的 10 | 11 | // 关闭 MFC 的一些常见且经常可放心忽略的隐藏警告消息 12 | #define _AFX_ALL_WARNINGS 13 | 14 | #include // MFC 核心组件和标准组件 15 | #include // MFC 扩展 16 | 17 | 18 | #include // MFC 自动化类 19 | 20 | 21 | 22 | #ifndef _AFX_NO_OLE_SUPPORT 23 | #include // MFC 对 Internet Explorer 4 公共控件的支持 24 | #endif 25 | #ifndef _AFX_NO_AFXCMN_SUPPORT 26 | #include // MFC 对 Windows 公共控件的支持 27 | #endif // _AFX_NO_AFXCMN_SUPPORT 28 | 29 | #include // MFC 支持功能区和控制条 30 | 31 | 32 | #include // MFC 套接字扩展 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | #ifdef _UNICODE 41 | #if defined _M_IX86 42 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") 43 | #elif defined _M_X64 44 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") 45 | #else 46 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 47 | #endif 48 | #endif 49 | 50 | 51 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: 与预编译标头对应的源文件 2 | 3 | #include "pch.h" 4 | 5 | // 当使用预编译的头时,需要使用此源文件,编译才能成功。 6 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: 这是预编译标头文件。 2 | // 下方列出的文件仅编译一次,提高了将来生成的生成性能。 3 | // 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。 4 | // 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。 5 | // 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | // 添加要在此处预编译的标头 11 | 12 | #include "framework.h" 13 | #include "fiber/libfiber.hpp" 14 | #include "fiber/go_fiber.hpp" 15 | 16 | #endif //PCH_H 17 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/res/EchoServer.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/gui/EchoServer/res/EchoServer.ico -------------------------------------------------------------------------------- /samples/gui/EchoServer/res/EchoServer.rc2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/gui/EchoServer/res/EchoServer.rc2 -------------------------------------------------------------------------------- /samples/gui/EchoServer/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ 生成的包含文件。 3 | // 供 EchoServer.rc 使用 4 | // 5 | #define IDM_ABOUTBOX 0x0010 6 | #define IDD_ABOUTBOX 100 7 | #define IDS_ABOUTBOX 101 8 | #define IDD_ECHOSERVER_DIALOG 102 9 | #define IDP_SOCKETS_INIT_FAILED 103 10 | #define IDR_MAINFRAME 128 11 | #define IDC_LISTEN 1000 12 | #define IDC_IPADDR 1001 13 | #define IDC_PORT 1002 14 | #define IDC_STOP_LISTEN 1003 15 | #define IDC_CONNECT 1004 16 | #define IDC_FIBERS 1005 17 | #define IDC_COUNT 1006 18 | #define IDC_PROGRESS 1007 19 | #define IDC_COUNT2 1008 20 | #define IDC_IO_COUNT 1008 21 | 22 | // Next default values for new objects 23 | // 24 | #ifdef APSTUDIO_INVOKED 25 | #ifndef APSTUDIO_READONLY_SYMBOLS 26 | #define _APS_NEXT_RESOURCE_VALUE 130 27 | #define _APS_NEXT_COMMAND_VALUE 32771 28 | #define _APS_NEXT_CONTROL_VALUE 1008 29 | #define _APS_NEXT_SYMED_VALUE 101 30 | #endif 31 | #endif 32 | -------------------------------------------------------------------------------- /samples/gui/EchoServer/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。 4 | 5 | //如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并 6 | // 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/FiberClient.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FiberClient.h" 3 | 4 | CFiberClient::CFiberClient(SOCKET s) 5 | : m_sock(s) 6 | { 7 | } 8 | 9 | CFiberClient::~CFiberClient(void) 10 | { 11 | closesocket(m_sock); 12 | } 13 | 14 | void CFiberClient::run(void) 15 | { 16 | char buf[8192]; 17 | while (true) { 18 | int ret = recv(m_sock, buf, sizeof(buf), 0); 19 | if (ret <= 0) { 20 | break; 21 | } 22 | 23 | if (send(m_sock, buf, ret, 0) == -1) { 24 | break; 25 | } 26 | } 27 | 28 | delete this; 29 | } 30 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/FiberClient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class CFiberClient : public acl::fiber 6 | { 7 | public: 8 | CFiberClient(SOCKET sock); 9 | 10 | private: 11 | ~CFiberClient(void); 12 | 13 | protected: 14 | void run(void); 15 | 16 | private: 17 | SOCKET m_sock; 18 | }; 19 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/FiberConnect.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FiberConnect.h" 3 | 4 | CFiberConnect::CFiberConnect(const char* ip, int port, int count) 5 | : ip_(ip) 6 | , port_(port) 7 | , count_(count) 8 | { 9 | } 10 | 11 | CFiberConnect::~CFiberConnect(void) {} 12 | 13 | bool CFiberConnect::Start(void) 14 | { 15 | struct sockaddr_in in; 16 | in.sin_family = AF_INET; 17 | in.sin_port = htons(port_); 18 | if (inet_pton(AF_INET, ip_.c_str(), &in.sin_addr) == -1) { 19 | printf("invalid ip = % s\r\n", ip_.c_str()); 20 | return false; 21 | } 22 | 23 | SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); 24 | if (sock == INVALID_SOCKET) { 25 | return false; 26 | } 27 | 28 | if (connect(sock, (const sockaddr*)&in, sizeof(in)) == -1) { 29 | closesocket(sock); 30 | printf("connect %s:%d error\r\n", ip_.c_str(), port_); 31 | return false; 32 | } 33 | 34 | printf(">>>connect %s:%d ok\r\n", ip_.c_str(), port_); 35 | 36 | const char data[] = "hello world!\r\n"; 37 | char buf[256]; 38 | int i; 39 | for (i = 0; i < count_; i++) { 40 | int ret = send(sock, data, sizeof(data) - 1, 0); 41 | if (ret == -1) { 42 | break; 43 | } 44 | ret = recv(sock, buf, sizeof(buf), 0); 45 | if (ret <= 0) { 46 | break; 47 | } 48 | if (i % 1000 == 0) { 49 | printf(">>>current io=%d, thread=%d, fiber=%d\r\n", 50 | i, GetCurrentThreadId(), acl::fiber::self()); 51 | } 52 | } 53 | 54 | closesocket(sock); 55 | printf(">>>All over count=%d, %d\r\n", count_, i); 56 | return true; 57 | } 58 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/FiberConnect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CFiberConnect 4 | { 5 | public: 6 | CFiberConnect(const char* ip, int port, int count); 7 | ~CFiberConnect(void); 8 | 9 | bool Start(void); 10 | 11 | private: 12 | std::string ip_; 13 | int port_; 14 | int count_; 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/FiberServer.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FiberClient.h" 3 | #include "FiberServer.h" 4 | 5 | CFiberServer::CFiberServer(bool autoDestroy /* = true */) 6 | : m_sock(INVALID_SOCKET) 7 | , m_autoDestroy(autoDestroy) 8 | { 9 | } 10 | 11 | CFiberServer::~CFiberServer(void) 12 | { 13 | if (m_sock != INVALID_SOCKET) { 14 | closesocket(m_sock); 15 | } 16 | } 17 | 18 | bool CFiberServer::BindAndListen(int port, const std::string& addr) 19 | { 20 | SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); 21 | if (sock == INVALID_SOCKET) { 22 | return false; 23 | } 24 | 25 | struct sockaddr_in in; 26 | in.sin_family = AF_INET; 27 | in.sin_port = htons(port); 28 | if (inet_pton(AF_INET, addr.c_str(), &in.sin_addr) == -1) { 29 | closesocket(sock); 30 | return false; 31 | } 32 | 33 | if (bind(sock, (const sockaddr*)&in, sizeof(in)) == -1) { 34 | closesocket(sock); 35 | return false; 36 | } 37 | 38 | if (listen(sock, 128) == -1) { 39 | return false; 40 | } 41 | 42 | m_sock = sock; 43 | return true; 44 | } 45 | 46 | void CFiberServer::run(void) 47 | { 48 | while (true) { 49 | SOCKET s = accept(m_sock, NULL, NULL); 50 | if (s == INVALID_SOCKET) { 51 | break; 52 | } 53 | 54 | acl::fiber* fb = new CFiberClient(s); 55 | fb->start(); 56 | } 57 | 58 | if (m_autoDestroy) { 59 | delete this; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/FiberServer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CFiberServer : public acl::fiber 4 | { 5 | public: 6 | CFiberServer(bool autoDestroy = true); 7 | ~CFiberServer(void); 8 | 9 | bool BindAndListen(int port, const std::string& addr); 10 | 11 | protected: 12 | // @override 13 | void run(void); 14 | 15 | private: 16 | SOCKET m_sock; 17 | bool m_autoDestroy; 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/Resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ 生成的包含文件。 3 | // 供 SimpleWin.rc 使用 4 | // 5 | #define IDC_MYICON 2 6 | #define IDD_SIMPLEWIN_DIALOG 102 7 | #define IDS_APP_TITLE 103 8 | #define IDD_ABOUTBOX 103 9 | #define IDM_ABOUT 104 10 | #define IDM_EXIT 105 11 | #define IDI_SIMPLEWIN 107 12 | #define IDI_SMALL 108 13 | #define IDC_SIMPLEWIN 109 14 | #define IDR_MAINFRAME 128 15 | #define ID_Menu 32771 16 | #define IDM_START_LISTENER 32775 17 | #define IDM_STOP_LISTENER 32776 18 | #define IDM_OPEN_DOS 32777 19 | #define IDM_CLOSE_DOS 32778 20 | #define IDM_START_CONNECT 32779 21 | #define IDM_RESOLVE_THREAD 32780 22 | #define IDM_RESOLVE_FIBER 32781 23 | #define IDC_STATIC -1 24 | 25 | // Next default values for new objects 26 | // 27 | #ifdef APSTUDIO_INVOKED 28 | #ifndef APSTUDIO_READONLY_SYMBOLS 29 | #define _APS_NO_MFC 1 30 | #define _APS_NEXT_RESOURCE_VALUE 129 31 | #define _APS_NEXT_COMMAND_VALUE 32782 32 | #define _APS_NEXT_CONTROL_VALUE 1000 33 | #define _APS_NEXT_SYMED_VALUE 110 34 | #endif 35 | #endif 36 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/SimpleWin.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "resource.h" 4 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/SimpleWin.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/gui/SimpleWin/SimpleWin.ico -------------------------------------------------------------------------------- /samples/gui/SimpleWin/SimpleWin.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/gui/SimpleWin/SimpleWin.rc -------------------------------------------------------------------------------- /samples/gui/SimpleWin/SimpleWin.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 头文件 20 | 21 | 22 | 头文件 23 | 24 | 25 | 头文件 26 | 27 | 28 | 头文件 29 | 30 | 31 | 头文件 32 | 33 | 34 | 头文件 35 | 36 | 37 | 头文件 38 | 39 | 40 | 头文件 41 | 42 | 43 | 44 | 45 | 源文件 46 | 47 | 48 | 源文件 49 | 50 | 51 | 源文件 52 | 53 | 54 | 源文件 55 | 56 | 57 | 源文件 58 | 59 | 60 | 61 | 62 | 资源文件 63 | 64 | 65 | 66 | 67 | 资源文件 68 | 69 | 70 | 资源文件 71 | 72 | 73 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "targetver.h" 4 | #define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 5 | // Windows 头文件 6 | #include 7 | // C 运行时头文件 8 | #include 9 | #include 10 | #include 11 | #include 12 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: 与预编译标头对应的源文件 2 | 3 | #include "pch.h" 4 | 5 | // 当使用预编译的头时,需要使用此源文件,编译才能成功。 6 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: 这是预编译标头文件。 2 | // 下方列出的文件仅编译一次,提高了将来生成的生成性能。 3 | // 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。 4 | // 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。 5 | // 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | // 添加要在此处预编译的标头 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "framework.h" 17 | #include "fiber/libfiber.hpp" 18 | #include "fiber/go_fiber.hpp" 19 | 20 | #endif //PCH_H 21 | -------------------------------------------------------------------------------- /samples/gui/SimpleWin/small.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iqiyi/libfiber/438313f6699f1e28b2c2902017c8bbe05d9ec7b0/samples/gui/SimpleWin/small.ico -------------------------------------------------------------------------------- /samples/gui/SimpleWin/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // // 包含 SDKDDKVer.h 可定义可用的最高版本的 Windows 平台。 4 | // 如果希望为之前的 Windows 平台构建应用程序,在包含 SDKDDKVer.h 之前请先包含 WinSDKVer.h 并 5 | // 将 _WIN32_WINNT 宏设置为想要支持的平台。 6 | #include 7 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/25. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/25. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | #pragma mark - UISceneSession lifecycle 25 | 26 | 27 | - (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { 28 | // Called when a new scene session is being created. 29 | // Use this method to select a configuration to create the new scene with. 30 | return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role]; 31 | } 32 | 33 | 34 | - (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions { 35 | // Called when the user discards a scene session. 36 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 37 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 38 | } 39 | 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/FiberClient.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FiberClient.cpp 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/26. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include "fiber/libfiber.hpp" 12 | #include "FiberClient.hpp" 13 | 14 | void FiberClient::run(void) { 15 | printf("FiberClient run, fd=%d\r\n", fd_); 16 | char buf[8192]; 17 | while (true) { 18 | ssize_t ret = read(fd_, buf, sizeof(buf)); 19 | if (ret <= 0) { 20 | break; 21 | } 22 | if (write(fd_, buf, ret) <= 0) { 23 | break; 24 | } 25 | } 26 | printf("Close client fd=%d\r\n", fd_); 27 | close(fd_); 28 | delete this; 29 | } 30 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/FiberClient.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // FiberClient.hpp 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/26. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #ifndef FiberClient_hpp 10 | #define FiberClient_hpp 11 | 12 | class FiberClient : public acl::fiber { 13 | public: 14 | FiberClient(int fd) : fd_(fd) {} 15 | 16 | protected: 17 | // @override 18 | void run(void); 19 | 20 | ~FiberClient(void) {} 21 | 22 | private: 23 | int fd_; 24 | }; 25 | 26 | #endif /* FiberClient_hpp */ 27 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/FiberServer.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FiberServer.cpp 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/26. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include "fiber/libfiber.hpp" 13 | #include "FiberClient.hpp" 14 | #include "FiberServer.hpp" 15 | 16 | FiberServer::FiberServer(const char* ip, int port) 17 | : ip_(ip), port_(port), lfd_(-1) {} 18 | 19 | int FiberServer::BindAndrListen(const char *ip, int port) { 20 | int fd; 21 | int on; 22 | struct sockaddr_in sa; 23 | 24 | memset(&sa, 0, sizeof(sa)); 25 | sa.sin_family = AF_INET; 26 | sa.sin_port = htons(port); 27 | sa.sin_addr.s_addr = inet_addr(ip); 28 | 29 | fd = socket(AF_INET, SOCK_STREAM, 0); 30 | if (fd == -1) { 31 | printf("create socket error, %s\r\n", acl::fiber::last_serror()); 32 | return -1; 33 | } 34 | 35 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) { 36 | printf("setsockopt error %s\r\n", acl::fiber::last_serror()); 37 | close(fd); 38 | return -1; 39 | } 40 | 41 | if (bind(fd, (struct sockaddr *) &sa, sizeof(struct sockaddr)) < 0) { 42 | printf("bind error %s\r\n", acl::fiber::last_serror()); 43 | close(fd); 44 | return -1; 45 | } 46 | 47 | if (listen(fd, 1024) < 0) { 48 | printf("listen error %s\r\n", acl::fiber::last_serror()); 49 | close(fd); 50 | return -1; 51 | } 52 | 53 | return fd; 54 | } 55 | 56 | void FiberServer::run(void) { 57 | lfd_ = BindAndrListen(ip_.c_str(), port_); 58 | if (lfd_ == -1) { 59 | return; 60 | } 61 | 62 | printf("listen %s:%d ok\r\n", ip_.c_str(), port_); 63 | 64 | while (true) { 65 | struct sockaddr_in sa; 66 | size_t len = sizeof(sa); 67 | int fd = accept(lfd_, (struct sockaddr *)& sa, (socklen_t *)& len); 68 | if (fd == -1) { 69 | printf("accept error\r\n"); 70 | break; 71 | } 72 | printf("Accept on fd=%d\r\n", fd); 73 | FiberClient* fb = new FiberClient(fd); 74 | fb->start(); 75 | } 76 | close(lfd_); 77 | delete this; 78 | } 79 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/FiberServer.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // FiberServer.hpp 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/26. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #ifndef FiberServer_hpp 10 | #define FiberServer_hpp 11 | 12 | #include 13 | 14 | class FiberServer : public acl::fiber { 15 | public: 16 | FiberServer(const char* ip, int port); 17 | 18 | protected: 19 | // @override 20 | void run(void); 21 | 22 | ~FiberServer(void) {} 23 | 24 | private: 25 | std::string ip_; 26 | int port_; 27 | int lfd_; 28 | 29 | int BindAndrListen(const char *ip, int port); 30 | }; 31 | 32 | #endif /* FiberServer_hpp */ 33 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/FiberTest.h: -------------------------------------------------------------------------------- 1 | // 2 | // FiberTest.h 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/26. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #ifndef FiberTest_h 10 | #define FiberTest_h 11 | 12 | @interface FiberTest : NSObject 13 | 14 | -(void) Start; 15 | 16 | @end 17 | 18 | #endif /* FiberTest_h */ 19 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/FiberTest.mm: -------------------------------------------------------------------------------- 1 | // 2 | // FiberTest.m 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/26. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #import 10 | #include "FiberThread.hpp" 11 | #include "FiberTest.h" 12 | 13 | @implementation FiberTest 14 | 15 | -(void) Start 16 | { 17 | StartThread(); 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/FiberThread.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FiberTest.cpp 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/26. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "fiber/libfiber.hpp" 11 | #include "FiberServer.hpp" 12 | #include "FiberThread.hpp" 13 | 14 | static void ThreadRun(void) { 15 | const char* ip = "127.0.0.1"; 16 | int port = 8192; 17 | FiberServer* fb = new FiberServer(ip, port); 18 | fb->start(); 19 | 20 | acl::fiber::schedule(); 21 | } 22 | 23 | void StartThread(void) { 24 | std::thread* thread = new std::thread(ThreadRun); 25 | thread->detach(); 26 | } 27 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/FiberThread.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // FiberTest.hpp 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/26. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #ifndef FiberTest_hpp 10 | #define FiberTest_hpp 11 | 12 | #include 13 | 14 | void StartThread(void); 15 | 16 | #endif /* FiberTest_hpp */ 17 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIMainStoryboardFile 45 | Main 46 | UIRequiredDeviceCapabilities 47 | 48 | armv7 49 | 50 | UISupportedInterfaceOrientations 51 | 52 | UIInterfaceOrientationPortrait 53 | UIInterfaceOrientationLandscapeLeft 54 | UIInterfaceOrientationLandscapeRight 55 | 56 | UISupportedInterfaceOrientations~ipad 57 | 58 | UIInterfaceOrientationPortrait 59 | UIInterfaceOrientationPortraitUpsideDown 60 | UIInterfaceOrientationLandscapeLeft 61 | UIInterfaceOrientationLandscapeRight 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/SceneDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.h 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/25. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SceneDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow * window; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/SceneDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.m 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/25. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #import "SceneDelegate.h" 10 | 11 | @interface SceneDelegate () 12 | 13 | @end 14 | 15 | @implementation SceneDelegate 16 | 17 | 18 | - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { 19 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 20 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 21 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 22 | } 23 | 24 | 25 | - (void)sceneDidDisconnect:(UIScene *)scene { 26 | // Called as the scene is being released by the system. 27 | // This occurs shortly after the scene enters the background, or when its session is discarded. 28 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 29 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 30 | } 31 | 32 | 33 | - (void)sceneDidBecomeActive:(UIScene *)scene { 34 | // Called when the scene has moved from an inactive state to an active state. 35 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 36 | } 37 | 38 | 39 | - (void)sceneWillResignActive:(UIScene *)scene { 40 | // Called when the scene will move from an active state to an inactive state. 41 | // This may occur due to temporary interruptions (ex. an incoming phone call). 42 | } 43 | 44 | 45 | - (void)sceneWillEnterForeground:(UIScene *)scene { 46 | // Called as the scene transitions from the background to the foreground. 47 | // Use this method to undo the changes made on entering the background. 48 | } 49 | 50 | 51 | - (void)sceneDidEnterBackground:(UIScene *)scene { 52 | // Called as the scene transitions from the foreground to the background. 53 | // Use this method to save data, release shared resources, and store enough scene-specific state information 54 | // to restore the scene back to its current state. 55 | } 56 | 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/25. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/25. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "FiberTest.h" 11 | 12 | @interface ViewController () 13 | 14 | @end 15 | 16 | @implementation ViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | // Do any additional setup after loading the view. 21 | FiberTest *test = [[FiberTest alloc] init]; 22 | [test Start]; 23 | } 24 | 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_server/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // fiber_server 4 | // 5 | // Created by shuxin   zheng on 2020/9/25. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | NSString * appDelegateClassName; 14 | @autoreleasepool { 15 | // Setup code that might create autoreleased objects goes here. 16 | appDelegateClassName = NSStringFromClass([AppDelegate class]); 17 | } 18 | return UIApplicationMain(argc, argv, nil, appDelegateClassName); 19 | } 20 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_serverUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /samples/xcode/fiber_server/fiber_serverUITests/fiber_serverUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // fiber_serverUITests.m 3 | // fiber_serverUITests 4 | // 5 | // Created by shuxin   zheng on 2020/9/25. 6 | // Copyright © 2020 acl. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface fiber_serverUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation fiber_serverUITests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | 20 | // In UI tests it is usually best to stop immediately when a failure occurs. 21 | self.continueAfterFailure = NO; 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | - (void)tearDown { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | } 29 | 30 | - (void)testExample { 31 | // UI tests must launch the application that they test. 32 | XCUIApplication *app = [[XCUIApplication alloc] init]; 33 | [app launch]; 34 | 35 | // Use recording to get started writing UI tests. 36 | // Use XCTAssert and related functions to verify your tests produce the correct results. 37 | } 38 | 39 | - (void)testLaunchPerformance { 40 | if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { 41 | // This measures how long it takes to launch your application. 42 | [self measureWithMetrics:@[XCTOSSignpostMetric.applicationLaunchMetric] block:^{ 43 | [[[XCUIApplication alloc] init] launch]; 44 | }]; 45 | } 46 | } 47 | 48 | @end 49 | --------------------------------------------------------------------------------