From fcb36493b1dd66b90b44ffa1e08cd05fa3387e59 Mon Sep 17 00:00:00 2001 From: zsxxsz Date: Sat, 30 Dec 2017 23:30:30 +0800 Subject: [PATCH] fiber: rewrite fiber's framework for imgrating to windows --- acl_cpp_vc2012.sln | 35 +- acl_cpp_vc2013.sln | 27 ++ lib_fiber/c/include/fiber/lib_fiber.h | 436 +++++++++++++------------ lib_fiber/c/lib_fiber.vcxproj | 154 +++++++++ lib_fiber/c/lib_fiber.vcxproj.filters | 240 ++++++++++++++ lib_fiber/c/src/common.h | 2 + lib_fiber/c/src/common/argv.c | 8 +- lib_fiber/c/src/common/atomic.c | 11 +- lib_fiber/c/src/common/close_on_exec.c | 7 +- lib_fiber/c/src/common/doze.c | 9 +- lib_fiber/c/src/common/fifo.c | 341 +++++++++++++++++++ lib_fiber/c/src/common/fifo.h | 150 +++++++++ lib_fiber/c/src/common/gettimeofday.c | 143 ++++++++ lib_fiber/c/src/common/gettimeofday.h | 10 + lib_fiber/c/src/common/init.c | 7 +- lib_fiber/c/src/common/iostuff.h | 3 + lib_fiber/c/src/common/memory.c | 89 +++++ lib_fiber/c/src/common/memory.h | 8 + lib_fiber/c/src/common/msg.c | 24 +- lib_fiber/c/src/common/non_blocking.c | 17 +- lib_fiber/c/src/common/open_limit.c | 18 +- lib_fiber/c/src/common/pthread.c | 305 +++++++++++++++++ lib_fiber/c/src/common/pthread.h | 50 +++ lib_fiber/c/src/common/socketpair.c | 4 + lib_fiber/c/src/define.h | 31 +- lib_fiber/c/src/dns/dns.c | 155 ++++++--- lib_fiber/c/src/dns/dns.h | 9 + lib_fiber/c/src/event.c | 14 +- lib_fiber/c/src/event.h | 33 +- lib_fiber/c/src/fiber.c | 418 +++++------------------- lib_fiber/c/src/fiber.h | 27 +- lib_fiber/c/src/fiber/fiber_unix.c | 254 ++++++++++++++ lib_fiber/c/src/fiber/fiber_win.c | 1 + lib_fiber/c/src/fiber_event.c | 6 +- lib_fiber/c/src/fiber_io.c | 7 +- lib_fiber/c/src/fiber_lock.c | 4 + lib_fiber/c/src/fiber_sem.c | 4 +- lib_fiber/c/src/file_event.c | 2 + lib_fiber/c/src/hook/dns_init.c | 12 +- lib_fiber/c/src/hook/getaddrinfo.c | 5 +- lib_fiber/c/src/hook/gethostbyname.c | 8 +- lib_fiber/c/src/hook/io.c | 40 ++- lib_fiber/c/src/hook/poll.c | 3 + lib_fiber/c/src/hook/select.c | 4 + lib_fiber/c/src/hook/socket.c | 4 + lib_fiber/c/src/stdafx.h | 65 ++-- 46 files changed, 2476 insertions(+), 728 deletions(-) create mode 100644 lib_fiber/c/lib_fiber.vcxproj create mode 100644 lib_fiber/c/lib_fiber.vcxproj.filters create mode 100644 lib_fiber/c/src/common/fifo.c create mode 100644 lib_fiber/c/src/common/fifo.h create mode 100644 lib_fiber/c/src/common/gettimeofday.c create mode 100644 lib_fiber/c/src/common/gettimeofday.h create mode 100644 lib_fiber/c/src/common/memory.c create mode 100644 lib_fiber/c/src/common/memory.h create mode 100644 lib_fiber/c/src/common/pthread.c create mode 100644 lib_fiber/c/src/common/pthread.h create mode 100644 lib_fiber/c/src/fiber/fiber_unix.c create mode 100644 lib_fiber/c/src/fiber/fiber_win.c diff --git a/acl_cpp_vc2012.sln b/acl_cpp_vc2012.sln index 8fc86fd4b..0a5f5e7e1 100644 --- a/acl_cpp_vc2012.sln +++ b/acl_cpp_vc2012.sln @@ -717,6 +717,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dispatch_manager", "app\mas EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{53F31C86-0F18-49EB-B7F9-6E00D92DF39F}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_fiber", "lib_fiber\c\lib_fiber.vcxproj", "{AD99B75A-40BF-46DC-844B-23417FDC8690}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Mixed Platforms = Debug|Mixed Platforms @@ -3491,11 +3493,38 @@ Global {B59C7CB6-5708-4522-B833-CEB160AA4817}.Template|Win32.Build.0 = DebugDll|Win32 {B59C7CB6-5708-4522-B833-CEB160AA4817}.Template|x64.ActiveCfg = DebugDll|x64 {B59C7CB6-5708-4522-B833-CEB160AA4817}.Template|x64.Build.0 = DebugDll|x64 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Debug|Win32.ActiveCfg = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Debug|Win32.Build.0 = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Debug|x64.ActiveCfg = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.DebugDll|Mixed Platforms.ActiveCfg = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.DebugDll|Mixed Platforms.Build.0 = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.DebugDll|Win32.ActiveCfg = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.DebugDll|Win32.Build.0 = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.DebugDll|x64.ActiveCfg = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Release|Mixed Platforms.Build.0 = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Release|Win32.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Release|Win32.Build.0 = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Release|x64.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Releasedll|Mixed Platforms.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Releasedll|Mixed Platforms.Build.0 = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Releasedll|Win32.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Releasedll|Win32.Build.0 = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Releasedll|x64.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Template|Mixed Platforms.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Template|Mixed Platforms.Build.0 = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Template|Win32.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Template|Win32.Build.0 = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Template|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {324E7B70-E11C-4A39-A11F-4BB2A8E70064} = {53F31C86-0F18-49EB-B7F9-6E00D92DF39F} + {267F658E-44AF-4080-8577-EFCE99A5E030} = {53F31C86-0F18-49EB-B7F9-6E00D92DF39F} {02535D96-1693-4AA3-B650-B22DC776FDC2} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064} {840C2263-DF87-4FD2-8964-EF81B74695FE} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064} {5F4063AD-B591-4C64-ADEA-609968A83550} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064} @@ -3518,15 +3547,15 @@ Global {B6BE4E77-F69D-43B0-BE8A-77A8AA61A89E} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064} {A7459536-E4FE-4ECE-A721-EE49DBA0CF95} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064} {3C576B18-D253-4CA2-986E-7173C2978AC3} = {324E7B70-E11C-4A39-A11F-4BB2A8E70064} - {956FA905-A77F-41FE-A4BE-C3BD3B5B3E83} = {02535D96-1693-4AA3-B650-B22DC776FDC2} {225D0BFA-64D7-4F8F-951E-36A494CF6178} = {02535D96-1693-4AA3-B650-B22DC776FDC2} {ADE6F714-BD52-432D-AB86-62FA59AB6746} = {02535D96-1693-4AA3-B650-B22DC776FDC2} - {9A04F86E-D4CB-45ED-9BB6-9939B9400B6F} = {02535D96-1693-4AA3-B650-B22DC776FDC2} {BE2DF8B2-2DCD-4F32-99B9-0B0CA24BFAD9} = {02535D96-1693-4AA3-B650-B22DC776FDC2} + {956FA905-A77F-41FE-A4BE-C3BD3B5B3E83} = {02535D96-1693-4AA3-B650-B22DC776FDC2} {A07145B7-36AE-4D6F-8536-30A8BE48529D} = {02535D96-1693-4AA3-B650-B22DC776FDC2} {95F01BE0-DD1D-4671-8C22-BD420917401B} = {02535D96-1693-4AA3-B650-B22DC776FDC2} {9551BD86-0CCF-4C85-A630-4FCC5F5842C8} = {02535D96-1693-4AA3-B650-B22DC776FDC2} {82913F68-7612-4303-86B6-12BF5D61B0A3} = {02535D96-1693-4AA3-B650-B22DC776FDC2} + {9A04F86E-D4CB-45ED-9BB6-9939B9400B6F} = {02535D96-1693-4AA3-B650-B22DC776FDC2} {41FA5224-3315-4CDA-9C44-19085049F179} = {716AA69D-C8D2-4274-8207-A384FC20EAF0} {7680672C-4C9B-4BE8-8BAE-BB23B951AAA0} = {716AA69D-C8D2-4274-8207-A384FC20EAF0} {094E23DA-F097-4510-9977-0995B8502197} = {716AA69D-C8D2-4274-8207-A384FC20EAF0} @@ -3615,7 +3644,5 @@ Global {B4E00704-AE9F-40B0-964A-B0F9FF257AF9} = {3C576B18-D253-4CA2-986E-7173C2978AC3} {1B392F34-557F-44E2-8A47-B808C2EA4832} = {3C576B18-D253-4CA2-986E-7173C2978AC3} {20299269-7A1C-45CB-8807-861745A55F82} = {3C576B18-D253-4CA2-986E-7173C2978AC3} - {267F658E-44AF-4080-8577-EFCE99A5E030} = {53F31C86-0F18-49EB-B7F9-6E00D92DF39F} - {324E7B70-E11C-4A39-A11F-4BB2A8E70064} = {53F31C86-0F18-49EB-B7F9-6E00D92DF39F} EndGlobalSection EndGlobal diff --git a/acl_cpp_vc2013.sln b/acl_cpp_vc2013.sln index 0baa504e4..570ab7795 100644 --- a/acl_cpp_vc2013.sln +++ b/acl_cpp_vc2013.sln @@ -15,6 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{C65ABD0D-658 SAMPLES.md = SAMPLES.md EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_fiber", "lib_fiber\c\lib_fiber.vcxproj", "{AD99B75A-40BF-46DC-844B-23417FDC8690}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Mixed Platforms = Debug|Mixed Platforms @@ -109,6 +111,31 @@ Global {6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC}.Template|Win32.ActiveCfg = Release|Win32 {6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC}.Template|Win32.Build.0 = Release|Win32 {6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC}.Template|x64.ActiveCfg = Releasedll|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Debug|Win32.ActiveCfg = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Debug|Win32.Build.0 = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Debug|x64.ActiveCfg = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.DebugDll|Mixed Platforms.ActiveCfg = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.DebugDll|Mixed Platforms.Build.0 = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.DebugDll|Win32.ActiveCfg = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.DebugDll|Win32.Build.0 = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.DebugDll|x64.ActiveCfg = Debug|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Release|Mixed Platforms.Build.0 = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Release|Win32.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Release|Win32.Build.0 = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Release|x64.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Releasedll|Mixed Platforms.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Releasedll|Mixed Platforms.Build.0 = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Releasedll|Win32.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Releasedll|Win32.Build.0 = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Releasedll|x64.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Template|Mixed Platforms.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Template|Mixed Platforms.Build.0 = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Template|Win32.ActiveCfg = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Template|Win32.Build.0 = Release|Win32 + {AD99B75A-40BF-46DC-844B-23417FDC8690}.Template|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/lib_fiber/c/include/fiber/lib_fiber.h b/lib_fiber/c/include/fiber/lib_fiber.h index 6f66f602f..aa56c19c7 100644 --- a/lib_fiber/c/include/fiber/lib_fiber.h +++ b/lib_fiber/c/include/fiber/lib_fiber.h @@ -5,34 +5,38 @@ extern "C" { #endif +#if defined(_WIN32) || defined (_WIN64) +typedef long ssize; +#else #include #include +#endif //typedef struct ACL_VSTREAM ACL_VSTREAM; /** - * 协程结构类型 + * Э̽ṹ */ typedef struct ACL_FIBER ACL_FIBER; /** - * 设置是否需要 hook 系统中的 IO 相关的 API,内部缺省值为 1 - * @param onoff {int} 是否需要 hook + * ǷҪ hook ϵͳе IO ص APIڲȱʡֵΪ 1 + * @param onoff {int} ǷҪ hook */ void acl_fiber_hook_api(int onoff); /** - * 创建一个协程 - * @param fn {void (*)(ACL_FIBER*, void*)} 协程运行时的回调函数地址 - * @param arg {void*} 回调 fn 函数时的第二个参数 - * @param size {size_t} 所创建协程所占栈空间大小 + * һЭ + * @param fn {void (*)(ACL_FIBER*, void*)} ЭʱĻصַ + * @param arg {void*} ص fn ʱĵڶ + * @param size {size_t} ЭռջռС * @return {ACL_FIBER*} */ ACL_FIBER* acl_fiber_create(void (*fn)(ACL_FIBER*, void*), void* arg, size_t size); /** - * 返回当前线程中处于消亡状态的协程数 + * صǰ߳д״̬Э * @retur {int} */ int acl_fiber_ndead(void); @@ -40,318 +44,318 @@ int acl_fiber_ndead(void); void acl_fiber_check_timer(size_t max); /** - * 返回当前正在运行的协程对象 - * @retur {ACL_FIBER*} 返回 NULL 表示当前没有正在运行的协程 + * صǰеЭ̶ + * @retur {ACL_FIBER*} NULL ʾǰûеЭ */ ACL_FIBER* acl_fiber_running(void); /** - * 获得所给协程的协程 ID 号 - * @param fiber {const ACL_FIBER*} acl_fiber_create 创建的协程对象,必须非空 - * @return {unsigned int} 协程 ID 号 + * Э̵Э ID + * @param fiber {const ACL_FIBER*} acl_fiber_create Э̶󣬱ǿ + * @return {unsigned int} Э ID */ unsigned int acl_fiber_id(const ACL_FIBER* fiber); /** - * 获得当前所运行的协程的 ID 号 - * @return {unsigned int} 当前运行协程的 ID 号 + * õǰеЭ̵ ID + * @return {unsigned int} ǰЭ̵ ID */ unsigned int acl_fiber_self(void); /** - * 设置所给协程的错误号 - * @param fiber {ACL_FIBER*} 指定的协程对象,为 NULL 则使用当前运行的协程 - * @param errnum {int} 错误号 + * Э̵Ĵ + * @param fiber {ACL_FIBER*} ָЭ̶Ϊ NULL ʹõǰеЭ + * @param errnum {int} */ void acl_fiber_set_errno(ACL_FIBER* fiber, int errnum); /** - * 获得指定协程的错误号 - * @param fiber {ACL_FIBER*} 指定的协程对象,若为 NULL 则使用当前协程对象 - * @return {int} 所给协程错误号 + * ָЭ̵Ĵ + * @param fiber {ACL_FIBER*} ָЭ̶Ϊ NULL ʹõǰЭ̶ + * @return {int} Э̴ */ int acl_fiber_errno(ACL_FIBER* fiber); /** - * 获得当前系统级的 errno 号 + * õǰϵͳ errno * @return {int} */ int acl_fiber_sys_errno(void); /** - * 设置当前系统的 errno 号 + * õǰϵͳ errno * @param errnum {int} */ void acl_fiber_sys_errno_set(int errnum); /** - * 是否保持所指定协程的错误号,当设置为“保持”后,则该协程仅保持当前状态下的 - * 错误号,之后该协程的错误号 errno 将不再改变,走到再次调用本函数取消保持 - * @param fiber {ACL_FIBER*} 指定的协程对象,为 NULL 则使用当前运行的协程 - * @param yesno {int} 是否保持 + * Ƿ񱣳ָЭ̵ĴţΪ֡Эֵ̽ǰ״̬µ + * ţ֮Э̵Ĵ errno ٸı䣬ߵٴεñȡ + * @param fiber {ACL_FIBER*} ָЭ̶Ϊ NULL ʹõǰеЭ + * @param yesno {int} Ƿ񱣳 */ void acl_fiber_keep_errno(ACL_FIBER* fiber, int yesno); /** - * 获得指定协程的当前状态 - * @param fiber {const ACL_FIBER*} 指定的协程对象,为 NULL 则使用当前协程 - * @return {int} 协程状态 + * ָЭ̵ĵǰ״̬ + * @param fiber {const ACL_FIBER*} ָЭ̶Ϊ NULL ʹõǰЭ + * @return {int} Э״̬ */ int acl_fiber_status(const ACL_FIBER* fiber); /** - * 通知处于休眠状态的协程退出 - * @param fiber {const ACL_FIBER*} 指定的协程对象,必须非 NULL + * ֪ͨ״̬Э˳ + * @param fiber {const ACL_FIBER*} ָЭ̶󣬱 NULL */ void acl_fiber_kill(ACL_FIBER* fiber); /** - * 检查本协程是否被其它协程通知退出 - * @param fiber {const ACL_FIBER*} 指定的协程对象,若为 NULL 则自动使用当前 - * 正在运行的协程 - * @return {int} 返回值为 0 表示没有被通知退出,非 0 表示被通知退出 + * 鱾ЭǷЭ֪ͨ˳ + * @param fiber {const ACL_FIBER*} ָЭ̶Ϊ NULL Զʹõǰ + * еЭ + * @return {int} ֵΪ 0 ʾûб֪ͨ˳ 0 ʾ֪ͨ˳ */ int acl_fiber_killed(ACL_FIBER* fiber); /** - * 唤醒因 IO 等原因处于休眠的协程 - * @param fiber {const ACL_FIBER*} 协程对象,必须非 NULL - * @param signum {int} SIGINT, SIGKILL, SIGTERM ... 参考系统中 bits/signum.h + * IO ԭߵЭ + * @param fiber {const ACL_FIBER*} Э̶󣬱 NULL + * @param signum {int} SIGINT, SIGKILL, SIGTERM ... οϵͳ bits/signum.h */ void acl_fiber_signal(ACL_FIBER* fiber, int signum); /** - * 获得其它协程发送给指定协程的信号值 - * @param fiber {const ACL_FIBER*} 指定的协程对象,为 NULL 时则使用当前协程 - * @retur {int} 返回指定协程收到的信号值 + * Э̷͸ָЭ̵źֵ + * @param fiber {const ACL_FIBER*} ָЭ̶Ϊ NULL ʱʹõǰЭ + * @retur {int} ָЭյźֵ */ int acl_fiber_signum(ACL_FIBER* fiber); /** - * 将当前运行的协程挂起,由调度器选择下一个需要运行的协程 + * ǰеЭ̹ɵѡһҪеЭ * @return {int} */ int acl_fiber_yield(void); /** - * 将指定协程对象置入待运行队列中 - * @param fiber {ACL_FIBER*} 指定协程,必须非 NULL + * ָЭ̶ж + * @param fiber {ACL_FIBER*} ָЭ̣ NULL */ void acl_fiber_ready(ACL_FIBER* fiber); /** - * 将当前运行的协程挂起,同时执行等待队列下一个待运行的协程 + * ǰеЭ̹ͬʱִеȴһеЭ */ void acl_fiber_switch(void); /** - * 调用本函数启动协程的调度过程 + * ñЭ̵ĵȹ */ void acl_fiber_schedule(void); /** - * 调用本函数检测当前线程是否处于协程调度状态 - * @return {int} 0 表示非协程状态,非 0 表示处于协程调度状态 + * ñ⵱ǰ߳ǷЭ̵״̬ + * @return {int} 0 ʾЭ״̬ 0 ʾЭ̵״̬ */ int acl_fiber_scheduled(void); /** - * 停止协程过程 + * ֹͣЭ̹ */ void acl_fiber_schedule_stop(void); /** - * 使当前运行的协程休眠指定毫秒数 - * @param milliseconds {unsigned int} 指定要休眠的毫秒数 - * @return {unsigned int} 本协程休眠后再次被唤醒后剩余的毫秒数 + * ʹǰеЭָ + * @param milliseconds {unsigned int} ָҪߵĺ + * @return {unsigned int} ЭߺٴαѺʣĺ */ unsigned int acl_fiber_delay(unsigned int milliseconds); /** - * 使当前运行的协程休眠指定秒数 - * @param seconds {unsigned int} 指定要休眠的秒数 - * @return {unsigned int} 本协程休眠后再次被唤醒后剩余的秒数 + * ʹǰеЭָ + * @param seconds {unsigned int} ָҪߵ + * @return {unsigned int} ЭߺٴαѺʣ */ unsigned int acl_fiber_sleep(unsigned int seconds); /** - * 创建一个协程用作定时器 - * @param milliseconds {unsigned int} 所创建定时器被唤醒的毫秒数 - * @param size {size_t} 所创建协程的栈空间大小 - * @param fn {void (*)(ACL_FIBER*, void*)} 定时器协程被唤醒时的回调函数 - * @param ctx {void*} 回调 fn 函数时的第二个参数 - * @return {ACL_FIBER*} 新创建的定时器协程 + * һЭʱ + * @param milliseconds {unsigned int} ʱѵĺ + * @param size {size_t} Э̵ջռС + * @param fn {void (*)(ACL_FIBER*, void*)} ʱЭ̱ʱĻص + * @param ctx {void*} ص fn ʱĵڶ + * @return {ACL_FIBER*} ´ĶʱЭ */ ACL_FIBER* acl_fiber_create_timer(unsigned int milliseconds, size_t size, void (*fn)(ACL_FIBER*, void*), void* ctx); /** - * 在定时器协程未被唤醒前,可以通过本函数重置该协程被唤醒的时间 - * @param timer {ACL_FIBER*} 由 acl_fiber_create_timer 创建的定时器协程 - * @param milliseconds {unsigned int} 指定该定时器协程被唤醒的毫秒数 + * ڶʱЭδǰͨøЭ̱ѵʱ + * @param timer {ACL_FIBER*} acl_fiber_create_timer ĶʱЭ + * @param milliseconds {unsigned int} ָöʱЭ̱ѵĺ */ void acl_fiber_reset_timer(ACL_FIBER* timer, unsigned int milliseconds); /** - * 本函数设置 DNS 服务器的地址 - * @param ip {const char*} DNS 服务器 IP 地址 - * @param port {int} DNS 服务器的端口 + * DNS ĵַ + * @param ip {const char*} DNS IP ַ + * @param port {int} DNS Ķ˿ */ void acl_fiber_set_dns(const char* ip, int port); /* for fiber specific */ /** - * 设定当前协程的局部变量 - * @param key {int*} 协程局部变量的索引键的地址,初始时该值应 <= 0,内部会自动 - * 分配一个 > 0 的索引键,并给该地址赋值,后面的协程可以复用该值设置各自的 - * 局部变量,该指针必须非 NULL - * @param ctx {void *} 协程局部变量 - * @param free_fn {void (*)(void*)} 当协程退出时会调用此函数释放协程局部变量 - * @return {int} 返回所设置的协程局部变量的键值,返回 -1 表示当前协程不存在 + * 趨ǰЭ̵ľֲ + * @param key {int*} Эֲ̾ĵַʼʱֵӦ <= 0ڲԶ + * һ > 0 õֵַЭ̿ԸøֵøԵ + * ֲָ NULL + * @param ctx {void *} Эֲ̾ + * @param free_fn {void (*)(void*)} Э˳ʱô˺ͷЭֲ̾ + * @return {int} õЭֲ̾ļֵ -1 ʾǰЭ̲ */ int acl_fiber_set_specific(int* key, void* ctx, void (*free_fn)(void*)); /** - * 获得当前协程局部变量 - * @param key {int} 由 acl_fiber_set_specific 返回的键值 - * @retur {void*} 返回 NULL 表示不存在 + * õǰЭֲ̾ + * @param key {int} acl_fiber_set_specific صļֵ + * @retur {void*} NULL ʾ */ void* acl_fiber_get_specific(int key); /* fiber locking */ /** - * 协程互斥锁,线程非安全,只能用在同一线程内 + * Э̷̻߳ǰȫֻͬһ߳ */ typedef struct ACL_FIBER_MUTEX ACL_FIBER_MUTEX; /** - * 协程读写锁,线程非安全,只能用在同一线程内 + * Э̶д̷߳ǰȫֻͬһ߳ */ typedef struct ACL_FIBER_RWLOCK ACL_FIBER_RWLOCK; /** - * 创建协程互斥锁,线程非安全,只能用在同一线程内 + * Э̷̻߳ǰȫֻͬһ߳ * @return {ACL_FIBER_MUTEX*} */ ACL_FIBER_MUTEX* acl_fiber_mutex_create(void); /** - * 释放协程互斥锁 - * @param l {ACL_FIBER_MUTEX*} 由 acl_fiber_mutex_create 创建的协程互斥锁 + * ͷЭ̻ + * @param l {ACL_FIBER_MUTEX*} acl_fiber_mutex_create Э̻ */ void acl_fiber_mutex_free(ACL_FIBER_MUTEX* l); /** - * 对协程互斥锁进行阻塞式加锁,如果加锁成功则返回,否则则阻塞 - * @param l {ACL_FIBER_MUTEX*} 由 acl_fiber_mutex_create 创建的协程互斥锁 + * Э̻ʽɹ򷵻أ + * @param l {ACL_FIBER_MUTEX*} acl_fiber_mutex_create Э̻ */ void acl_fiber_mutex_lock(ACL_FIBER_MUTEX* l); /** - * 对协程互斥锁尝试性进行加锁,无论是否成功加锁都会立即返回 - * @param l {ACL_FIBER_MUTEX*} 由 acl_fiber_mutex_create 创建的协程互斥锁 - * @return {int} 如果加锁成功则返回 0 值,否则返回 -1 + * Э̻ԽмǷɹ + * @param l {ACL_FIBER_MUTEX*} acl_fiber_mutex_create Э̻ + * @return {int} ɹ򷵻 0 ֵ򷵻 -1 */ int acl_fiber_mutex_trylock(ACL_FIBER_MUTEX* l); /** - * 加锁成功的协程调用本函数进行解锁,调用本函数的协程必须是该锁的属主,否则 - * 内部会产生断言 - * @param l {ACL_FIBER_MUTEX*} 由 acl_fiber_mutex_create 创建的协程互斥锁 + * ɹЭ̵ñнñЭ̱Ǹ + * ڲ + * @param l {ACL_FIBER_MUTEX*} acl_fiber_mutex_create Э̻ */ void acl_fiber_mutex_unlock(ACL_FIBER_MUTEX* l); /** - * 创建协程读写锁,线程非安全,只能用在同一线程内 + * Э̶д̷߳ǰȫֻͬһ߳ * @return {ACL_FIBER_RWLOCK*} */ ACL_FIBER_RWLOCK* acl_fiber_rwlock_create(void); /** - * 释放协程读写锁 - * @param l {ACL_FIBER_RWLOCK*} 由 acl_fiber_rwlock_create 创建的读写锁 + * ͷЭ̶д + * @param l {ACL_FIBER_RWLOCK*} acl_fiber_rwlock_create Ķд */ void acl_fiber_rwlock_free(ACL_FIBER_RWLOCK* l); /** - * 对协程读写锁加读锁,如果该锁当前正被其它协程加了读锁,则本协程依然可以 - * 正常加读锁,如果该锁当前正被其它协程加了写锁,则本协程进入阻塞状态,直至 - * 写锁释放 - * @param l {ACL_FIBER_RWLOCK*} 由 acl_fiber_rwlock_create 创建的读写锁 + * Э̶дӶǰЭ̼˶ЭȻ + * ӶǰЭ̼дЭ̽״ֱ̬ + * дͷ + * @param l {ACL_FIBER_RWLOCK*} acl_fiber_rwlock_create Ķд */ void acl_fiber_rwlock_rlock(ACL_FIBER_RWLOCK* l); /** - * 对协程读写锁尝试性加读锁,加锁无论是否成功都会立即返回 - * @param l {ACL_FIBER_RWLOCK*} 由 acl_fiber_rwlock_create 创建的读写锁 - * @retur {int} 返回 1 表示加锁成功,返回 0 表示加锁失败 + * Э̶дԼӶǷɹ + * @param l {ACL_FIBER_RWLOCK*} acl_fiber_rwlock_create Ķд + * @retur {int} 1 ʾɹ 0 ʾʧ */ int acl_fiber_rwlock_tryrlock(ACL_FIBER_RWLOCK* l); /** - * 对协程读写锁加写锁,只有当该锁未被任何协程加读/写锁时才会返回,否则阻塞, - * 直至该锁可加写锁 - * @param l {ACL_FIBER_RWLOCK*} 由 acl_fiber_rwlock_create 创建的读写锁 + * Э̶ддֻеδκЭ̼Ӷ/дʱŻ᷵أ + * ֱɼд + * @param l {ACL_FIBER_RWLOCK*} acl_fiber_rwlock_create Ķд */ void acl_fiber_rwlock_wlock(ACL_FIBER_RWLOCK* l); /** - * 对协程读写锁尝试性加写锁,无论是否加锁成功都会立即返回 - * @param l {ACL_FIBER_RWLOCK*} 由 acl_fiber_rwlock_create 创建的读写锁 - * @return {int} 返回 1 表示加写锁成功,返回 0 表示加锁失败 + * Э̶дԼдǷɹ + * @param l {ACL_FIBER_RWLOCK*} acl_fiber_rwlock_create Ķд + * @return {int} 1 ʾдɹ 0 ʾʧ */ int acl_fiber_rwlock_trywlock(ACL_FIBER_RWLOCK* l); /** - * 对协程读写锁成功加读锁的协程调用本函数解读锁,调用者必须是之前已成功加读 - * 锁成功的协程 - * @param l {ACL_FIBER_RWLOCK*} 由 acl_fiber_rwlock_create 创建的读写锁 + * Э̶дɹӶЭ̵ñ֮߱ǰѳɹӶ + * ɹЭ + * @param l {ACL_FIBER_RWLOCK*} acl_fiber_rwlock_create Ķд */ void acl_fiber_rwlock_runlock(ACL_FIBER_RWLOCK* l); /** - * 对协程读写锁成功加写锁的协程调用本函数解写锁,调用者必须是之前已成功加写 - * 锁成功的协程 - * @param l {ACL_FIBER_RWLOCK*} 由 acl_fiber_rwlock_create 创建的读写锁 + * Э̶дɹдЭ̵ñд֮߱ǰѳɹд + * ɹЭ + * @param l {ACL_FIBER_RWLOCK*} acl_fiber_rwlock_create Ķд */ void acl_fiber_rwlock_wunlock(ACL_FIBER_RWLOCK* l); /* fiber_event.c */ -/* 线程安全的协程锁,可以用在不同线程的协程之间及不同线程之间的互斥 */ +/* ̰߳ȫЭڲ̵ͬ߳Э֮估֮ͬ߳Ļ */ typedef struct ACL_FIBER_EVENT ACL_FIBER_EVENT; /** - * 创建基于事件的协程/线程混合锁 + * ¼Э/̻߳ * @return {ACL_FIBER_EVENT *} */ ACL_FIBER_EVENT *acl_fiber_event_create(void); /** - * 释放事件锁 + * ͷ¼ * @param {ACL_FIBER_EVENT *} */ void acl_fiber_event_free(ACL_FIBER_EVENT *event); /** - * 等待事件锁可用 + * ȴ¼ * @param {ACL_FIBER_EVENT *} - * @return {int} 返回 0 表示成功,-1 表示出错 + * @return {int} 0 ʾɹ-1 ʾ */ int acl_fiber_event_wait(ACL_FIBER_EVENT *event); /** - * 尝试等待事件锁可用 + * Եȴ¼ * @param {ACL_FIBER_EVENT *} - * @return {int} 返回 0 表示成功,-1 表示锁被占用 + * @return {int} 0 ʾɹ-1 ʾռ */ int acl_fiber_event_trywait(ACL_FIBER_EVENT *event); /** - * 事件锁拥有者通知等待者事件锁可用,则等待者收到通知后则可获得事件锁 + * ¼ӵ֪ͨȴ¼ãȴյ֪ͨɻ¼ * @param {ACL_FIBER_EVENT *} - * @return {int} 返回 0 表示成功,-1 表示出错 + * @return {int} 0 ʾɹ-1 ʾ */ int acl_fiber_event_notify(ACL_FIBER_EVENT *event); @@ -360,59 +364,61 @@ int acl_fiber_event_notify(ACL_FIBER_EVENT *event); typedef struct ACL_FIBER_SEM ACL_FIBER_SEM; /** - * 创建协程信号量,同时内部会将当前线程与该信号量绑定 - * @param num {int} 信号量初始值(必须 >= 0) + * ЭźͬʱڲὫǰ߳ź + * @param num {int} źʼֵ >= 0 * @return {ACL_FIBER_SEM *} */ ACL_FIBER_SEM* acl_fiber_sem_create(int num); /** - * 释放协程信号量 + * ͷЭź * @param {ACL_FIBER_SEM *} */ void acl_fiber_sem_free(ACL_FIBER_SEM* sem); /** - * 获得当前协程信号量所绑定的线程 ID - * @param sem {ACL_FIBER_SEM*} 协程信号量对象 + * õǰЭź󶨵߳ ID + * @param sem {ACL_FIBER_SEM*} Эź * @return {pthread_t} */ +#if !defined(_WIN32) && !defined(_WIN64) pthread_t acl_fiber_sem_get_tid(ACL_FIBER_SEM* sem); +#endif /** - * 设置指定协程信号量的的线程 ID,当改变本协程信号量所属的线程时如果等待的协程 - * 数据非 0 则内部自动 fatal,即当协程信号量上等待协程非空时禁止调用本方法 - * @param sem {ACL_FIBER_SEM*} 协程信号量对象 - * @param {pthread_t} 线程 ID + * ָЭźĵ߳ IDı䱾Эź߳ʱȴЭ + * ݷ 0 ڲԶ fatalЭźϵȴЭ̷ǿʱֹñ + * @param sem {ACL_FIBER_SEM*} Эź + * @param {unsigned long} ߳ ID */ -void acl_fiber_sem_set_tid(ACL_FIBER_SEM* sem, pthread_t tid); +void acl_fiber_sem_set_tid(ACL_FIBER_SEM* sem, unsigned long tid); /** - * 当协程信号量 > 0 时使信号量减 1,否则等待信号量 > 0 + * Эź > 0 ʱʹź 1ȴź > 0 * @param sem {ACL_FIBER_SEM *} - * @retur {int} 返回信号量当前值,如果返回 -1 表明当前线程与协程信号量所属线程 - * 不是同一线程,此时该方法不等待立即返回 + * @retur {int} źǰֵ -1 ǰ߳Эź߳ + * ͬһ̣߳ʱ÷ȴ */ int acl_fiber_sem_wait(ACL_FIBER_SEM* sem); /** - * 尝试使协程信号量减 1 + * ʹЭź 1 * @param sem {ACL_FIBER_SEM *} - * @retur {int} 成功减 1 时返回值 >= 0,返回 -1 表示当前信号量不可用,或当前 - * 调用者线程与协程信号量所属线程不是同一线程 + * @retur {int} ɹ 1 ʱֵ >= 0 -1 ʾǰźãǰ + * ߳Эź̲߳ͬһ߳ */ int acl_fiber_sem_trywait(ACL_FIBER_SEM* sem); /** - * 使协程信号量加 1 + * ʹЭź 1 * @param sem {ACL_FIBER_SEM *} - * @retur {int} 返回信号量当前值,返回 -1 表示当前调用者线程与协程信号量所属 - * 线程不是同一线程 + * @retur {int} źǰֵ -1 ʾǰ߳Эź + * ̲߳ͬһ߳ */ int acl_fiber_sem_post(ACL_FIBER_SEM* sem); /** - * 获得指定协程信号量的当前值,该值反映了目前等待该信号量的数量 + * ָЭźĵǰֵֵӳĿǰȴź * @param sem {ACL_FIBER_SEM*} * @retur {int} */ @@ -421,114 +427,114 @@ int acl_fiber_sem_num(ACL_FIBER_SEM* sem); /* channel communication */ /** - * 协程间通信的管道 + * Э̼ͨŵĹܵ */ typedef struct ACL_CHANNEL ACL_CHANNEL; /** - * 创建协程通信管道 - * @param elemsize {int} 在 ACL_CHANNEL 进行传输的对象的固定尺寸大小(字节) - * @param bufsize {int} ACL_CHANNEL 内部缓冲区大小,即可以缓存 elemsize 尺寸大小 - * 对象的个数 + * ЭͨŹܵ + * @param elemsize {int} ACL_CHANNEL дĶĹ̶ߴСֽڣ + * @param bufsize {int} ACL_CHANNEL ڲСԻ elemsize ߴС + * ĸ * @return {CHANNNEL*} */ ACL_CHANNEL* acl_channel_create(int elemsize, int bufsize); /** - * 释放由 acl_channel_create 创建的协程通信管道对象 - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 + * ͷ acl_channel_create ЭͨŹܵ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ */ void acl_channel_free(ACL_CHANNEL* c); /** - * 阻塞式向指定 ACL_CHANNEL 中发送指定的对象地址 - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 - * @param v {void*} 被发送的对象地址 - * @return {int} 返回值 >= 0 + * ʽָ ACL_CHANNEL зָĶַ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ + * @param v {void*} ͵Ķַ + * @return {int} ֵ >= 0 */ int acl_channel_send(ACL_CHANNEL* c, void* v); /** - * 非阻塞式向指定 ACL_CHANNEL 中发送指定的对象,内部会根据 acl_channel_create 中指定 - * 的 elemsize 对象大小进行数据拷贝 - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 - * @param v {void*} 被发送的对象地址 + * ʽָ ACL_CHANNEL зָĶڲ acl_channel_create ָ + * elemsize Сݿ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ + * @param v {void*} ͵Ķַ */ int acl_channel_send_nb(ACL_CHANNEL* c, void* v); /** - * 从指定的 ACL_CHANNEL 中阻塞式读取对象, - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 - * @param v {void*} 存放结果内容 - * @return {int} 返回值 >= 0 表示成功读到数据 + * ָ ACL_CHANNEL ʽȡ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ + * @param v {void*} Ž + * @return {int} ֵ >= 0 ʾɹ */ int acl_channel_recv(ACL_CHANNEL* c, void* v); /** - * 从指定的 ACL_CHANNEL 中非阻塞式读取对象,无论是否读到数据都会立即返回 - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 - * @param v {void*} 存放结果内容 - * @return {int} 返回值 >= 0 表示成功读到数据,否则表示未读到数据 + * ָ ACL_CHANNEL зʽȡǷݶ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ + * @param v {void*} Ž + * @return {int} ֵ >= 0 ʾɹݣʾδ */ int acl_channel_recv_nb(ACL_CHANNEL* c, void* v); /** - * 向指定的 ACL_CHANNEL 中阻塞式发送指定对象的地址 - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 - * @param v {void*} 被发送对象的地址 - * @return {int} 返回值 >= 0 + * ָ ACL_CHANNEL ʽָĵַ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ + * @param v {void*} Ͷĵַ + * @return {int} ֵ >= 0 */ int acl_channel_sendp(ACL_CHANNEL* c, void* v); /** - * 从指定的 CHANNLE 中阻塞式接收由 acl_channel_sendp 发送的对象的地址 - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 - * @return {void*} 返回非 NULL,指定接收到的对象的地址 + * ָ CHANNLE ʽ acl_channel_sendp ͵Ķĵַ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ + * @return {void*} ط NULLָյĶĵַ */ void* acl_channel_recvp(ACL_CHANNEL* c); /** - * 向指定的 ACL_CHANNEL 中非阻塞式发送指定对象的地址 - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 - * @param v {void*} 被发送对象的地址 - * @return {int} 返回值 >= 0 + * ָ ACL_CHANNEL зʽָĵַ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ + * @param v {void*} Ͷĵַ + * @return {int} ֵ >= 0 */ int acl_channel_sendp_nb(ACL_CHANNEL* c, void* v); /** - * 从指定的 CHANNLE 中阻塞式接收由 acl_channel_sendp 发送的对象的地址 - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 - * @return {void*} 返回非 NULL,指定接收到的对象的地址,如果返回 NULL 表示 - * 没有读到任何对象 + * ָ CHANNLE ʽ acl_channel_sendp ͵Ķĵַ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ + * @return {void*} ط NULLָյĶĵַ NULL ʾ + * ûжκζ */ void* acl_channel_recvp_nb(ACL_CHANNEL* c); /** - * 向指定的 ACL_CHANNEL 中发送无符号长整形数值 - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 - * @param val {unsigned long} 要发送的数值 - * @return {int} 返回值 >= 0 + * ָ ACL_CHANNEL з޷ųֵ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ + * @param val {unsigned long} Ҫ͵ֵ + * @return {int} ֵ >= 0 */ int acl_channel_sendul(ACL_CHANNEL* c, unsigned long val); /** - * 从指定的 ACL_CHANNEL 中接收无符号长整形数值 - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 + * ָ ACL_CHANNEL н޷ųֵ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ * @return {unsigned long} */ unsigned long acl_channel_recvul(ACL_CHANNEL* c); /** - * 向指定的 ACL_CHANNEL 中以非阻塞方式发送无符号长整形数值 - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 - * @param val {unsigned long} 要发送的数值 - * @return {int} 返回值 >= 0 + * ָ ACL_CHANNEL Էʽ޷ųֵ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ + * @param val {unsigned long} Ҫ͵ֵ + * @return {int} ֵ >= 0 */ int acl_channel_sendul_nb(ACL_CHANNEL* c, unsigned long val); /** - * 从指定的 ACL_CHANNEL 中以非阻塞方式接收无符号长整形数值 - * @param c {ACL_CHANNEL*} 由 acl_channel_create 创建的管道对象 + * ָ ACL_CHANNEL Էʽ޷ųֵ + * @param c {ACL_CHANNEL*} acl_channel_create Ĺܵ * @return {unsigned long} */ unsigned long acl_channel_recvul_nb(ACL_CHANNEL* c); @@ -552,49 +558,49 @@ ssize_t fiber_sendmsg(int sockfd, const struct msghdr* msg, int flags); /****************************************************************************/ /** - * 在将写日志至日志文件前回调用户自定义的函数,且将日志信息传递给该函数, - * 只有当用户通过 msg_pre_write 进行设置后才生效 - * @param ctx {void*} 用户的自定义参数 - * @param fmt {const char*} 格式参数 - * @param ap {va_list} 格式参数列表 + * ڽд־־ļǰصûԶĺҽ־Ϣݸú + * ֻеûͨ msg_pre_write úЧ + * @param ctx {void*} ûԶ + * @param fmt {const char*} ʽ + * @param ap {va_list} ʽб */ typedef void (*MSG_PRE_WRITE_FN)(void *ctx, const char *fmt, va_list ap); /** - * 应用通过此函数类型可以自定义日志记录函数,当应用在打开日志前调用 - * msg_register 注册了自定义记录函数,则当应用写日志时便用此自定义 - * 函数记录日志,否则用缺省的日志记录函数 - * @param ctx {void*} 应用传递进去的参数 - * @param fmt {const char*} 格式参数 - * @param ap {va_list} 参数列表 + * Ӧͨ˺ͿԶ־¼Ӧڴ־ǰ + * msg_register עԶ¼Ӧд־ʱôԶ + * ¼־ȱʡ־¼ + * @param ctx {void*} ӦôݽȥIJ + * @param fmt {const char*} ʽ + * @param ap {va_list} б */ typedef void (*MSG_WRITE_FN) (void *ctx, const char *fmt, va_list ap); /** - * 在打开日志前调用此函数注册应用自己的日志记录函数 - * @param write_fn {MSG_WRITE_FN} 自定义日志记录函数 - * @param ctx {void*} 自定义参数 + * ڴ־ǰô˺עӦԼ־¼ + * @param write_fn {MSG_WRITE_FN} Զ־¼ + * @param ctx {void*} Զ */ void msg_register(MSG_WRITE_FN write_fn, void *ctx); /** - * 将 msg_register 注册自定义函数清除,采用缺省的日志函数集 + * msg_register עԶ庯ȱʡ־ */ void msg_unregister(void); /** - * 在打开日志前调用此函数注册应用的私有函数,在记录日志前会先记录信息通过 - * 此注册的函数传递给应用 - * @param pre_write {MSG_PRE_WRITE_FN} 日志记录前调用的函数 - * @param ctx {void*} 自定义参数 + * ڴ־ǰô˺עӦõ˽кڼ¼־ǰȼ¼Ϣͨ + * עĺݸӦ + * @param pre_write {MSG_PRE_WRITE_FN} ־¼ǰõĺ + * @param ctx {void*} Զ */ void msg_pre_write(MSG_PRE_WRITE_FN pre_write, void *ctx); /** - * 当未调用 msg_open 方式打开日志时,调用了 msg_info/error/fatal/warn - * 的操作,是否允许信息输出至标准输出屏幕上,通过此函数来设置该开关,该开关 - * 仅影响是否需要将信息输出至终端屏幕而不影响是否输出至文件中 - * @param onoff {int} 非 0 表示允许输出至屏幕 + * δ msg_open ʽ־ʱ msg_info/error/fatal/warn + * IJǷϢ׼Ļϣͨ˺øÿأÿ + * ӰǷҪϢնĻӰǷļ + * @param onoff {int} 0 ʾĻ */ void msg_stdout_enable(int onoff); diff --git a/lib_fiber/c/lib_fiber.vcxproj b/lib_fiber/c/lib_fiber.vcxproj new file mode 100644 index 000000000..b9d4453e8 --- /dev/null +++ b/lib_fiber/c/lib_fiber.vcxproj @@ -0,0 +1,154 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {AD99B75A-40BF-46DC-844B-23417FDC8690} + Win32Proj + lib_fiber + + + + StaticLibrary + true + v120 + Unicode + + + StaticLibrary + false + v110 + true + Unicode + + + + + + + + + + + + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\src;.\include + + + Windows + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + \ No newline at end of file diff --git a/lib_fiber/c/lib_fiber.vcxproj.filters b/lib_fiber/c/lib_fiber.vcxproj.filters new file mode 100644 index 000000000..2be11927a --- /dev/null +++ b/lib_fiber/c/lib_fiber.vcxproj.filters @@ -0,0 +1,240 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {02aaa36c-e182-4878-aea8-17c9c7d99f41} + + + {356538fb-5e38-4d2d-9519-4cf6ac50944c} + + + {08cf9220-1c0c-4cc0-b340-6f3f2f00b0f5} + + + {db249318-674e-46ed-8d7b-05382163acdd} + + + {baaeb113-34bc-4df8-9649-b024ec495a95} + + + + + + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\event + + + 源文件\event + + + 源文件\hook + + + 源文件\dns + + + 源文件\dns + + + 源文件\dns + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 头文件 + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + + + 源文件 + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\event + + + 源文件\event + + + 源文件\hook + + + 源文件\hook + + + 源文件\hook + + + 源文件\hook + + + 源文件\hook + + + 源文件\hook + + + 源文件\hook + + + 源文件\hook + + + 源文件\dns + + + 源文件\dns + + + 源文件\dns + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件\common + + + 源文件\common + + + 源文件\common + + + 源文件\fiber + + + 源文件\fiber + + + 源文件\common + + + \ No newline at end of file diff --git a/lib_fiber/c/src/common.h b/lib_fiber/c/src/common.h index 9e3726bb0..3743bd94f 100644 --- a/lib_fiber/c/src/common.h +++ b/lib_fiber/c/src/common.h @@ -10,5 +10,7 @@ #include "common/array.h" #include "common/argv.h" #include "common/strops.h" +#include "common/pthread.h" +#include "common/memory.h" #endif diff --git a/lib_fiber/c/src/common/argv.c b/lib_fiber/c/src/common/argv.c index c97d04064..dfa56d6e2 100644 --- a/lib_fiber/c/src/common/argv.c +++ b/lib_fiber/c/src/common/argv.c @@ -34,7 +34,7 @@ static void argv_push_front(struct ARGV *argvp, const char *s) argvp->argv[i] = argvp->argv[i - 1]; } - argvp->argv[0] = strdup(s); + argvp->argv[0] = STRDUP(s); argvp->argc++; } @@ -181,7 +181,7 @@ void argv_add(ARGV *argvp,...) if (SPACE_LEFT(argvp) <= 0) { argv_extend(argvp); } - argvp->argv[argvp->argc++] = strdup(arg); + argvp->argv[argvp->argc++] = STRDUP(arg); } va_end(ap); argvp->argv[argvp->argc] = 0; @@ -197,7 +197,7 @@ void argv_addv(ARGV *argvp, va_list ap) if (SPACE_LEFT(argvp) <= 0) { argv_extend(argvp); } - argvp->argv[argvp->argc++] = strdup(arg); + argvp->argv[argvp->argc++] = STRDUP(arg); } argvp->argv[argvp->argc] = 0; } @@ -223,7 +223,7 @@ int argv_size(ARGV *argvp) ARGV *argv_split(const char *str, const char *delim) { ARGV *argvp = argv_alloc(1); - char *saved_string = strdup(str); + char *saved_string = STRDUP(str); char *bp = saved_string; char *arg; diff --git a/lib_fiber/c/src/common/atomic.c b/lib_fiber/c/src/common/atomic.c index b820e9659..b51ef90e3 100644 --- a/lib_fiber/c/src/common/atomic.c +++ b/lib_fiber/c/src/common/atomic.c @@ -67,7 +67,7 @@ void atomic_int64_set(ATOMIC *self, long long n) (void) __sync_lock_test_and_set((long long *) self->value, n); #else (void) self; - (void) value; + (void) n; msg_error("%s(%d), %s: not support!", __FILE__, __LINE__, __FUNCTION__); #endif @@ -101,6 +101,15 @@ long long atomic_int64_add_fetch(ATOMIC *self, long long n) long long atomic_int64_cas(ATOMIC *self, long long cmp, long long n) { +#if defined(__GNUC__) && (__GNUC__ >= 4) return (long long) __sync_val_compare_and_swap( (long long*) self->value, cmp, n); +#else + (void) self; + (void) cmp; + (void) n; + msg_error("%s(%d), %s: not support!", + __FILE__, __LINE__, __FUNCTION__); + return -1; +#endif } diff --git a/lib_fiber/c/src/common/close_on_exec.c b/lib_fiber/c/src/common/close_on_exec.c index 8a0ef141f..f7533e605 100644 --- a/lib_fiber/c/src/common/close_on_exec.c +++ b/lib_fiber/c/src/common/close_on_exec.c @@ -1,5 +1,4 @@ #include "stdafx.h" -#include #include /* Utility library. */ @@ -13,6 +12,7 @@ int close_on_exec(int fd, int on) { +#ifdef SYS_UNIX int flags; if ((flags = fcntl(fd, F_GETFD, 0)) < 0) { @@ -24,4 +24,9 @@ int close_on_exec(int fd, int on) } return ((flags & PATTERN) != 0); +#else + (void) fd; + (void) on; + return 0; +#endif } diff --git a/lib_fiber/c/src/common/doze.c b/lib_fiber/c/src/common/doze.c index 0e700cedd..9bf91f7c0 100644 --- a/lib_fiber/c/src/common/doze.c +++ b/lib_fiber/c/src/common/doze.c @@ -1,9 +1,4 @@ #include "stdafx.h" -#include -#include -#include -#include - #include "msg.h" #include "iostuff.h" @@ -14,7 +9,11 @@ void doze(unsigned delay) struct timeval tv; tv.tv_sec = delay / 1000; +#if defined(SYS_WIN) + tv.tv_usec = (long) (delay - tv.tv_sec * 1000) * 1000; +#else tv.tv_usec = (suseconds_t) (delay - tv.tv_sec * 1000) * 1000; +#endif while (select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv) < 0) { if (last_error() != EINTR) { diff --git a/lib_fiber/c/src/common/fifo.c b/lib_fiber/c/src/common/fifo.c new file mode 100644 index 000000000..efe3cb9b5 --- /dev/null +++ b/lib_fiber/c/src/common/fifo.c @@ -0,0 +1,341 @@ +#include "stdafx.h" +#include "iterator.h" +#include "fifo.h" + +static void push_back(FIFO *fifo, void *data) +{ + fifo_push_back(fifo, data); +} + +static void push_front(FIFO *fifo, void *data) +{ + fifo_push_front(fifo, data); +} + +static void* pop_back(FIFO *fifo) +{ + return fifo_pop_back(fifo); +} + +static void* pop_front(FIFO *fifo) +{ + return fifo_pop_front(fifo); +} + +static void *iter_head(ITER *iter, struct FIFO *fifo) +{ + FIFO_INFO *ptr; + + iter->dlen = -1; + iter->key = NULL; + iter->klen = -1; + iter->i = 0; + iter->size = fifo->cnt; + iter->ptr = ptr = fifo->head; + iter->data = ptr ? ptr->data : NULL; + return iter->ptr; +} + +static void *iter_next(ITER *iter, struct FIFO *fifo fiber_unused) +{ + FIFO_INFO *ptr; + + ptr = (FIFO_INFO*) iter->ptr; + iter->ptr = ptr = ptr ? ptr->next : NULL; + if (ptr) { + iter->data = ptr->data; + iter->i++; + } else + iter->data = NULL; + return iter; +} + +static void *iter_tail(ITER *iter, struct FIFO *fifo) +{ + FIFO_INFO *ptr; + + iter->dlen = -1; + iter->key = NULL; + iter->klen = -1; + iter->i = fifo->cnt - 1; + iter->size = fifo->cnt; + iter->ptr = ptr = fifo->tail; + iter->data = ptr ? ptr->data : NULL; + return iter->ptr; +} + +static void *iter_prev(ITER *iter, struct FIFO *fifo fiber_unused) +{ + FIFO_INFO *ptr; + + ptr = (FIFO_INFO*) iter->ptr; + iter->ptr = ptr = ptr ? ptr->prev : NULL; + if (ptr) { + iter->data = ptr->data; + iter->i--; + } else + iter->data = NULL; + return iter; +} + +static FIFO_INFO *iter_info(ITER *iter, struct FIFO *fifo fiber_unused) +{ + return iter->ptr ? (FIFO_INFO*) iter->ptr : NULL; +} + +void acl_fifo_init(FIFO *fifo) +{ + fifo->head = NULL; + fifo->tail = NULL; + fifo->cnt = 0; + + fifo->push_back = push_back; + fifo->push_front = push_front; + fifo->pop_back = pop_back; + fifo->pop_front = pop_front; + fifo->iter_head = iter_head; + fifo->iter_next = iter_next; + fifo->iter_tail = iter_tail; + fifo->iter_prev = iter_prev; + fifo->iter_info = iter_info; +} + +FIFO *fifo_new1(void) +{ + FIFO *fifo; + + fifo = (FIFO *) malloc(sizeof(*fifo)); + fifo->head = NULL; + fifo->tail = NULL; + fifo->cnt = 0; + + fifo->push_back = push_back; + fifo->push_front = push_front; + fifo->pop_back = pop_back; + fifo->pop_front = pop_front; + fifo->iter_head = iter_head; + fifo->iter_next = iter_next; + fifo->iter_tail = iter_tail; + fifo->iter_prev = iter_prev; + + return fifo; +} + +void fifo_free(FIFO *fifo, void (*free_fn)(void *)) +{ + void *data; + + while ((data = fifo_pop(fifo)) != NULL) { + if (free_fn) + free_fn(data); + } + free(fifo); +} + +FIFO_INFO *fifo_push_back2(FIFO *fifo, void *data) +{ + FIFO_INFO *info; + + info = (FIFO_INFO *) malloc(sizeof(*info)); + info->data = data; + + if (fifo->tail == NULL) { + info->prev = info->next = NULL; + fifo->head = fifo->tail = info; + } else { + fifo->tail->next = info; + info->prev = fifo->tail; + info->next = NULL; + fifo->tail = info; + } + + fifo->cnt++; + return info; +} + +FIFO_INFO *fifo_push_front(FIFO *fifo, void *data) +{ + FIFO_INFO *info; + + info = (FIFO_INFO*) malloc(sizeof(*info)); + info->data = data; + + if (fifo->head == NULL) { + info->prev = info->next = NULL; + fifo->head = fifo->tail = info; + } else { + info->next = fifo->head; + fifo->head->prev = info; + info->prev = NULL; + fifo->head = info; + } + + fifo->cnt++; + return info; +} + +void *fifo_pop_front(FIFO *fifo) +{ + FIFO_INFO *info; + void *data; + + if (fifo->head == NULL) + return NULL; + + info = fifo->head; + if (fifo->head->next) { + fifo->head->next->prev = NULL; + fifo->head = fifo->head->next; + } else { + fifo->head = fifo->tail = NULL; + } + data = info->data; + free(info); + fifo->cnt--; + return data; +} + +void *fifo_pop_back(FIFO *fifo) +{ + FIFO_INFO *info; + void *data; + + if (fifo->tail == NULL) + return NULL; + + info = fifo->tail; + if (fifo->tail->prev) { + fifo->tail->prev->next = NULL; + fifo->tail = fifo->tail->prev; + } else { + fifo->head = fifo->tail = NULL; + } + data = info->data; + free(info); + fifo->cnt--; + return data; +} + +int fifo_delete(FIFO *fifo, const void *data) +{ + FIFO_INFO *iter = fifo->head; + + while (iter) { + if (iter->data == data) { + if (iter->prev) + iter->prev->next = iter->next; + else + fifo->head = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + else + fifo->tail = iter->prev; + free(iter); + fifo->cnt--; + return 1; + } + + iter = iter->next; + } + return 0; +} + +void *fifo_head(FIFO *fifo) +{ + if (fifo->head) + return fifo->head->data; + else + return NULL; +} + +void *fifo_tail(FIFO *fifo) +{ + if (fifo->tail) + return fifo->tail->data; + else + return NULL; +} + +void fifo_free2(FIFO *fifo, void (*free_fn)(FIFO_INFO *)) +{ + FIFO_INFO *info; + + while ((info = fifo_pop_info(fifo)) != NULL) { + if (free_fn) + free_fn(info); + } + free(fifo); +} + +void fifo_push_info_back(FIFO *fifo, FIFO_INFO *info) +{ + if (fifo->tail == NULL) { + info->prev = info->next = NULL; + fifo->head = fifo->tail = info; + } else { + fifo->tail->next = info; + info->prev = fifo->tail; + info->next = NULL; + fifo->tail = info; + } + + fifo->cnt++; +} + +FIFO_INFO *acl_fifo_pop_info(FIFO *fifo) +{ + FIFO_INFO *info; + + if (fifo->head == NULL) + return NULL; + + info = fifo->head; + if (fifo->head->next) { + fifo->head->next->prev = NULL; + fifo->head = fifo->head->next; + } else { + fifo->head = fifo->tail = NULL; + } + + fifo->cnt--; + return info; +} + +void fifo_delete_info(FIFO *fifo, FIFO_INFO *info) +{ + if (info->prev) + info->prev->next = info->next; + else + fifo->head = info->next; + if (info->next) + info->next->prev = info->prev; + else + fifo->tail = info->prev; + + free(info); + fifo->cnt--; +} + +FIFO_INFO *fifo_head_info(FIFO *fifo) +{ + if (fifo->head) + return fifo->head; + else + return NULL; +} + +FIFO_INFO *fifo_tail_info(FIFO *fifo) +{ + if (fifo->tail) + return fifo->tail; + else + return NULL; +} + +int fifo_size(FIFO *fifo) +{ + if (fifo) + return fifo->cnt; + else + return 0; +} diff --git a/lib_fiber/c/src/common/fifo.h b/lib_fiber/c/src/common/fifo.h new file mode 100644 index 000000000..a2f063517 --- /dev/null +++ b/lib_fiber/c/src/common/fifo.h @@ -0,0 +1,150 @@ +#ifndef FIFO_INCLUDE_H +#define FIFO_INCLUDE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "iterator.h" + +typedef struct FIFO_INFO FIFO_INFO; +typedef struct FIFO_ITER FIFO_ITER; +typedef struct FIFO FIFO; + +struct FIFO_INFO { + void *data; + FIFO_INFO *prev; + FIFO_INFO *next; +}; + +struct FIFO_ITER { + FIFO_INFO *ptr; +}; + +struct FIFO { + FIFO_INFO *head; + FIFO_INFO *tail; + int cnt; + + /* Ӽ */ + + /* βӶ̬ */ + void (*push_back)(struct FIFO*, void*); + /* ͷӶ̬ */ + void (*push_front)(struct FIFO*, void*); + /* β̬ */ + void *(*pop_back)(struct FIFO*); + /* ͷ̬ */ + void *(*pop_front)(struct FIFO*); + + /* for iterator */ + + /* ȡͷ */ + void *(*iter_head)(ITER*, struct FIFO*); + /* ȡһ */ + void *(*iter_next)(ITER*, struct FIFO*); + /* ȡβ */ + void *(*iter_tail)(ITER*, struct FIFO*); + /* ȡһ */ + void *(*iter_prev)(ITER*, struct FIFO*); + /* ȡĵǰԱṹ */ + FIFO_INFO *(*iter_info)(ITER*, struct FIFO*); +}; + +/** + * ʼһУӦÿջϷУøúгʼ + * @param fifo {FIFO *} + * @example: + * void test(void) { + FIFO fifo; + + fifo_init(&fifo); + * } + */ +void fifo_init(FIFO *fifo); + +/** + * ڴзһж + * @return {FIFO*} + */ +FIFO *fifo_new(void); + +/** + * ڴзһж󲢴ڴضΪ + * @return {FIFO*} + */ +FIFO *fifo_new(void); + +/** + * ӶɾֵͬĶ + * @param fifo {FIFO*} + * @param data {const void*} + */ +int fifo_delete(FIFO *fifo, const void *data); +void fifo_delete_info(FIFO *fifo, FIFO_INFO *info); + +/** + * ͷԶѷĶж + * @param fifo {FIFO*} + * @param free_fn {void (*)(void*)}, úָ벻Ϊ + * ͷŶж̬Ķ + */ +void fifo_free(FIFO *fifo, void (*free_fn)(void *)); +void fifo_free2(FIFO *fifo, void (*free_fn)(FIFO_INFO *)); + +/** + * һ̬Ѷ + * @param fifo {FIFO*} + * @param data {void*} ̬ + * @return {FIFO_INFO*} data ǿ򷵻ضеӶ, 򷵻 NULL + */ +FIFO_INFO *fifo_push_back(FIFO *fifo, void *data); +#define fifo_push fifo_push_back +void fifo_push_info_back(FIFO *fifo, FIFO_INFO *info); +#define fifo_push_info fifo_push_info_back +FIFO_INFO *fifo_push_front(FIFO *fifo, void *data); + +/** + * ӶȽȳʽһ̬, ͬʱöӶɾ + * @param fifo {FIFO*} + * @return {void*}, ΪգʾΪ + */ +void *fifo_pop_front(FIFO *fifo); +#define fifo_pop fifo_pop_front +FIFO_INFO *fifo_pop_info(FIFO *fifo); + +/** + * ӶԺȳʽһ̬ ͬʱöӶɾ + * @param fifo {FIFO*} + * @return {void*}, ΪգʾΪ + */ +void *fifo_pop_back(FIFO *fifo); + +/** + * ضͷĶ̬ + * @param fifo {FIFO*} + * @return {void*}, ΪգʾΪ + */ +void *fifo_head(FIFO *fifo); +FIFO_INFO *fifo_head_info(FIFO *fifo); + +/** + * ضβĶ̬ + * @param fifo {FIFO*} + * @return {void*}, ΪգʾΪ + */ +void *fifo_tail(FIFO *fifo); +FIFO_INFO *fifo_tail_info(FIFO *fifo); + +/** + * ضж̬ܸ + * @param fifo {FIFO*} + * @return {int}, >= 0 + */ +int fifo_size(FIFO *fifo); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib_fiber/c/src/common/gettimeofday.c b/lib_fiber/c/src/common/gettimeofday.c new file mode 100644 index 000000000..82accde89 --- /dev/null +++ b/lib_fiber/c/src/common/gettimeofday.c @@ -0,0 +1,143 @@ +#include "stdafx.h" +#include "pthread.h" +#include "msg.h" +#include "init.h" +#include "gettimeofday.h" + +#ifdef SYS_WIN + +#define WIN32_LEAN_AND_MEAN +#include +#include + +struct timezone { + int tz_minuteswest; /**< minutes W of Greenwich */ + int tz_dsttime; /**< type of dst correction */ +}; + +# ifndef __GNUC__ +# define EPOCHFILETIME (116444736000000000i64) +# else +# define EPOCHFILETIME (116444736000000000LL) +# endif + +static void dummy(void *ptr fiber_unused) +{ +} + +static void free_tls(void *ptr) +{ + free(ptr); +} + +static void *__tls = NULL; +static void main_free_tls(void) +{ + if (__tls) { + free(__tls); + __tls = NULL; + } +} + +static pthread_key_t once_key; +static void once_init(void) +{ + if ((unsigned long) pthread_self() == main_thread_self()) { + pthread_key_create(&once_key, dummy); + atexit(main_free_tls); + } else + pthread_key_create(&once_key, free_tls); +} + +static pthread_once_t once_control = PTHREAD_ONCE_INIT; +static void *tls_calloc(size_t len) +{ + void *ptr; + + (void) pthread_once(&once_control, once_init); + ptr = (void*) pthread_getspecific(once_key); + if (ptr == NULL) { + ptr = calloc(1, len); + pthread_setspecific(once_key, ptr); + if ((unsigned long) pthread_self() == main_thread_self()) + __tls = ptr; + } + return ptr; +} + +typedef struct { + time_t last_init; + struct timeval tvbase; + LARGE_INTEGER frequency; + LARGE_INTEGER stamp; + int tzflag; +} TIME_CTX_T; + +int gettimeofday(struct timeval *tv, struct timezone *tz) +{ + FILETIME ft; + LARGE_INTEGER li; + __int64 t; + int nnested = 0; + LARGE_INTEGER stamp; + time_t now; + TIME_CTX_T *ctx = tls_calloc(sizeof(TIME_CTX_T)); + + /* ÿ̵߳ô˺ʱҪгʼΪ˷ֹʱ̫ + * ʱӼÿ 1 Уһλ׼ʱ + */ +#define DAY_SEC (3600 * 24) + + time(&now); + if (now - ctx->last_init > DAY_SEC) { + ctx->last_init = now; + + /* CPUʱƵ */ + if (!QueryPerformanceFrequency(&ctx->frequency)) + msg_fatal("%s(%d): Unable to get System Frequency(%s)", + __FILE__, __LINE__, last_serror()); + /* ϵͳʱ( 1970 ) */ + GetSystemTimeAsFileTime(&ft); + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + t = li.QuadPart; /* In 100-nanosecond intervals */ + t -= EPOCHFILETIME; /* Offset to the Epoch time */ + t /= 10; /* In microseconds */ + + /* תɱοĻ׼ʱ */ + ctx->tvbase.tv_sec = (long)(t / 1000000); + ctx->tvbase.tv_usec = (long)(t % 1000000); + + /* ñοڵʱӼ */ + if (!QueryPerformanceCounter(&ctx->stamp)) + msg_fatal("%s(%d): unable to get System time(%s)", + __FILE__, __LINE__, last_serror()); + } + + /* ʼڵʱ */ + + if (tv) { + /* ñοڵʱӼ */ + if (!QueryPerformanceCounter(&stamp)) + msg_fatal("%s(%d): unable to get System time(%s)", + __FILE__, __LINE__, last_serror()); + + /* 㵱ǰȷʱ */ + t = (stamp.QuadPart - ctx->stamp.QuadPart) * 1000000 / ctx->frequency.QuadPart; + tv->tv_sec = ctx->tvbase.tv_sec + (long)(t / 1000000); + tv->tv_usec = ctx->tvbase.tv_usec + (long)(t % 1000000); + } + + if (tz) { + if (!ctx->tzflag) { + _tzset(); + ctx->tzflag++; + } + tz->tz_minuteswest = _timezone / 60; + tz->tz_dsttime = _daylight; + } + + return (0); +} + +#endif diff --git a/lib_fiber/c/src/common/gettimeofday.h b/lib_fiber/c/src/common/gettimeofday.h new file mode 100644 index 000000000..3b4bccb75 --- /dev/null +++ b/lib_fiber/c/src/common/gettimeofday.h @@ -0,0 +1,10 @@ +#ifndef __GETTIMEOFDAY_HEAD_H__ +#define __GETTIMEOFDAY_HEAD_H__ + +#include "define.h" + +#ifdef SYS_WIN +int gettimeofday(struct timeval *tv, struct timezone *tz); +#endif + +#endif diff --git a/lib_fiber/c/src/common/init.c b/lib_fiber/c/src/common/init.c index 0e04850e3..6b8df4a6f 100644 --- a/lib_fiber/c/src/common/init.c +++ b/lib_fiber/c/src/common/init.c @@ -1,11 +1,12 @@ #include "stdafx.h" -#include - +#include "pthread.h" #include "init.h" -static pthread_t var_main_tid = (pthread_t) -1; +static unsigned long var_main_tid = (unsigned long) -1; +#ifdef __GNUC__ void lib_init(void) __attribute__ ((constructor)); +#endif void lib_init(void) { diff --git a/lib_fiber/c/src/common/iostuff.h b/lib_fiber/c/src/common/iostuff.h index 1f7c162cd..d2e03598e 100644 --- a/lib_fiber/c/src/common/iostuff.h +++ b/lib_fiber/c/src/common/iostuff.h @@ -49,7 +49,10 @@ int issock(int fd); int read_wait(int fd, int timeout); void tcp_nodelay(int fd, int onoff); + +#ifdef SYS_UNIX int sane_socketpair(int domain, int type, int protocol, int result[2]); +#endif #ifdef __cplusplus } diff --git a/lib_fiber/c/src/common/memory.c b/lib_fiber/c/src/common/memory.c new file mode 100644 index 000000000..a6acfb812 --- /dev/null +++ b/lib_fiber/c/src/common/memory.c @@ -0,0 +1,89 @@ +#include "stdafx.h" +#include "memory.h" + +#ifdef FIBER_STACK_GUARD + +static size_t page_size(void) +{ + static __thread long pgsz = 0; + + if (pgsz == 0) { + pgsz = sysconf(_SC_PAGE_SIZE); + assert(pgsz > 0); + } + + return (size_t) pgsz; +} + +static size_t stack_size(size_t size) +{ + size_t pgsz = page_size(), sz; + if (size < pgsz) { + size = pgsz; + } + sz = (size + pgsz - 1) & ~(pgsz - 1); + return sz; +} + +void *stack_alloc(size_t size) +{ + int ret; + char *ptr = NULL; + size_t pgsz = page_size(); + + size = stack_size(size); + size += pgsz; + + ret = posix_memalign((void *) &ptr, pgsz, size); + if (ret != 0) { + msg_fatal("%s(%d), %s: posix_memalign error %s", + __FILE__, __LINE__, __FUNCTION__, last_serror()); + } + + ret = mprotect(ptr, pgsz, PROT_NONE); + if (ret != 0) { + msg_fatal("%s(%d), %s: mprotect error=%s", + __FILE__, __LINE__, __FUNCTION__, last_serror()); + } + + ptr += pgsz; + return ptr; +} + +void stack_free(void *ptr) +{ + int ret; + size_t pgsz = page_size(); + + ptr = (char *) ptr - pgsz; + ret = mprotect(ptr, page_size(), PROT_READ|PROT_WRITE); + if (ret != 0) { + msg_fatal("%s(%d), %s: mprotect error=%s", + __FILE__, __LINE__, __FUNCTION__, last_serror()); + } + free(ptr); +} + +#else + +void *stack_alloc(size_t size) +{ + return malloc(size); +} + +void stack_free(void *ptr) +{ + free(ptr); +} + +#endif + +void *stack_calloc(size_t size) +{ + void* ptr = stack_alloc(size); + + if (ptr) { + memset(ptr, 0, size); + } + return ptr; +} diff --git a/lib_fiber/c/src/common/memory.h b/lib_fiber/c/src/common/memory.h new file mode 100644 index 000000000..5ed891776 --- /dev/null +++ b/lib_fiber/c/src/common/memory.h @@ -0,0 +1,8 @@ +#ifndef __MEMORY_HEAD_H__ +#define __MEMORY_HEAD_H__ + +void *stack_alloc(size_t size); +void *stack_calloc(size_t size); +void stack_free(void *ptr); + +#endif diff --git a/lib_fiber/c/src/common/msg.c b/lib_fiber/c/src/common/msg.c index 20bcf00b8..ef0bb651e 100644 --- a/lib_fiber/c/src/common/msg.c +++ b/lib_fiber/c/src/common/msg.c @@ -1,19 +1,9 @@ #include "stdafx.h" - -#include -#include -#include -#include -#include -#include -#include -#include - #include "fiber/lib_fiber.h" #include "init.h" +#include "pthread.h" #include "msg.h" - #ifndef USE_PRINTF_MACRO static int __stdout_enable = 0; @@ -65,7 +55,7 @@ void msg_info(const char *fmt,...) } if (__stdout_enable) { - printf("msg_info->pid(%d), ", getpid()); + printf("msg_info->pid(%d), ", GETPID()); vprintf(fmt, ap); printf("\r\n"); } @@ -88,7 +78,7 @@ void msg_warn(const char *fmt,...) } if (__stdout_enable) { - printf("msg_warn->pid(%d), ", getpid()); + printf("msg_warn->pid(%d), ", GETPID()); vprintf(fmt, ap); printf("\r\n"); } @@ -111,7 +101,7 @@ void msg_error(const char *fmt,...) } if (__stdout_enable) { - printf("msg_error->pid(%d), ", getpid()); + printf("msg_error->pid(%d), ", GETPID()); vprintf(fmt, ap); printf("\r\n"); } @@ -134,7 +124,7 @@ void msg_fatal(const char *fmt,...) } if (__stdout_enable) { - printf("msg_fatal->pid(%d), ", getpid()); + printf("msg_fatal->pid(%d), ", GETPID()); printf("fatal:"); vprintf(fmt, ap); printf("\r\n"); @@ -154,7 +144,11 @@ const char *msg_strerror(int errnum, char *buffer, size_t size) return NULL; } +#ifdef SYS_WIN + _snprintf(buffer, size, "%s", strerror(errnum)); +#else snprintf(buffer, size, "%s", strerror(errnum)); +#endif return buffer; } diff --git a/lib_fiber/c/src/common/non_blocking.c b/lib_fiber/c/src/common/non_blocking.c index f517884ef..f6f25e0d9 100644 --- a/lib_fiber/c/src/common/non_blocking.c +++ b/lib_fiber/c/src/common/non_blocking.c @@ -1,10 +1,20 @@ #include "stdafx.h" -#include - #include "msg.h" #include "iostuff.h" -/* Backwards compatibility */ +#ifdef SYS_WIN +int non_blocking(int fd, int on) +{ + unsigned long n = on; + int flags = 0; + + if (ioctlsocket(fd, FIONBIO, &n) < 0) { + msg_error("ioctlsocket(fd,FIONBIO) failed"); + return -1; + } + return flags; +} +#elif defined(SYS_UNIX) # ifndef O_NONBLOCK # define PATTERN FNDELAY # else @@ -44,3 +54,4 @@ int non_blocking(int fd, int on) return flags; } +#endif diff --git a/lib_fiber/c/src/common/open_limit.c b/lib_fiber/c/src/common/open_limit.c index 2973e763c..d0ce3dc05 100644 --- a/lib_fiber/c/src/common/open_limit.c +++ b/lib_fiber/c/src/common/open_limit.c @@ -1,14 +1,15 @@ #include "stdafx.h" -#include -#include -#include -#include - -/* Application-specific. */ - #include "msg.h" #include "iostuff.h" +#ifdef SYS_WIN +int open_limit(int limit) +{ + if (limit <= 0) + limit = 1024; + return limit; +} +#else /* * 44BSD compatibility. */ @@ -20,8 +21,6 @@ /* open_limit - set/query file descriptor limit */ -#include - int open_limit(int limit) { int rlim_cur = -1; @@ -80,3 +79,4 @@ int open_limit(int limit) return rlim_cur; #endif } +#endif // !SYS_WIN diff --git a/lib_fiber/c/src/common/pthread.c b/lib_fiber/c/src/common/pthread.c new file mode 100644 index 000000000..071178e48 --- /dev/null +++ b/lib_fiber/c/src/common/pthread.c @@ -0,0 +1,305 @@ +#include "stdafx.h" +#include "fifo.h" +#include "msg.h" +#include "iterator.h" +#include "pthread.h" + +#ifdef SYS_WIN + +typedef struct { + pthread_key_t key; + void (*destructor)(void *); +} TLS_KEY; + +typedef struct { + TLS_KEY *tls_key; + void *value; +} TLS_VALUE; + +static int __thread_inited = 0; +static TLS_KEY __tls_key_list[PTHREAD_KEYS_MAX]; +static pthread_mutex_t __thread_lock; +static pthread_key_t __tls_value_list_key = TLS_OUT_OF_INDEXES; +static pthread_once_t __create_thread_control_once = PTHREAD_ONCE_INIT; + +static void tls_value_list_free(void); + +void pthread_end(void) +{ + static int __thread_ended = 0; + int i; + + tls_value_list_free(); + + if (__thread_ended) + return; + + __thread_ended = 1; + pthread_mutex_destroy(&__thread_lock); + + for (i = 0; i < PTHREAD_KEYS_MAX; i++) { + if (__tls_key_list[i].key >= 0 + && __tls_key_list[i].key < PTHREAD_KEYS_MAX) + { + TlsFree(__tls_key_list[i].key); + __tls_key_list[i].key = TLS_OUT_OF_INDEXES; + } + __tls_key_list[i].destructor = NULL; + } +} + +/* ÿ̵Ψһʼ */ + +static void pthread_init_once(void) +{ + const char *myname = "pthread_init_once"; + int i; + + pthread_mutex_init(&__thread_lock, NULL); + __thread_inited = 1; + + for (i = 0; i < PTHREAD_KEYS_MAX; i++) { + __tls_key_list[i].destructor = NULL; + __tls_key_list[i].key = TLS_OUT_OF_INDEXES; + } + + __tls_value_list_key = TlsAlloc(); + if (__tls_value_list_key == TLS_OUT_OF_INDEXES) + msg_fatal("%s(%d): TlsAlloc error(%s)", + myname, __LINE__, last_serror()); + if (__tls_value_list_key < 0 + || __tls_value_list_key >= PTHREAD_KEYS_MAX) + { + msg_fatal("%s(%d): TlsAlloc error(%s), not in(%d, %d)", + myname, __LINE__, last_serror(), + 0, PTHREAD_KEYS_MAX); + } + + __tls_key_list[__tls_value_list_key].destructor = NULL; + __tls_key_list[__tls_value_list_key].key = __tls_value_list_key; +} + +/* ֲ߳̾ */ + +static FIFO *tls_value_list_get(void) +{ + FIFO *tls_value_list_ptr; + + tls_value_list_ptr = TlsGetValue(__tls_value_list_key); + if (tls_value_list_ptr == NULL) { + tls_value_list_ptr = fifo_new(); + TlsSetValue(__tls_value_list_key, tls_value_list_ptr); + } + return tls_value_list_ptr; +} + +static void tls_value_list_on_free(void *ctx) +{ + free(ctx); +} + +static void tls_value_list_free(void) +{ + FIFO *tls_value_list_ptr; + + tls_value_list_ptr = TlsGetValue(__tls_value_list_key); + if (tls_value_list_ptr != NULL) { + TlsSetValue(__tls_value_list_key, NULL); + fifo_free(tls_value_list_ptr, tls_value_list_on_free); + } +} + +int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) +{ + int n = 0; + + if (once_control == NULL || init_routine == NULL) { + return EINVAL; + } + + /* ֻеһ InterlockedCompareExchange ̲߳Żִ + * init_routine, ߳Զ InterlockedCompareExchange + * Уһֱѭֱһִ߳ init_routine + * ϲҽ *once_control ¸ֵ, ֻڶ˻ж߳ + * ͬʱʱпֶܳݵĺ߳̿ѭ + * ߳˳ˣΪ *once_control Ѿһ߳ + * ֵѭֻ˴Ϊ˱֤߳ + * pthread_once ǰ init_routine 뱻ҽ + * һ, VC6£InterlockedCompareExchange ӿڶ + * Щ죬ҪӲָͣμ + * Jeffrey Richter, 366 ҳ + */ + while (1) { + LONG prev = InterlockedCompareExchange( + once_control, 1, PTHREAD_ONCE_INIT); + if (prev == 2) + return 0; + else if (prev == 0) { + /* ֻеһ̲߳Ż */ + init_routine(); + /* *conce_control ¸ֵʹ̲߳ while + * ѭ while ѭ + */ + InterlockedExchange(once_control, 2); + return 0; + } else { + assert(prev == 1); + + /* ֹѭ˷CPU */ + Sleep(1); /** sleep 1ms */ + } + } + return 1; /* ɴ룬 */ +} + +unsigned long pthread_self(void) +{ + return GetCurrentThreadId(); +} + +int pthread_key_create(pthread_key_t *key_ptr, void (*destructor)(void*)) +{ + const char *myname = "pthread_key_create"; + + pthread_once(&__create_thread_control_once, pthread_init_once); + + *key_ptr = TlsAlloc(); + if (*key_ptr == TLS_OUT_OF_INDEXES) { + return ENOMEM; + } else if (*key_ptr >= PTHREAD_KEYS_MAX) { + msg_error("%s(%d): key(%d) > PTHREAD_KEYS_MAX(%d)", + myname, __LINE__, *key_ptr, PTHREAD_KEYS_MAX); + TlsFree(*key_ptr); + *key_ptr = TLS_OUT_OF_INDEXES; + return ENOMEM; + } + + __tls_key_list[*key_ptr].destructor = destructor; + __tls_key_list[*key_ptr].key = *key_ptr; + return 0; +} + +void *pthread_getspecific(pthread_key_t key) +{ + return TlsGetValue(key); +} + +int pthread_setspecific(pthread_key_t key, void *value) +{ + const char *myname = "pthread_setspecific"; + FIFO *tls_value_list_ptr = tls_value_list_get(); + ITER iter; + + if (key < 0 || key >= PTHREAD_KEYS_MAX) { + msg_error("%s(%d): key(%d) invalid", myname, __LINE__, key); + return EINVAL; + } + if (__tls_key_list[key].key != key) { + msg_error("%s(%d): __tls_key_list[%d].key(%d) != key(%d)", + myname, __LINE__, key, __tls_key_list[key].key, key); + return EINVAL; + } + + foreach(iter, tls_value_list_ptr) { + TLS_VALUE *tls_value = (TLS_VALUE*) iter.data; + if (tls_value->tls_key != NULL + && tls_value->tls_key->key == key) { + + /* ͬļҪͷž */ + if (tls_value->tls_key->destructor && tls_value->value) + tls_value->tls_key->destructor(tls_value->value); + tls_value->tls_key = NULL; + tls_value->value = NULL; + break; + } + } + + if (TlsSetValue(key, value)) { + TLS_VALUE *tls_value = (TLS_VALUE*) malloc(sizeof(TLS_VALUE)); + tls_value->tls_key = &__tls_key_list[key]; + tls_value->value = value; + fifo_push(tls_value_list_ptr, tls_value); + return 0; + } else { + msg_error("%s(%d): TlsSetValue(key=%d) error(%s)", + myname, __LINE__, key, last_serror()); + return -1; + } +} + +/* Free the mutex */ +int pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + if (mutex) { + if (mutex->id) { + CloseHandle(mutex->id); + mutex->id = 0; + } + return 0; + } else + return -1; +} + +int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mattr) +{ + const char *myname = "pthread_mutex_init"; + + if (mutex == NULL) { + msg_error("%s, %s(%d): input invalid", + __FILE__, myname, __LINE__); + return -1; + } + + mutex->dynamic = 0; + + /* Create the mutex, with initial value signaled */ + mutex->id = CreateMutex((SECURITY_ATTRIBUTES *) mattr, FALSE, NULL); + if (!mutex->id) { + msg_error("%s, %s(%d): CreateMutex error(%s)", + __FILE__, myname, __LINE__, last_serror()); + free(mutex); + return -1; + } + + return 0; +} + +int pthread_mutex_lock(pthread_mutex_t *mutex) +{ + const char *myname = "pthread_mutex_lock"; + + if (mutex == NULL) { + msg_error("%s, %s(%d): input invalid", + __FILE__, myname, __LINE__); + return -1; + } + + if (WaitForSingleObject(mutex->id, INFINITE) == WAIT_FAILED) { + msg_error("%s, %s(%d): WaitForSingleObject error(%s)", + __FILE__, myname, __LINE__, last_serror()); + return -1; + } + + return 0; +} + +int pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + const char *myname = "pthread_mutex_unlock"; + + if (mutex == NULL) { + msg_error("%s, %s(%d): input invalid", + __FILE__, myname, __LINE__); + return -1; + } + + if (ReleaseMutex(mutex->id) == FALSE) { + msg_error("%s, %s(%d): ReleaseMutex error(%s)", + __FILE__, myname, __LINE__, last_serror()); + return -1; + } + + return 0; +} + +#endif /* SYS_WIN */ diff --git a/lib_fiber/c/src/common/pthread.h b/lib_fiber/c/src/common/pthread.h new file mode 100644 index 000000000..9df4acf5a --- /dev/null +++ b/lib_fiber/c/src/common/pthread.h @@ -0,0 +1,50 @@ +#ifndef PTHREAD_INCLUDE_H +#define PTHREAD_INCLUDE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) || defined(_WIN64) +#include + +#define __thread __declspec(thread) + +//#define TLS_OUT_OF_INDEXES 0xffffffff +#define PTHREAD_KEYS_MAX 1024 +#define PTHREAD_ONCE_INIT 0 +#define PTHREAD_ONCE_INIT 0 +typedef unsigned long pthread_t; +typedef struct pthread_mutex_t pthread_mutex_t; +typedef struct pthread_mutexattr_t pthread_mutexattr_t; +typedef int pthread_key_t; +typedef int pthread_once_t; + +struct pthread_mutex_t { + HANDLE id; + char dynamic; +}; + +struct pthread_mutexattr_t { + SECURITY_ATTRIBUTES attr; +}; + +unsigned long pthread_self(void); +int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); +int pthread_key_create(pthread_key_t *key_ptr, void (*destructor)(void*)); + +void *pthread_getspecific(pthread_key_t key); +int pthread_setspecific(pthread_key_t key, void *value); + +int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mattr); +int pthread_mutex_destroy(pthread_mutex_t *mutex); +int pthread_mutex_lock(pthread_mutex_t *mutex); +int pthread_mutex_unlock(pthread_mutex_t *mutex); + +#endif // _WIN32 || _WIN64 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib_fiber/c/src/common/socketpair.c b/lib_fiber/c/src/common/socketpair.c index ffce1dd07..328bd825a 100644 --- a/lib_fiber/c/src/common/socketpair.c +++ b/lib_fiber/c/src/common/socketpair.c @@ -2,6 +2,8 @@ #include "msg.h" #include "iostuff.h" +#ifdef SYS_UNIX + /* sane_socketpair - sanitize socketpair() error returns */ int sane_socketpair(int domain, int type, int protocol, int result[2]) @@ -31,3 +33,5 @@ int sane_socketpair(int domain, int type, int protocol, int result[2]) } return ret; } + +#endif diff --git a/lib_fiber/c/src/define.h b/lib_fiber/c/src/define.h index a44de61d3..2632033ad 100644 --- a/lib_fiber/c/src/define.h +++ b/lib_fiber/c/src/define.h @@ -1,6 +1,23 @@ #ifndef __DEFINE_INCLUDE_H__ #define __DEFINE_INCLUDE_H__ +#if defined(__linux__) +# define SYS_UNIX +# define HAS_POLL +# define HAS_EPOLL +#elif defined(__FreeBSD__) +# define SYS_UNIX +# define HAS_POLL +# define HAS_KQUEUE +#elif defined(_WIN32) || defined(_WIN64) +# define SYS_WIN +# define HAS_WMSG +# define HAS_IOCP +# define __thread __declspec(thread) +#else +# error "unknown OS" +#endif + #ifndef fiber_unused # ifdef __GNUC__ # define fiber_unused __attribute__ ((__unused__)) @@ -39,18 +56,4 @@ #define DEPRECATED_FOR(f) DEPRECATED #endif /* __GNUC__ */ -struct SOCK_ADDR { - union { - struct sockaddr_storage ss; -#ifdef AF_INET6 - struct sockaddr_in6 in6; -#endif - struct sockaddr_in in; -#ifdef ACL_UNIX - struct sockaddr_un un; -#endif - struct sockaddr sa; - } sa; -}; - #endif /* __DEFINE_INCLUDE_H__ */ diff --git a/lib_fiber/c/src/dns/dns.c b/lib_fiber/c/src/dns/dns.c index 831cc6155..5847b8f84 100644 --- a/lib_fiber/c/src/dns/dns.c +++ b/lib_fiber/c/src/dns/dns.c @@ -23,6 +23,11 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. * ========================================================================== */ +#include "stdafx.h" +#include "common.h" + +#ifdef SYS_UNIX + #if !defined(__FreeBSD__) && !defined(__sun) #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 @@ -48,7 +53,9 @@ #include /* malloc(3) realloc(3) free(3) rand(3) random(3) arc4random(3) */ #include /* FILE fopen(3) fclose(3) getc(3) rewind(3) */ #include /* memcpy(3) strlen(3) memmove(3) memchr(3) memcmp(3) strchr(3) strsep(3) strcspn(3) */ +#ifdef SYS_UNIX #include /* strcasecmp(3) strncasecmp(3) */ +#endif #include /* isspace(3) isdigit(3) */ #include /* time_t time(2) difftime(3) */ #include /* SIGPIPE sigemptyset(3) sigaddset(3) sigpending(2) sigprocmask(2) pthread_sigmask(3) sigtimedwait(2) */ @@ -352,7 +359,16 @@ const char *dns_strerror(int error) { case DNS_EFAIL: return "A non-recoverable error occurred when attempting to resolve the name"; default: - return strerror(error); + { +#ifdef SYS_WIN + static __thread char buf[1024]; + buf[0] = 0; + strerror_s(buf, sizeof(buf), error); + return buf; +#else + return strerror(error); +#endif + } } /* switch() */ } /* dns_strerror() */ @@ -398,12 +414,12 @@ const char *dns_strerror(int error) { #endif #endif -static inline unsigned dns_atomic_fetch_add(dns_atomic_t *i) { +static unsigned dns_atomic_fetch_add(dns_atomic_t *i) { return DNS_ATOMIC_FETCH_ADD(i); } /* dns_atomic_fetch_add() */ -static inline unsigned dns_atomic_fetch_sub(dns_atomic_t *i) { +static unsigned dns_atomic_fetch_sub(dns_atomic_t *i) { return DNS_ATOMIC_FETCH_SUB(i); } /* dns_atomic_fetch_sub() */ @@ -532,7 +548,7 @@ struct dns_k_permutor { }; /* struct dns_k_permutor */ -static inline unsigned dns_k_permutor_powof(unsigned n) { +static unsigned dns_k_permutor_powof(unsigned n) { unsigned m, i = 0; for (m = 1; m < n; m <<= 1, i++) @@ -783,6 +799,17 @@ DNS_NOTUSED static size_t dns_strnlcpy(char *dst, size_t lim, const char *src, s #define DNS_HAVE_SOCKADDR_UN (defined AF_UNIX && !defined _WIN32) static size_t dns_af_len(int af) { +#ifdef SYS_WIN + switch (af) + { + case AF_INET6: + return sizeof (struct sockaddr_in6); + case AF_INET: + return sizeof (struct sockaddr_in); + default: + return 0; + } +#else static const size_t table[AF_MAX] = { [AF_INET6] = sizeof (struct sockaddr_in6), [AF_INET] = sizeof (struct sockaddr_in), @@ -790,8 +817,8 @@ static size_t dns_af_len(int af) { [AF_UNIX] = sizeof (struct sockaddr_un), #endif }; - return table[af]; +#endif } /* dns_af_len() */ #define dns_sa_family(sa) (((struct sockaddr *)(sa))->sa_family) @@ -926,11 +953,14 @@ static int dns_sa_cmp(void *a, void *b) { #if _WIN32 static int dns_inet_pton(int af, const void *src, void *dst) { union { struct sockaddr_in sin; struct sockaddr_in6 sin6; } u; - + int len = (int) sizeof(u); u.sin.sin_family = af; - if (0 != WSAStringToAddressA((void *)src, af, (void *)0, (struct sockaddr *)&u, &(int){ sizeof u })) + if (0 != WSAStringToAddressA((void *)src, af, (void *)0, + (struct sockaddr *)&u, &len)) { + return -1; + } switch (af) { case AF_INET6: @@ -1069,19 +1099,19 @@ static char *dns_strsep(char **sp, const char *delim) { #endif -static inline _Bool dns_isalpha(unsigned char c) { +static _Bool dns_isalpha(unsigned char c) { return isalpha(c); } /* dns_isalpha() */ -static inline _Bool dns_isdigit(unsigned char c) { +static _Bool dns_isdigit(unsigned char c) { return isdigit(c); } /* dns_isdigit() */ -static inline _Bool dns_isalnum(unsigned char c) { +static _Bool dns_isalnum(unsigned char c) { return isalnum(c); } /* dns_isalnum() */ -static inline _Bool dns_isspace(unsigned char c) { +static _Bool dns_isspace(unsigned char c) { return isspace(c); } /* dns_isspace() */ @@ -1089,6 +1119,7 @@ static inline _Bool dns_isspace(unsigned char c) { #if defined(_WIN32) || defined(_WIN64) static int dns_poll(int fd, short events, int timeout) { fd_set rset, wset; + struct timeval tv, *tp; if (!events) return 0; @@ -1104,7 +1135,14 @@ static int dns_poll(int fd, short events, int timeout) { if (events & DNS_POLLOUT) FD_SET(fd, &wset); - select(fd + 1, &rset, &wset, 0, (timeout >= 0)? &(struct timeval){ timeout, 0 } : NULL); + if (timeout > 0) { + tv.tv_sec = timeout; + tv.tv_usec = 0; + tp = &tv; + } else { + tp = NULL; + } + select(fd + 1, &rset, &wset, 0, tp); return 0; } @@ -1141,6 +1179,44 @@ static int dns_poll(int fd, short events, int timeout) { #endif /* add by zsx--2017.12.20 */ +#ifdef SYS_WIN +static int read_wait(int fd, int timeout) { + struct timeval tv; + struct timeval *tp; + fd_set rset, xset; + int err; + + FD_ZERO(&rset); + FD_SET(fd, &rset); + FD_ZERO(&xset); + FD_SET(fd, &xset); + + if (timeout > 0) { + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + tp = &tv; + } else { + tp = NULL; + } + +TAG_AGAIN: + switch (select(1, &rset, (fd_set *) 0, &xset, tp)) { + case -1: + err = last_error(); + if (err == EINTR || err == WSAEINPROGRESS + || err == WSAEWOULDBLOCK) { + + goto TAG_AGAIN; + } + return -1; + case 0: + set_error(ETIMEDOUT); + return 0; + default: + return 1; + } +} +#else static int read_wait(int fd, int timeout) { struct pollfd fds; @@ -1166,6 +1242,7 @@ static int read_wait(int fd, int timeout) { } } } +#endif static int __timeout = 5000; @@ -1334,13 +1411,12 @@ struct dns_buf { size_t overflow; }; /* struct dns_buf */ -static inline size_t -dns_b_tell(struct dns_buf *b) +static size_t dns_b_tell(struct dns_buf *b) { return b->p - b->base; } -static inline dns_error_t +static dns_error_t dns_b_setoverflow(struct dns_buf *b, size_t n, dns_error_t error) { b->overflow += n; @@ -1378,14 +1454,12 @@ dns_b_pputc(struct dns_buf *b, unsigned char uc, size_t p) return 0; } -static inline dns_error_t -dns_b_put16(struct dns_buf *b, uint16_t u) +static dns_error_t dns_b_put16(struct dns_buf *b, uint16_t u) { return dns_b_putc(b, u >> 8), dns_b_putc(b, u >> 0); } -static inline dns_error_t -dns_b_pput16(struct dns_buf *b, uint16_t u, size_t p) +static dns_error_t dns_b_pput16(struct dns_buf *b, uint16_t u, size_t p) { if (dns_b_pputc(b, u >> 8, p) || dns_b_pputc(b, u >> 0, p + 1)) return b->error; @@ -1393,8 +1467,7 @@ dns_b_pput16(struct dns_buf *b, uint16_t u, size_t p) return 0; } -DNS_NOTUSED static inline dns_error_t -dns_b_put32(struct dns_buf *b, uint32_t u) +DNS_NOTUSED static dns_error_t dns_b_put32(struct dns_buf *b, uint32_t u) { return dns_b_putc(b, u >> 24), dns_b_putc(b, u >> 16), dns_b_putc(b, u >> 8), dns_b_putc(b, u >> 0); @@ -1420,7 +1493,7 @@ dns_b_puts(struct dns_buf *b, const void *src) return dns_b_put(b, src, strlen(src)); } -DNS_NOTUSED static inline dns_error_t +DNS_NOTUSED static dns_error_t dns_b_fmtju(struct dns_buf *b, const uintmax_t u, const unsigned width) { size_t digits, padding, overflow; @@ -1469,7 +1542,7 @@ dns_b_popc(struct dns_buf *b) b->p--; } -static inline const char * +static const char * dns_b_tolstring(struct dns_buf *b, size_t *n) { if (b->p < b->pe) { @@ -1492,23 +1565,20 @@ dns_b_tolstring(struct dns_buf *b, size_t *n) } } -static inline const char * -dns_b_tostring(struct dns_buf *b) +static const char *dns_b_tostring(struct dns_buf *b) { size_t n; return dns_b_tolstring(b, &n); } -static inline size_t -dns_b_strlen(struct dns_buf *b) +static size_t dns_b_strlen(struct dns_buf *b) { size_t n; dns_b_tolstring(b, &n); return n; } -static inline size_t -dns_b_strllen(struct dns_buf *b) +static size_t dns_b_strllen(struct dns_buf *b) { size_t n = dns_b_strlen(b); return n + b->overflow; @@ -1522,8 +1592,7 @@ dns_b_from(const struct dns_buf *b, const void *src, size_t n) return b; } -static inline int -dns_b_getc(const struct dns_buf *_b, const int eof) +static int dns_b_getc(const struct dns_buf *_b, const int eof) { struct dns_buf *b = (struct dns_buf *)_b; @@ -1533,8 +1602,7 @@ dns_b_getc(const struct dns_buf *_b, const int eof) return *b->p++; } -static inline intmax_t -dns_b_get16(const struct dns_buf *b, const intmax_t eof) +static intmax_t dns_b_get16(const struct dns_buf *b, const intmax_t eof) { intmax_t n; @@ -1544,7 +1612,7 @@ dns_b_get16(const struct dns_buf *b, const intmax_t eof) return (!b->overflow)? n : eof; } -DNS_NOTUSED static inline intmax_t +DNS_NOTUSED static intmax_t dns_b_get32(const struct dns_buf *b, const intmax_t eof) { intmax_t n; @@ -1555,7 +1623,7 @@ dns_b_get32(const struct dns_buf *b, const intmax_t eof) return (!b->overflow)? n : eof; } -static inline dns_error_t +static dns_error_t dns_b_move(struct dns_buf *dst, const struct dns_buf *_src, size_t n) { struct dns_buf *src = (struct dns_buf *)_src; @@ -5331,7 +5399,7 @@ struct dns_nssconf_source { typedef unsigned dns_nssconf_i; -static inline int dns_nssconf_peek(const struct dns_resolv_conf *resconf, dns_nssconf_i state) { +static int dns_nssconf_peek(const struct dns_resolv_conf *resconf, dns_nssconf_i state) { return (state < lengthof(resconf->lookup) && resconf->lookup[state])? resconf->lookup[state] : 0; } /* dns_nssconf_peek() */ @@ -7192,13 +7260,13 @@ static struct dns_packet *dns_res_merge(struct dns_packet *P0, struct dns_packet int error, copy, i; enum dns_section section; -retry: +tag_retry: if (!(P[2] = dns_p_make(bufsiz, &error))) - goto error; + goto tag_error; dns_rr_foreach(&rr[0], P[0], .section = DNS_S_QD) { if ((error = dns_rr_copy(P[2], &rr[0], P[0]))) - goto error; + goto tag_error; } for (section = DNS_S_AN; (DNS_S_ALL & section); section <<= 1) { @@ -7220,17 +7288,17 @@ retry: bufsiz = DNS_PP_MAX(65535, bufsiz * 2); - goto retry; + goto tag_retry; } - goto error; + goto tag_error; } } /* foreach(rr) */ } /* foreach(packet) */ } /* foreach(section) */ return P[2]; -error: +tag_error: *error_ = error; dns_p_free(P[2]); @@ -8078,7 +8146,7 @@ struct dns_addrinfo { #define DNS_AI_AFMAX 32 #define DNS_AI_AF2INDEX(af) (1UL << ((af) - 1)) -static inline unsigned long dns_ai_af2index(int af) { +static unsigned long dns_ai_af2index(int af) { dns_static_assert(dns_same_type(unsigned long, DNS_AI_AF2INDEX(1), 1), "internal type mismatch"); dns_static_assert(dns_same_type(unsigned long, ((struct dns_addrinfo *)0)->af.todo, 1), "internal type mismatch"); @@ -10014,3 +10082,4 @@ int main(int argc, char **argv) { #pragma GCC diagnostic pop #endif +#endif diff --git a/lib_fiber/c/src/dns/dns.h b/lib_fiber/c/src/dns/dns.h index bc80ce68d..9f8e9d9eb 100644 --- a/lib_fiber/c/src/dns/dns.h +++ b/lib_fiber/c/src/dns/dns.h @@ -26,6 +26,10 @@ #ifndef DNS_H #define DNS_H +#include "define.h" + +#ifdef SYS_UNIX + #include /* size_t offsetof() */ #include /* FILE */ @@ -48,6 +52,9 @@ #include /* struct addrinfo */ #endif +#ifdef SYS_WIN +//typedef int _Bool; +#endif /* * V I S I B I L I T Y @@ -1256,3 +1263,5 @@ int get_read_timeout(void); #endif #endif /* DNS_H */ + +#endif diff --git a/lib_fiber/c/src/event.c b/lib_fiber/c/src/event.c index bfb190b4a..6dfa1d987 100644 --- a/lib_fiber/c/src/event.c +++ b/lib_fiber/c/src/event.c @@ -11,6 +11,8 @@ EVENT *event_create(int size) EVENT *ev = event_epoll_create(size); #elif defined(HAS_KQUEUE) EVENT *ev = event_kqueue_create(size); +#elif defined(SYS_WIN) + EVENT *ev = NULL; #endif ring_init(&ev->events); @@ -18,9 +20,13 @@ EVENT *event_create(int size) ev->setsize = size; ev->maxfd = -1; +#ifdef HAS_POLL ring_init(&ev->poll_list); - ring_init(&ev->epoll_list); +#endif +#ifdef HAS_EPOLL + ring_init(&ev->epoll_list); +#endif return ev; } @@ -259,6 +265,7 @@ static void event_prepare(EVENT *ev) #define TO_APPL ring_to_appl +#ifdef HAS_POLL static inline void event_process_poll(EVENT *ev) { while (1) { @@ -275,6 +282,7 @@ static inline void event_process_poll(EVENT *ev) ring_init(&ev->poll_list); } +#endif #ifdef HAS_EPOLL static void event_process_epoll(EVENT *ev) @@ -314,7 +322,11 @@ int event_process(EVENT *ev, int timeout) event_prepare(ev); ret = ev->event_wait(ev, timeout); + +#ifdef HAS_POLL event_process_poll(ev); +#endif + #ifdef HAS_EPOLL event_process_epoll(ev); #endif diff --git a/lib_fiber/c/src/event.h b/lib_fiber/c/src/event.h index 258c01dea..f07e2f645 100644 --- a/lib_fiber/c/src/event.h +++ b/lib_fiber/c/src/event.h @@ -1,6 +1,9 @@ #ifndef EVENT_INCLUDE_H #define EVENT_INCLUDE_H +#include "define.h" +#include "common/gettimeofday.h" + #ifdef HAS_EPOLL #include #endif @@ -12,18 +15,30 @@ (x) = ((long long) _tv.tv_sec) * 1000 + ((long long) _tv.tv_usec)/ 1000; \ } while (0) -typedef struct POLLFD POLLFD; typedef struct FILE_EVENT FILE_EVENT; +typedef struct EVENT EVENT; + +#ifdef HAS_POLL +typedef struct POLLFD POLLFD; typedef struct POLL_CTX POLL_CTX; typedef struct POLL_EVENT POLL_EVENT; +#endif + +#ifdef HAS_EPOLL typedef struct EPOLL_CTX EPOLL_CTX; typedef struct EPOLL_EVENT EPOLL_EVENT; -typedef struct EVENT EVENT; +#endif typedef int event_oper(EVENT *ev, FILE_EVENT *fe); typedef void event_proc(EVENT *ev, FILE_EVENT *fe); + +#ifdef HAS_POLL typedef void poll_proc(EVENT *ev, POLL_EVENT *pe); +#endif + +#ifdef HAS_EPOLL typedef void epoll_proc(EVENT *ev, EPOLL_EVENT *ee); +#endif /** * for each connection fd @@ -51,12 +66,15 @@ struct FILE_EVENT { event_proc *r_proc; event_proc *w_proc; +#ifdef HAS_POLL POLLFD *pfd; -#ifdef HAS_EPOLL +#endif +#ifdef HAS_EPOLL EPOLL_CTX *epx; #endif }; +#ifdef HAS_POLL struct POLLFD { FILE_EVENT *fe; POLL_EVENT *pe; @@ -71,6 +89,7 @@ struct POLL_EVENT { int nfds; POLLFD *fds; }; +#endif #ifdef HAS_EPOLL struct EPOLL_CTX { @@ -103,8 +122,12 @@ struct EVENT { int setsize; int maxfd; +#ifdef HAS_POLL RING poll_list; +#endif +#ifdef HAS_EPOLL RING epoll_list; +#endif const char *(*name)(void); int (*handle)(EVENT *); @@ -131,8 +154,8 @@ int event_size(EVENT *ev); void event_free(EVENT *ev); void event_close(EVENT *ev, FILE_EVENT *fe); -int event_add_read(EVENT *ev, FILE_EVENT *fe, event_proc *proc); -int event_add_write(EVENT *ev, FILE_EVENT *fe, event_proc *proc); +int event_add_read(EVENT *ev, FILE_EVENT *fe, event_proc *proc); +int event_add_write(EVENT *ev, FILE_EVENT *fe, event_proc *proc); void event_del_read(EVENT *ev, FILE_EVENT *fe); void event_del_write(EVENT *ev, FILE_EVENT *fe); int event_process(EVENT *ev, int left); diff --git a/lib_fiber/c/src/fiber.c b/lib_fiber/c/src/fiber.c index 313e61447..6be144292 100644 --- a/lib_fiber/c/src/fiber.c +++ b/lib_fiber/c/src/fiber.c @@ -24,121 +24,26 @@ static fcntl_fn __sys_fcntl = NULL; typedef struct THREAD { RING ready; /* ready fiber queue */ RING dead; /* dead fiber queue */ - ACL_FIBER **fibers; - unsigned size; - unsigned slot; - int exitcode; - ACL_FIBER *running; - ACL_FIBER original; - int errnum; - unsigned idgen; - int count; - size_t switched; - int nlocal; + ACL_FIBER **fibers; + unsigned size; + unsigned slot; + int exitcode; + ACL_FIBER *running; + ACL_FIBER *original; + int errnum; + unsigned idgen; + int count; + size_t switched; + int nlocal; } THREAD; -static void fiber_init(void) __attribute__ ((constructor)); - -static THREAD *__main_fiber = NULL; +static THREAD *__main_fiber = NULL; static __thread THREAD *__thread_fiber = NULL; static __thread int __scheduled = 0; -__thread int var_hook_sys_api = 0; +__thread int var_hook_sys_api = 0; static pthread_key_t __fiber_key; - -#ifdef FIBER_STACK_GUARD - -static size_t page_size(void) -{ - static __thread long pgsz = 0; - - if (pgsz == 0) { - pgsz = sysconf(_SC_PAGE_SIZE); - assert(pgsz > 0); - } - - return (size_t) pgsz; -} - -static size_t stack_size(size_t size) -{ - size_t pgsz = page_size(), sz; - if (size < pgsz) { - size = pgsz; - } - sz = (size + pgsz - 1) & ~(pgsz - 1); - return sz; -} - -static void *stack_alloc(size_t size) -{ - int ret; - char *ptr = NULL; - size_t pgsz = page_size(); - - size = stack_size(size); - size += pgsz; - - ret = posix_memalign((void *) &ptr, pgsz, size); - if (ret != 0) { - msg_fatal("%s(%d), %s: posix_memalign error %s", - __FILE__, __LINE__, __FUNCTION__, last_serror()); - } - - ret = mprotect(ptr, pgsz, PROT_NONE); - if (ret != 0) { - msg_fatal("%s(%d), %s: mprotect error=%s", - __FILE__, __LINE__, __FUNCTION__, last_serror()); - } - - ptr += pgsz; - return ptr; -} - -static void stack_free(void *ptr) -{ - int ret; - size_t pgsz = page_size(); - - ptr = (char *) ptr - pgsz; - ret = mprotect(ptr, page_size(), PROT_READ|PROT_WRITE); - if (ret != 0) { - msg_fatal("%s(%d), %s: mprotect error=%s", - __FILE__, __LINE__, __FUNCTION__, last_serror()); - } - free(ptr); -} - -#else - -static void *stack_alloc(size_t size) -{ - return malloc(size); -} - -static void stack_free(void *ptr) -{ - free(ptr); -} - -#endif - -#ifndef USE_JMP -static void *stack_calloc(size_t size) -{ - void* ptr = stack_alloc(size); - if (ptr) { - memset(ptr, 0, size); - } - return ptr; -} -#endif - -/****************************************************************************/ - -/* forward declare */ -static ACL_FIBER *fiber_alloc(void (*fn)(ACL_FIBER *, void *), - void *arg, size_t size); +static void fiber_init(void); void acl_fiber_hook_api(int onoff) { @@ -161,9 +66,8 @@ static void thread_free(void *ctx) if (tf->fibers) { free(tf->fibers); } - if (tf->original.context) { - free(tf->original.context); - } + + tf->original->free_fn(tf->original); free(tf); if (__main_fiber == __thread_fiber) { @@ -205,21 +109,16 @@ static void fiber_check(void) } __thread_fiber = (THREAD *) calloc(1, sizeof(THREAD)); -#ifdef USE_JMP - /* set context NULL when using setjmp that setcontext will not be - * called in fiber_swap. - */ - __thread_fiber->original.context = NULL; -#else - __thread_fiber->original.context = (ucontext_t *) - stack_calloc(sizeof(ucontext_t)); + +#ifdef SYS_UNIX + __thread_fiber->original = fiber_unix_origin(); #endif - __thread_fiber->fibers = NULL; - __thread_fiber->size = 0; - __thread_fiber->slot = 0; - __thread_fiber->idgen = 0; - __thread_fiber->count = 0; - __thread_fiber->nlocal = 0; + __thread_fiber->fibers = NULL; + __thread_fiber->size = 0; + __thread_fiber->slot = 0; + __thread_fiber->idgen = 0; + __thread_fiber->count = 0; + __thread_fiber->nlocal = 0; ring_init(&__thread_fiber->ready); ring_init(&__thread_fiber->dead); @@ -278,6 +177,8 @@ void acl_fiber_sys_errno_set(int errnum) *__sys_errno() = errnum; } +#ifdef SYS_UNIX + int fcntl(int fd, int cmd, ...) { long arg; @@ -323,6 +224,8 @@ int fcntl(int fd, int cmd, ...) return ret; } +#endif + void acl_fiber_set_errno(ACL_FIBER *fiber, int errnum) { if (fiber == NULL) { @@ -364,7 +267,7 @@ void fiber_save_errno(void) } if ((curr = __thread_fiber->running) == NULL) { - curr = &__thread_fiber->original; + curr = __thread_fiber->original; } if (curr->flag & FIBER_F_SAVE_ERRNO) { @@ -379,95 +282,6 @@ void fiber_save_errno(void) } } -#if defined(__x86_64__) - -# if defined(__AVX__) -# define CLOBBER \ - , "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",\ - "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" -# else -# define CLOBBER -# endif - -// asm(".cfi_undefined rip;\r\n") - -# define SETJMP(ctx) ({\ - int ret;\ - asm("lea LJMPRET%=(%%rip), %%rcx\n\t"\ - "xor %%rax, %%rax\n\t"\ - "mov %%rbx, (%%rdx)\n\t"\ - "mov %%rbp, 8(%%rdx)\n\t"\ - "mov %%r12, 16(%%rdx)\n\t"\ - "mov %%rsp, 24(%%rdx)\n\t"\ - "mov %%r13, 32(%%rdx)\n\t"\ - "mov %%r14, 40(%%rdx)\n\t"\ - "mov %%r15, 48(%%rdx)\n\t"\ - "mov %%rcx, 56(%%rdx)\n\t"\ - "mov %%rdi, 64(%%rdx)\n\t"\ - "mov %%rsi, 72(%%rdx)\n\t"\ - "LJMPRET%=:\n\t"\ - : "=a" (ret)\ - : "d" (ctx)\ - : "memory", "rcx", "r8", "r9", "r10", "r11",\ - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",\ - "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"\ - CLOBBER\ - );\ - ret;\ -}) - -# define LONGJMP(ctx) \ - asm("movq (%%rax), %%rbx\n\t"\ - "movq 8(%%rax), %%rbp\n\t"\ - "movq 16(%%rax), %%r12\n\t"\ - "movq 24(%%rax), %%rdx\n\t"\ - "movq 32(%%rax), %%r13\n\t"\ - "movq 40(%%rax), %%r14\n\t"\ - "mov %%rdx, %%rsp\n\t"\ - "movq 48(%%rax), %%r15\n\t"\ - "movq 56(%%rax), %%rdx\n\t"\ - "movq 64(%%rax), %%rdi\n\t"\ - "movq 72(%%rax), %%rsi\n\t"\ - "jmp *%%rdx\n\t"\ - : : "a" (ctx) : "rdx" \ - ) - -#elif defined(__i386__) - -# define SETJMP(ctx) ({\ - int ret;\ - asm("movl $LJMPRET%=, %%eax\n\t"\ - "movl %%eax, (%%edx)\n\t"\ - "movl %%ebx, 4(%%edx)\n\t"\ - "movl %%esi, 8(%%edx)\n\t"\ - "movl %%edi, 12(%%edx)\n\t"\ - "movl %%ebp, 16(%%edx)\n\t"\ - "movl %%esp, 20(%%edx)\n\t"\ - "xorl %%eax, %%eax\n\t"\ - "LJMPRET%=:\n\t"\ - : "=a" (ret) : "d" (ctx) : "memory");\ - ret;\ - }) - -# define LONGJMP(ctx) \ - asm("movl (%%eax), %%edx\n\t"\ - "movl 4(%%eax), %%ebx\n\t"\ - "movl 8(%%eax), %%esi\n\t"\ - "movl 12(%%eax), %%edi\n\t"\ - "movl 16(%%eax), %%ebp\n\t"\ - "movl 20(%%eax), %%esp\n\t"\ - "jmp *%%edx\n\t"\ - : : "a" (ctx) : "edx" \ - ) - -#else - -# define SETJMP(ctx) \ - sigsetjmp(ctx, 0) -# define LONGJMP(ctx) \ - siglongjmp(ctx, 1) -#endif - static void fiber_kick(int max) { RING *head; @@ -509,26 +323,7 @@ static void fiber_swap(ACL_FIBER *from, ACL_FIBER *to) ring_prepend(&__thread_fiber->dead, &from->me); } -#ifdef USE_JMP - /* use setcontext() for the initial jump, as it allows us to set up - * a stack, but continue with longjmp() as it's much faster. - */ - if (SETJMP(from->env) == 0) { - /* context just be used once for set up a stack, which will - * be freed in fiber_start. The context in __thread_fiber - * was set NULL. - */ - if (to->context != NULL) { - setcontext(to->context); - } else { - LONGJMP(to->env); - } - } -#else - if (swapcontext(from->context, to->context) < 0) - msg_fatal("%s(%d), %s: swapcontext error %s", - __FILE__, __LINE__, __FUNCTION__, last_serror()); -#endif + from->swap_fn(from, to); } static void check_timer(ACL_FIBER *fiber fiber_unused, void *ctx) @@ -538,7 +333,11 @@ static void check_timer(ACL_FIBER *fiber fiber_unused, void *ctx) free(intptr); while (1) { +#ifdef SYS_WIN + Sleep(1000); +#else sleep(1); +#endif fiber_kick((int) max); } } @@ -559,7 +358,7 @@ ACL_FIBER *acl_fiber_running(void) void acl_fiber_kill(ACL_FIBER *fiber) { - acl_fiber_signal(fiber, SIGKILL); + acl_fiber_signal(fiber, SIGTERM); } int acl_fiber_killed(ACL_FIBER *fiber) @@ -586,7 +385,11 @@ void acl_fiber_signal(ACL_FIBER *fiber, int signum) return; } +#ifdef SYS_WIN + if (signum == SIGTERM) { +#else if (signum == SIGKILL || signum == SIGTERM || signum == SIGQUIT) { +#endif fiber->errnum = ECANCELED; fiber->flag |= FIBER_F_KILLED; } @@ -659,52 +462,6 @@ int acl_fiber_yield(void) return abs(__thread_fiber->switched - n - 1); } -union cc_arg -{ - void *p; - int i[2]; -}; - -static void fiber_start(unsigned int x, unsigned int y) -{ - union cc_arg arg; - ACL_FIBER *fiber; - int i; - - arg.i[0] = x; - arg.i[1] = y; - - fiber = (ACL_FIBER *) arg.p; - -#ifdef USE_JMP - /* when using setjmp/longjmp, the context just be used only once */ - if (fiber->context != NULL) { - stack_free(fiber->context); - fiber->context = NULL; - } -#endif - - fiber->fn(fiber, fiber->arg); - - for (i = 0; i < fiber->nlocal; i++) { - if (fiber->locals[i] == NULL) { - continue; - } - if (fiber->locals[i]->free_fn) { - fiber->locals[i]->free_fn(fiber->locals[i]->ctx); - } - free(fiber->locals[i]); - } - - if (fiber->locals) { - free(fiber->locals); - fiber->locals = NULL; - fiber->nlocal = 0; - } - - fiber_exit(0); -} - int acl_fiber_ndead(void) { if (__thread_fiber == NULL) { @@ -750,24 +507,39 @@ void fbase_free(FIBER_BASE *fbase) void fiber_free(ACL_FIBER *fiber) { -#ifdef USE_VALGRIND - VALGRIND_STACK_DEREGISTER(fiber->vid); -#endif fbase_finish(&fiber->base); + fiber->free_fn(fiber); +} - if (fiber->context) { - stack_free(fiber->context); +static void fiber_start(ACL_FIBER *fiber) +{ + int i; + + fiber->fn(fiber, fiber->arg); + + for (i = 0; i < fiber->nlocal; i++) { + if (fiber->locals[i] == NULL) { + continue; + } + if (fiber->locals[i]->free_fn) { + fiber->locals[i]->free_fn(fiber->locals[i]->ctx); + } + free(fiber->locals[i]); } - stack_free(fiber->buff); - free(fiber); + + if (fiber->locals) { + free(fiber->locals); + fiber->locals = NULL; + fiber->nlocal = 0; + } + + fiber_exit(0); } static ACL_FIBER *fiber_alloc(void (*fn)(ACL_FIBER *, void *), void *arg, size_t size) { - ACL_FIBER *fiber; - sigset_t zero; - union cc_arg carg; + ACL_FIBER *fiber = NULL; RING *head; fiber_check(); @@ -777,10 +549,9 @@ static ACL_FIBER *fiber_alloc(void (*fn)(ACL_FIBER *, void *), /* try to reuse the fiber memory in dead queue */ head = ring_pop_head(&__thread_fiber->dead); if (head == NULL) { - fiber = (ACL_FIBER *) calloc(1, sizeof(ACL_FIBER)); - /* no using calloc just avoiding using real memory */ - fiber->buff = (char *) stack_alloc(size); - fbase_init(&fiber->base, FBASE_F_FIBER); +#ifdef SYS_UNIX + fiber = fiber_unix_alloc(fiber_start); +#endif } else if ((fiber = APPL(head, ACL_FIBER, me))->size < size) { /* if using realloc, real memory will be used, when we first * free and malloc again, then we'll just use virtual memory, @@ -788,8 +559,9 @@ static ACL_FIBER *fiber_alloc(void (*fn)(ACL_FIBER *, void *), */ stack_free(fiber->buff); fiber->buff = (char *) stack_alloc(size); - } else + } else { size = fiber->size; + } __thread_fiber->idgen++; if (__thread_fiber->idgen == 0) { /* overflow ? */ @@ -808,46 +580,9 @@ static ACL_FIBER *fiber_alloc(void (*fn)(ACL_FIBER *, void *), fiber->waiting = NULL; ring_init(&fiber->holding); - carg.p = fiber; - - if (fiber->context == NULL) { - fiber->context = (ucontext_t *) stack_alloc(sizeof(ucontext_t)); - } - memset(fiber->context, 0, sizeof(ucontext_t)); - - sigemptyset(&zero); - sigaddset(&zero, SIGPIPE); - sigaddset(&zero, SIGSYS); - sigaddset(&zero, SIGALRM); - sigaddset(&zero, SIGURG); - sigaddset(&zero, SIGWINCH); -// sigaddset(&zero, SIGINT); -// sigaddset(&zero, SIGHUP); - sigprocmask(SIG_BLOCK, &zero, &fiber->context->uc_sigmask); - - if (getcontext(fiber->context) < 0) { - msg_fatal("%s(%d), %s: getcontext error: %s", - __FILE__, __LINE__, __FUNCTION__, last_serror()); - } - - fiber->context->uc_stack.ss_sp = fiber->buff + 8; - fiber->context->uc_stack.ss_size = fiber->size - 64; - -#ifdef USE_JMP - fiber->context->uc_link = NULL; -#else - fiber->context->uc_link = __thread_fiber->original.context; +#ifdef SYS_UNIX + fiber_unit_init(fiber) #endif - -#ifdef USE_VALGRIND - /* avoding the valgrind's warning */ - fiber->vid = VALGRIND_STACK_REGISTER(fiber->context->uc_stack.ss_sp, - (char*) fiber->context->uc_stack.ss_sp - + fiber->context->uc_stack.ss_size); -#endif - makecontext(fiber->context, (void(*)(void)) fiber_start, - 2, carg.i[0], carg.i[1]); - return fiber; } @@ -859,7 +594,7 @@ ACL_FIBER *acl_fiber_create(void (*fn)(ACL_FIBER *, void *), __thread_fiber->count++; if (__thread_fiber->slot >= __thread_fiber->size) { - __thread_fiber->size += 128; + __thread_fiber->size += 128; __thread_fiber->fibers = (ACL_FIBER **) realloc( __thread_fiber->fibers, __thread_fiber->size * sizeof(ACL_FIBER *)); @@ -894,6 +629,8 @@ int acl_fiber_status(const ACL_FIBER *fiber) static void fiber_init(void) { +#ifdef SYS_UNIX + static pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; static int __called = 0; @@ -914,6 +651,7 @@ static void fiber_init(void) __sys_fcntl = (fcntl_fn) dlsym(RTLD_NEXT, "fcntl"); (void) pthread_mutex_unlock(&__lock); +#endif } void acl_fiber_schedule(void) @@ -942,7 +680,7 @@ void acl_fiber_schedule(void) __thread_fiber->running = fiber; __thread_fiber->switched++; - fiber_swap(&__thread_fiber->original, fiber); + fiber_swap(__thread_fiber->original, fiber); __thread_fiber->running = NULL; } @@ -999,7 +737,7 @@ void acl_fiber_switch(void) #else msg_info("thread-%lu: NO FIBER in ready", pthread_self()); #endif - fiber_swap(current, &__thread_fiber->original); + fiber_swap(current, __thread_fiber->original); return; } diff --git a/lib_fiber/c/src/fiber.h b/lib_fiber/c/src/fiber.h index 0e9cca2e1..3419df68d 100644 --- a/lib_fiber/c/src/fiber.h +++ b/lib_fiber/c/src/fiber.h @@ -1,8 +1,6 @@ #ifndef FIBER_INCLUDE_H #define FIBER_INCLUDE_H -#include -#include #include "event.h" #ifdef ACL_ARM_LINUX @@ -37,9 +35,6 @@ typedef struct FIBER_BASE { struct ACL_FIBER { FIBER_BASE base; -#ifdef USE_VALGRIND - unsigned int vid; -#endif fiber_status_t status; RING me; unsigned id; @@ -59,19 +54,15 @@ struct ACL_FIBER { FIBER_LOCAL **locals; int nlocal; -#ifdef USE_JMP -# if defined(__x86_64__) - unsigned long long env[10]; -# else - sigjmp_buf env; -# endif -#endif - ucontext_t *context; - void (*fn)(ACL_FIBER *, void *); - void *arg; - void (*timer_fn)(ACL_FIBER *, void *); - size_t size; - char *buff; + void (*free_fn)(ACL_FIBER *); + void (*swap_fn)(ACL_FIBER *, ACL_FIBER *); + void (*start_fn)(ACL_FIBER *); + + void (*fn)(ACL_FIBER *, void *); + void *arg; + void (*timer_fn)(ACL_FIBER *, void *); + size_t size; + char *buff; }; /* in fiber.c */ diff --git a/lib_fiber/c/src/fiber/fiber_unix.c b/lib_fiber/c/src/fiber/fiber_unix.c new file mode 100644 index 000000000..824975a40 --- /dev/null +++ b/lib_fiber/c/src/fiber/fiber_unix.c @@ -0,0 +1,254 @@ +#include "stdafx.h" +#include "common.h" +#include "fiber.h" + +#ifdef SYS_UNIX + +typedef struct ucontext_t { int dummy; } ucontext_t; + +typedef struct FIBER_UNIX { + ACL_FIBER fiber; +#ifdef USE_VALGRIND + unsigned int vid; +#endif + +#ifdef USE_JMP +# if defined(__x86_64__) + unsigned long long env[10]; +# else + sigjmp_buf env; +# endif +#endif + ucontext_t *context; +} FIBER_UNIX; + +#if defined(__x86_64__) +# if defined(__AVX__) +# define CLOBBER \ + , "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", \ + "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" +# else +# define CLOBBER +# endif + +// asm(".cfi_undefined rip;\r\n") +# define SETJMP(ctx) ({\ + int ret; \ + asm("lea LJMPRET%=(%%rip), %%rcx\n\t"\ + "xor %%rax, %%rax\n\t"\ + "mov %%rbx, (%%rdx)\n\t"\ + "mov %%rbp, 8(%%rdx)\n\t"\ + "mov %%r12, 16(%%rdx)\n\t"\ + "mov %%rsp, 24(%%rdx)\n\t"\ + "mov %%r13, 32(%%rdx)\n\t"\ + "mov %%r14, 40(%%rdx)\n\t"\ + "mov %%r15, 48(%%rdx)\n\t"\ + "mov %%rcx, 56(%%rdx)\n\t"\ + "mov %%rdi, 64(%%rdx)\n\t"\ + "mov %%rsi, 72(%%rdx)\n\t"\ + "LJMPRET%=:\n\t"\ + : "=a" (ret)\ + : "d" (ctx)\ + : "memory", "rcx", "r8", "r9", "r10", "r11", \ + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", \ + "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"\ + CLOBBER\ + ); \ + ret; \ +}) + +# define LONGJMP(ctx) \ + asm("movq (%%rax), %%rbx\n\t"\ + "movq 8(%%rax), %%rbp\n\t"\ + "movq 16(%%rax), %%r12\n\t"\ + "movq 24(%%rax), %%rdx\n\t"\ + "movq 32(%%rax), %%r13\n\t"\ + "movq 40(%%rax), %%r14\n\t"\ + "mov %%rdx, %%rsp\n\t"\ + "movq 48(%%rax), %%r15\n\t"\ + "movq 56(%%rax), %%rdx\n\t"\ + "movq 64(%%rax), %%rdi\n\t"\ + "movq 72(%%rax), %%rsi\n\t"\ + "jmp *%%rdx\n\t"\ + : : "a" (ctx) : "rdx" \ + ) + +#elif defined(__i386__) + +# define SETJMP(ctx) ({\ + int ret; \ + asm("movl $LJMPRET%=, %%eax\n\t"\ + "movl %%eax, (%%edx)\n\t"\ + "movl %%ebx, 4(%%edx)\n\t"\ + "movl %%esi, 8(%%edx)\n\t"\ + "movl %%edi, 12(%%edx)\n\t"\ + "movl %%ebp, 16(%%edx)\n\t"\ + "movl %%esp, 20(%%edx)\n\t"\ + "xorl %%eax, %%eax\n\t"\ + "LJMPRET%=:\n\t"\ + : "=a" (ret) : "d" (ctx) : "memory"); \ + ret; \ + }) + +# define LONGJMP(ctx) \ + asm("movl (%%eax), %%edx\n\t"\ + "movl 4(%%eax), %%ebx\n\t"\ + "movl 8(%%eax), %%esi\n\t"\ + "movl 12(%%eax), %%edi\n\t"\ + "movl 16(%%eax), %%ebp\n\t"\ + "movl 20(%%eax), %%esp\n\t"\ + "jmp *%%edx\n\t"\ + : : "a" (ctx) : "edx" \ + ) + +#else + +# define SETJMP(ctx) \ + sigsetjmp(ctx, 0) +# define LONGJMP(ctx) \ + siglongjmp(ctx, 1) +#endif + +static void fiber_unix_swap(ACL_FIBER *from, ACL_FIBER *to) +{ +#ifdef USE_JMP + /* use setcontext() for the initial jump, as it allows us to set up + * a stack, but continue with longjmp() as it's much faster. + */ + if (SETJMP(from->env) == 0) { + /* context just be used once for set up a stack, which will + * be freed in fiber_start. The context in __thread_fiber + * was set NULL. + */ + if (to->context != NULL) { + setcontext(to->context); + } + else { + LONGJMP(to->env); + } + } +#else + if (swapcontext(from->context, to->context) < 0) { + msg_fatal("%s(%d), %s: swapcontext error %s", + __FILE__, __LINE__, __FUNCTION__, last_serror()); + } +#endif +} + +static void fiber_unix_free(ACL_FIBER *fiber) +{ + FIBER_UNIX *fb = (FIBER_UNIX *) fiber; + +#ifdef USE_VALGRIND + VALGRIND_STACK_DEREGISTER(fiber->vid); +#endif + if (fb->context) { + free(fb->context); + } + stack_free(fiber->buff); + free(fb); +} + +ACL_FIBER *fiber_unix_origin(void) +{ + FIBER_UNIX *fb = (FIBER_UNIX *)calloc(1, sizeof(*fb)); + +#ifdef USE_JMP + /* set context NULL when using setjmp that setcontext will not be + * called in fiber_swap. + */ + fb->context = NULL; +#else + fb->context = (ucontext_t *) stack_calloc(sizeof(ucontext_t)); +#endif + fb->fiber.free_fn = fiber_unix_free; + return fb; +} + +union cc_arg +{ + void *p; + int i[2]; +}; + +static void fiber_unix_start(unsigned int x, unsigned int y) +{ + union cc_arg arg; + FIBER_UNIX *fb; + + arg.i[0] = x; + arg.i[1] = y; + + fb = (FIBER_UNIX *)arg.p; + +#ifdef USE_JMP + /* when using setjmp/longjmp, the context just be used only once */ + if (fb->context != NULL) { + stack_free(fb->context); + fb->context = NULL; + } +#endif + fb->fiber.start_fn(&fb->fiber); +} + +ACL_FIBER *fiber_unix_alloc(void(*start_fn)(ACL_FIBER *)) +{ + FIBER_UNIX *fb = (FIBER_UNIX *)calloc(1, sizeof(*fb)); + + fbase_init(&fb->fiber.base, FBASE_F_FIBER); + + /* no using calloc just avoiding using real memory */ + fb->fiber.buff = (char *) stack_alloc(size); + fb->fiber.free_fn = fiber_unix_free; + fb->fiber.swap_fn = fiber_unix_swap; + fb->fiber.start_fn = start_fn; + + return (ACL_FIBER *) fb; +} + +void fiber_unix_init(ACL_FIBER *fiber) +{ + FIBER_UNIX *fb = (FIBER_UNIX *) fiber; + union cc_arg carg; + sigset_t zero; + + carg.p = fiber; + + if (fb->context == NULL) { + fiber->context = (ucontext_t *) stack_alloc(sizeof(ucontext_t)); + } + memset(fb->context, 0, sizeof(ucontext_t)); + + sigemptyset(&zero); + sigaddset(&zero, SIGPIPE); + sigaddset(&zero, SIGSYS); + sigaddset(&zero, SIGALRM); + sigaddset(&zero, SIGURG); + sigaddset(&zero, SIGWINCH); + sigprocmask(SIG_BLOCK, &zero, &fb->context->uc_sigmask); + + if (getcontext(fb->context) < 0) { + msg_fatal("%s(%d), %s: getcontext error: %s", + __FILE__, __LINE__, __FUNCTION__, last_serror()); + } + + fb->context->uc_stack.ss_sp = fb->buff + 8; + fb->context->uc_stack.ss_size = fb->size - 64; + +#ifdef USE_JMP + fb->context->uc_link = NULL; +#else + fb->context->uc_link = __thread_fiber->original->context; +#endif + +#ifdef USE_VALGRIND + /* avoding the valgrind's warning */ + fb->vid = VALGRIND_STACK_REGISTER(fb->context->uc_stack.ss_sp, + (char*)fb->context->uc_stack.ss_sp + + fb->context->uc_stack.ss_size); +#endif + makecontext(fb->context, (void(*)(void)) unix_fiber_start, + 2, carg.i[0], carg.i[1]); +} + +#endif diff --git a/lib_fiber/c/src/fiber/fiber_win.c b/lib_fiber/c/src/fiber/fiber_win.c new file mode 100644 index 000000000..fd4f341c7 --- /dev/null +++ b/lib_fiber/c/src/fiber/fiber_win.c @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/lib_fiber/c/src/fiber_event.c b/lib_fiber/c/src/fiber_event.c index 6d7a8dd6b..57d8526e4 100644 --- a/lib_fiber/c/src/fiber_event.c +++ b/lib_fiber/c/src/fiber_event.c @@ -1,6 +1,8 @@ #include "stdafx.h" #include "common.h" +#ifdef SYS_UNIX + #ifdef LINUX # include # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) @@ -70,7 +72,7 @@ void acl_fiber_event_free(ACL_FIBER_EVENT *event) free(event); } -static inline void channel_open(FIBER_BASE *fbase) +static void channel_open(FIBER_BASE *fbase) { #if defined(HAS_EVENTFD) int flags = 0; @@ -260,3 +262,5 @@ int acl_fiber_event_notify(ACL_FIBER_EVENT *event) return 0; } + +#endif // SYS_UNIX diff --git a/lib_fiber/c/src/fiber_io.c b/lib_fiber/c/src/fiber_io.c index 5b875d9ad..6b1a015f4 100644 --- a/lib_fiber/c/src/fiber_io.c +++ b/lib_fiber/c/src/fiber_io.c @@ -2,6 +2,7 @@ #include "common.h" #include "fiber/lib_fiber.h" +#include "common/gettimeofday.h" #include "event.h" #include "fiber.h" @@ -161,7 +162,7 @@ static void fiber_io_loop(ACL_FIBER *self fiber_unused, void *ctx) assert(left < INT_MAX); /* add 1 just for the deviation of epoll_wait */ - event_process(ev, left > 0 ? left + 1 : (int) left); + event_process(ev, left > 0 ? (int) left + 1 : (int) left); if (__thread_fiber->io_stop) { break; @@ -258,7 +259,7 @@ unsigned int acl_fiber_delay(unsigned int milliseconds) if (ring_size(&__thread_fiber->ev_timer) == 0) { ev->timeout = -1; } else { - ev->timeout = min; + ev->timeout = (int) min; } SET_TIME(now); @@ -280,7 +281,7 @@ static void fiber_timer_callback(ACL_FIBER *fiber, void *ctx) break; } - acl_fiber_delay(left); + acl_fiber_delay((unsigned int) left); SET_TIME(now); if (fiber->when <= now) { diff --git a/lib_fiber/c/src/fiber_lock.c b/lib_fiber/c/src/fiber_lock.c index 638975baf..f51cae039 100644 --- a/lib_fiber/c/src/fiber_lock.c +++ b/lib_fiber/c/src/fiber_lock.c @@ -17,6 +17,8 @@ struct ACL_FIBER_RWLOCK { RING wwaiting; }; +#ifdef SYS_UNIX + ACL_FIBER_MUTEX *acl_fiber_mutex_create(void) { ACL_FIBER_MUTEX *lk = (ACL_FIBER_MUTEX *) malloc(sizeof(ACL_FIBER_MUTEX)); @@ -229,3 +231,5 @@ void acl_fiber_rwlock_wunlock(ACL_FIBER_RWLOCK *lk) acl_fiber_ready(fiber); } } + +#endif diff --git a/lib_fiber/c/src/fiber_sem.c b/lib_fiber/c/src/fiber_sem.c index ec85381b1..902e1ec1c 100644 --- a/lib_fiber/c/src/fiber_sem.c +++ b/lib_fiber/c/src/fiber_sem.c @@ -30,9 +30,9 @@ pthread_t acl_fiber_sem_get_tid(ACL_FIBER_SEM *sem) return sem->tid; } -void acl_fiber_sem_set_tid(ACL_FIBER_SEM *sem, pthread_t tid) +void acl_fiber_sem_set_tid(ACL_FIBER_SEM *sem, unsigned long tid) { - if (sem->tid != tid && ring_size(&sem->waiting) > 0) { + if ((unsigned long) sem->tid != tid && ring_size(&sem->waiting) > 0) { msg_fatal("%s(%d), %s: curr sem waiting=%d not empty", __FILE__, __LINE__, __FUNCTION__, (int) ring_size(&sem->waiting)); diff --git a/lib_fiber/c/src/file_event.c b/lib_fiber/c/src/file_event.c index 7afe821f8..574f80c89 100644 --- a/lib_fiber/c/src/file_event.c +++ b/lib_fiber/c/src/file_event.c @@ -14,7 +14,9 @@ void file_event_init(FILE_EVENT *fe, int fd) fe->mask = 0; fe->r_proc = NULL; fe->w_proc = NULL; +#ifdef HAS_POLL fe->pfd = NULL; +#endif } FILE_EVENT *file_event_alloc(int fd) diff --git a/lib_fiber/c/src/hook/dns_init.c b/lib_fiber/c/src/hook/dns_init.c index 8dcdc7d7a..9eb7f05c5 100644 --- a/lib_fiber/c/src/hook/dns_init.c +++ b/lib_fiber/c/src/hook/dns_init.c @@ -1,7 +1,10 @@ #include "stdafx.h" #include "dns/dns.h" +#include "common/pthread.h" #include "hook.h" +#ifdef SYS_UNIX + struct dns_resolv_conf *var_dns_conf = NULL; struct dns_hosts *var_dns_hosts = NULL; struct dns_hints *var_dns_hints = NULL; @@ -31,8 +34,13 @@ static void dns_on_exit(void) void dns_init(void) { +#ifdef SYS_WIN + static pthread_mutex_t __lock; +#elif defined(SYS_UNIX) static pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; +#endif static int __called = 0; + int err; (void) pthread_mutex_lock(&__lock); @@ -43,7 +51,7 @@ void dns_init(void) __called++; - int err = 0; + err = 0; var_dns_conf = dns_resconf_local(&err); assert(var_dns_conf && err == 0); var_dns_conf->options.timeout = 1000; @@ -58,3 +66,5 @@ void dns_init(void) (void) pthread_mutex_unlock(&__lock); } + +#endif diff --git a/lib_fiber/c/src/hook/getaddrinfo.c b/lib_fiber/c/src/hook/getaddrinfo.c index 64ca7ee94..2cba5025f 100644 --- a/lib_fiber/c/src/hook/getaddrinfo.c +++ b/lib_fiber/c/src/hook/getaddrinfo.c @@ -1,5 +1,4 @@ #include "stdafx.h" -#include #include "dns/dns.h" #include "dns/sane_inet.h" #include "common.h" @@ -13,6 +12,8 @@ typedef void (*freeaddrinfo_fn)(struct addrinfo *res); static getaddrinfo_fn __sys_getaddrinfo = NULL; static freeaddrinfo_fn __sys_freeaddrinfo = NULL; +#ifdef SYS_UNIX + static void hook_init(void) { static pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; @@ -190,3 +191,5 @@ void freeaddrinfo(struct addrinfo *res) free(tmp); } } + +#endif diff --git a/lib_fiber/c/src/hook/gethostbyname.c b/lib_fiber/c/src/hook/gethostbyname.c index fa812947b..6bcecea0e 100644 --- a/lib_fiber/c/src/hook/gethostbyname.c +++ b/lib_fiber/c/src/hook/gethostbyname.c @@ -8,6 +8,8 @@ typedef int (*gethostbyname_r_fn)(const char *, struct hostent *, char *, static gethostbyname_r_fn __sys_gethostbyname_r = NULL; +#ifdef SYS_UNIX + static void hook_init(void) { static pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; @@ -79,10 +81,10 @@ static int save_result(struct hostent *ent, struct addrinfo *res, if (ai->ai_family == AF_INET) { len = sizeof(struct in_addr); - memcpy(buf, &sa->sa.in.sin_addr, len); + memcpy((void *) buf, &sa->sa.in.sin_addr, len); } else if (ai->ai_family == AF_INET6) { len = sizeof(struct in6_addr); - memcpy(buf, &sa->sa.in6.sin6_addr, len); + memcpy((void *) buf, &sa->sa.in6.sin6_addr, len); } else { continue; } @@ -184,3 +186,5 @@ int gethostbyname_r(const char *name, struct hostent *ent, return -1; } + +#endif diff --git a/lib_fiber/c/src/hook/io.c b/lib_fiber/c/src/hook/io.c index 17b7483bf..9adf0967b 100644 --- a/lib_fiber/c/src/hook/io.c +++ b/lib_fiber/c/src/hook/io.c @@ -41,6 +41,7 @@ static sendfile64_fn __sys_sendfile64 = NULL; static void hook_init(void) { +#ifdef SYS_UNIX static pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; static int __called = 0; @@ -95,6 +96,7 @@ static void hook_init(void) #endif (void) pthread_mutex_unlock(&__lock); +#endif } unsigned int sleep(unsigned int seconds) @@ -154,7 +156,7 @@ int close(int fd) #ifdef READ_WAIT_FIRST -inline ssize_t fiber_read(int fd, void *buf, size_t count) +ssize_t fiber_read(int fd, void *buf, size_t count) { ssize_t ret; FILE_EVENT* fe; @@ -190,7 +192,7 @@ inline ssize_t fiber_read(int fd, void *buf, size_t count) return ret; } -inline ssize_t fiber_readv(int fd, const struct iovec *iov, int iovcnt) +ssize_t fiber_readv(int fd, const struct iovec *iov, int iovcnt) { ssize_t ret; FILE_EVENT *fe; @@ -226,7 +228,7 @@ inline ssize_t fiber_readv(int fd, const struct iovec *iov, int iovcnt) return ret; } -inline ssize_t fiber_recv(int sockfd, void *buf, size_t len, int flags) +ssize_t fiber_recv(int sockfd, void *buf, size_t len, int flags) { ssize_t ret; FILE_EVENT *fe; @@ -262,7 +264,7 @@ inline ssize_t fiber_recv(int sockfd, void *buf, size_t len, int flags) return ret; } -inline ssize_t fiber_recvfrom(int sockfd, void *buf, size_t len, int flags, +ssize_t fiber_recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { ssize_t ret; @@ -300,7 +302,7 @@ inline ssize_t fiber_recvfrom(int sockfd, void *buf, size_t len, int flags, return ret; } -inline ssize_t fiber_recvmsg(int sockfd, struct msghdr *msg, int flags) +ssize_t fiber_recvmsg(int sockfd, struct msghdr *msg, int flags) { ssize_t ret; FILE_EVENT *fe; @@ -338,7 +340,7 @@ inline ssize_t fiber_recvmsg(int sockfd, struct msghdr *msg, int flags) #else -inline ssize_t fiber_read(int fd, void *buf, size_t count) +ssize_t fiber_read(int fd, void *buf, size_t count) { FILE_EVENT *fe; @@ -378,7 +380,7 @@ inline ssize_t fiber_read(int fd, void *buf, size_t count) } } -inline ssize_t fiber_readv(int fd, const struct iovec *iov, int iovcnt) +ssize_t fiber_readv(int fd, const struct iovec *iov, int iovcnt) { FILE_EVENT *fe; @@ -418,7 +420,7 @@ inline ssize_t fiber_readv(int fd, const struct iovec *iov, int iovcnt) } } -inline ssize_t fiber_recv(int sockfd, void *buf, size_t len, int flags) +ssize_t fiber_recv(int sockfd, void *buf, size_t len, int flags) { FILE_EVENT *fe; @@ -458,7 +460,7 @@ inline ssize_t fiber_recv(int sockfd, void *buf, size_t len, int flags) } } -inline ssize_t fiber_recvfrom(int sockfd, void *buf, size_t len, int flags, +ssize_t fiber_recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { FILE_EVENT *fe; @@ -500,7 +502,7 @@ inline ssize_t fiber_recvfrom(int sockfd, void *buf, size_t len, int flags, } } -inline ssize_t fiber_recvmsg(int sockfd, struct msghdr *msg, int flags) +ssize_t fiber_recvmsg(int sockfd, struct msghdr *msg, int flags) { FILE_EVENT *fe; @@ -544,7 +546,7 @@ inline ssize_t fiber_recvmsg(int sockfd, struct msghdr *msg, int flags) /****************************************************************************/ -inline ssize_t fiber_write(int fd, const void *buf, size_t count) +ssize_t fiber_write(int fd, const void *buf, size_t count) { FILE_EVENT *fe; @@ -585,7 +587,7 @@ inline ssize_t fiber_write(int fd, const void *buf, size_t count) } } -inline ssize_t fiber_writev(int fd, const struct iovec *iov, int iovcnt) +ssize_t fiber_writev(int fd, const struct iovec *iov, int iovcnt) { FILE_EVENT *fe; @@ -626,7 +628,7 @@ inline ssize_t fiber_writev(int fd, const struct iovec *iov, int iovcnt) } } -inline ssize_t fiber_send(int sockfd, const void *buf, size_t len, int flags) +ssize_t fiber_send(int sockfd, const void *buf, size_t len, int flags) { FILE_EVENT *fe; @@ -667,7 +669,7 @@ inline ssize_t fiber_send(int sockfd, const void *buf, size_t len, int flags) } } -inline ssize_t fiber_sendto(int sockfd, const void *buf, size_t len, int flags, +ssize_t fiber_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { FILE_EVENT *fe; @@ -710,7 +712,7 @@ inline ssize_t fiber_sendto(int sockfd, const void *buf, size_t len, int flags, } } -inline ssize_t fiber_sendmsg(int sockfd, const struct msghdr *msg, int flags) +ssize_t fiber_sendmsg(int sockfd, const struct msghdr *msg, int flags) { FILE_EVENT *fe; @@ -782,7 +784,7 @@ ssize_t recvmsg(int sockfd, struct msghdr *msg, unsigned int flags) return fiber_recvmsg(sockfd, msg, flags); } -#else +#elif defined(SYS_UNIX) ssize_t recv(int sockfd, void *buf, size_t len, int flags) { @@ -800,8 +802,9 @@ ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) return fiber_recvmsg(sockfd, msg, flags); } -#endif +#endif // SYS_UNIX +#ifdef SYS_UNIX ssize_t write(int fd, const void *buf, size_t count) { return fiber_write(fd, buf, count); @@ -811,6 +814,7 @@ ssize_t writev(int fd, const struct iovec *iov, int iovcnt) { return fiber_writev(fd, iov, iovcnt); } +#endif #ifdef ACL_ARM_LINUX @@ -830,7 +834,7 @@ ssize_t sendmsg(int sockfd, const struct msghdr *msg, unsigned int flags) return fiber_sendmsg(sockfd, msg, (int) flags); } -#else +#elif defined(SYS_UNIX) ssize_t send(int sockfd, const void *buf, size_t len, int flags) { diff --git a/lib_fiber/c/src/hook/poll.c b/lib_fiber/c/src/hook/poll.c index a1d93c6c8..41cfaec36 100644 --- a/lib_fiber/c/src/hook/poll.c +++ b/lib_fiber/c/src/hook/poll.c @@ -5,6 +5,8 @@ #include "event.h" #include "fiber.h" +#ifdef HAS_POLL + typedef int (*poll_fn)(struct pollfd *, nfds_t, int); static poll_fn __sys_poll = NULL; @@ -195,3 +197,4 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout) pollfd_free(pe.fds); return pe.nready; } +#endif diff --git a/lib_fiber/c/src/hook/select.c b/lib_fiber/c/src/hook/select.c index 4dfcd53a5..e062c27f4 100644 --- a/lib_fiber/c/src/hook/select.c +++ b/lib_fiber/c/src/hook/select.c @@ -9,6 +9,8 @@ typedef int (*select_fn)(int, fd_set *, fd_set *, fd_set *, struct timeval *); static select_fn __sys_select = NULL; +#ifdef SYS_UNIX + static void hook_init(void) { static pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; @@ -100,3 +102,5 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, free(fds); return nready; } + +#endif diff --git a/lib_fiber/c/src/hook/socket.c b/lib_fiber/c/src/hook/socket.c index 95e58900b..4307d1c49 100644 --- a/lib_fiber/c/src/hook/socket.c +++ b/lib_fiber/c/src/hook/socket.c @@ -19,6 +19,8 @@ static listen_fn __sys_listen = NULL; static accept_fn __sys_accept = NULL; static connect_fn __sys_connect = NULL; +#ifdef SYS_UNIX + static void hook_init(void) { static pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; @@ -275,3 +277,5 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) return -1; } + +#endif diff --git a/lib_fiber/c/src/stdafx.h b/lib_fiber/c/src/stdafx.h index 966e6f938..54ad2c286 100644 --- a/lib_fiber/c/src/stdafx.h +++ b/lib_fiber/c/src/stdafx.h @@ -1,14 +1,7 @@ #ifndef __STD_AFX_INCLUDE_H__ #define __STD_AFX_INCLUDE_H__ - -#if defined(__linux__) -# define HAS_EPOLL -#elif defined(__FreeBSD__) -# define HAS_KQUEUE -#else -# error "unknown OS" -#endif +#include "define.h" #if 1 #define LIKELY(x) __builtin_expect(!!(x), 1) @@ -25,37 +18,71 @@ #include #include #include -#include -#include #include #include +#include +#include +#include +#include +#include #include +#include +#include + +#if defined(SYS_UNIX) +#include +#include #include #include -#include #include #include #include #include #include #include -#include #include #include -#include -#include -#include -#include +#include +#include + +#define STRDUP strdup +#define GETPID getpid + +#elif defined(SYS_WIN) +# if(_MSC_VER >= 1300) +# include +# include +# else +# include +# endif +# include /* for getaddrinfo */ +# include +# include + +#define STRDUP _strdup +#define GETPID _getpid +#define ssize_t long int +#endif #if defined(__linux__) # include # include #elif defined(__FreeBSD__) # include -#else -# error "unknown OS" #endif -#include "define.h" +struct SOCK_ADDR { + union { + struct sockaddr_storage ss; +#ifdef AF_INET6 + struct sockaddr_in6 in6; +#endif + struct sockaddr_in in; +#ifdef ACL_UNIX + struct sockaddr_un un; +#endif + struct sockaddr sa; + } sa; +}; #endif