mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-29 18:37:41 +08:00
fiber: rewrite fiber's framework for imgrating to windows
This commit is contained in:
parent
7e16c01698
commit
fcb36493b1
@ -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
|
||||
|
@ -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
|
||||
|
@ -5,34 +5,38 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined (_WIN64)
|
||||
typedef long ssize;
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#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*} 应用传递进去的参数
|
||||
* @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
|
||||
* 的操作,是否允许信息输出至标准输出屏幕上,通过此函数来设置该开关,该开关
|
||||
* 仅影响是否需要将信息输出至终端屏幕而不影响是否输出至文件中
|
||||
* @param onoff {int} 非 0 表示允许输出至屏幕
|
||||
*/
|
||||
void msg_stdout_enable(int onoff);
|
||||
|
||||
|
154
lib_fiber/c/lib_fiber.vcxproj
Normal file
154
lib_fiber/c/lib_fiber.vcxproj
Normal file
@ -0,0 +1,154 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{AD99B75A-40BF-46DC-844B-23417FDC8690}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>lib_fiber</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>.\src;.\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\fiber\lib_fiber.h" />
|
||||
<ClInclude Include="src\common.h" />
|
||||
<ClInclude Include="src\common\argv.h" />
|
||||
<ClInclude Include="src\common\array.h" />
|
||||
<ClInclude Include="src\common\atomic.h" />
|
||||
<ClInclude Include="src\common\fifo.h" />
|
||||
<ClInclude Include="src\common\gettimeofday.h" />
|
||||
<ClInclude Include="src\common\init.h" />
|
||||
<ClInclude Include="src\common\iostuff.h" />
|
||||
<ClInclude Include="src\common\iterator.h" />
|
||||
<ClInclude Include="src\common\memory.h" />
|
||||
<ClInclude Include="src\common\msg.h" />
|
||||
<ClInclude Include="src\common\pthread.h" />
|
||||
<ClInclude Include="src\common\ring.h" />
|
||||
<ClInclude Include="src\common\strops.h" />
|
||||
<ClInclude Include="src\define.h" />
|
||||
<ClInclude Include="src\dns\dns.h" />
|
||||
<ClInclude Include="src\dns\sane_inet.h" />
|
||||
<ClInclude Include="src\dns\valid_hostname.h" />
|
||||
<ClInclude Include="src\event.h" />
|
||||
<ClInclude Include="src\event\event_epoll.h" />
|
||||
<ClInclude Include="src\event\event_kqueue.h" />
|
||||
<ClInclude Include="src\fiber.h" />
|
||||
<ClInclude Include="src\hook\hook.h" />
|
||||
<ClInclude Include="src\stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\channel.c" />
|
||||
<ClCompile Include="src\common\argv.c" />
|
||||
<ClCompile Include="src\common\array.c" />
|
||||
<ClCompile Include="src\common\atomic.c" />
|
||||
<ClCompile Include="src\common\close_on_exec.c" />
|
||||
<ClCompile Include="src\common\doze.c" />
|
||||
<ClCompile Include="src\common\fifo.c" />
|
||||
<ClCompile Include="src\common\gettimeofday.c" />
|
||||
<ClCompile Include="src\common\init.c" />
|
||||
<ClCompile Include="src\common\memory.c" />
|
||||
<ClCompile Include="src\common\msg.c" />
|
||||
<ClCompile Include="src\common\non_blocking.c" />
|
||||
<ClCompile Include="src\common\open_limit.c" />
|
||||
<ClCompile Include="src\common\pthread.c" />
|
||||
<ClCompile Include="src\common\ring.c" />
|
||||
<ClCompile Include="src\common\socketpair.c" />
|
||||
<ClCompile Include="src\common\strops.c" />
|
||||
<ClCompile Include="src\common\tcp_nodelay.c" />
|
||||
<ClCompile Include="src\dns\dns.c" />
|
||||
<ClCompile Include="src\dns\sane_inet.c" />
|
||||
<ClCompile Include="src\dns\valid_hostname.c" />
|
||||
<ClCompile Include="src\event.c" />
|
||||
<ClCompile Include="src\event\event_epoll.c" />
|
||||
<ClCompile Include="src\event\event_kqueue.c" />
|
||||
<ClCompile Include="src\fiber.c" />
|
||||
<ClCompile Include="src\fiber\fiber_unix.c" />
|
||||
<ClCompile Include="src\fiber\fiber_win.c" />
|
||||
<ClCompile Include="src\fiber_event.c" />
|
||||
<ClCompile Include="src\fiber_io.c" />
|
||||
<ClCompile Include="src\fiber_lock.c" />
|
||||
<ClCompile Include="src\fiber_sem.c" />
|
||||
<ClCompile Include="src\file_event.c" />
|
||||
<ClCompile Include="src\hook\dns_init.c" />
|
||||
<ClCompile Include="src\hook\epoll.c" />
|
||||
<ClCompile Include="src\hook\getaddrinfo.c" />
|
||||
<ClCompile Include="src\hook\gethostbyname.c" />
|
||||
<ClCompile Include="src\hook\io.c" />
|
||||
<ClCompile Include="src\hook\poll.c" />
|
||||
<ClCompile Include="src\hook\select.c" />
|
||||
<ClCompile Include="src\hook\socket.c" />
|
||||
<ClCompile Include="src\stdafx.c">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
240
lib_fiber/c/lib_fiber.vcxproj.filters
Normal file
240
lib_fiber/c/lib_fiber.vcxproj.filters
Normal file
@ -0,0 +1,240 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="源文件\common">
|
||||
<UniqueIdentifier>{02aaa36c-e182-4878-aea8-17c9c7d99f41}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="源文件\event">
|
||||
<UniqueIdentifier>{356538fb-5e38-4d2d-9519-4cf6ac50944c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="源文件\hook">
|
||||
<UniqueIdentifier>{08cf9220-1c0c-4cc0-b340-6f3f2f00b0f5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="源文件\dns">
|
||||
<UniqueIdentifier>{db249318-674e-46ed-8d7b-05382163acdd}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="源文件\fiber">
|
||||
<UniqueIdentifier>{baaeb113-34bc-4df8-9649-b024ec495a95}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\common\argv.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common\array.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common\atomic.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common\init.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common\iostuff.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common\iterator.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common\msg.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common\ring.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common\strops.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\event\event_epoll.h">
|
||||
<Filter>源文件\event</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\event\event_kqueue.h">
|
||||
<Filter>源文件\event</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\hook\hook.h">
|
||||
<Filter>源文件\hook</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dns\dns.h">
|
||||
<Filter>源文件\dns</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dns\sane_inet.h">
|
||||
<Filter>源文件\dns</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dns\valid_hostname.h">
|
||||
<Filter>源文件\dns</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common.h">
|
||||
<Filter>源文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\define.h">
|
||||
<Filter>源文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\event.h">
|
||||
<Filter>源文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\fiber.h">
|
||||
<Filter>源文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\stdafx.h">
|
||||
<Filter>源文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>源文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\fiber\lib_fiber.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common\fifo.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common\pthread.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common\gettimeofday.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\common\memory.h">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\stdafx.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\argv.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\array.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\atomic.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\close_on_exec.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\doze.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\init.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\msg.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\non_blocking.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\open_limit.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\ring.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\socketpair.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\strops.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\tcp_nodelay.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\event\event_epoll.c">
|
||||
<Filter>源文件\event</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\event\event_kqueue.c">
|
||||
<Filter>源文件\event</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\hook\dns_init.c">
|
||||
<Filter>源文件\hook</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\hook\epoll.c">
|
||||
<Filter>源文件\hook</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\hook\getaddrinfo.c">
|
||||
<Filter>源文件\hook</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\hook\gethostbyname.c">
|
||||
<Filter>源文件\hook</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\hook\io.c">
|
||||
<Filter>源文件\hook</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\hook\poll.c">
|
||||
<Filter>源文件\hook</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\hook\select.c">
|
||||
<Filter>源文件\hook</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\hook\socket.c">
|
||||
<Filter>源文件\hook</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dns\dns.c">
|
||||
<Filter>源文件\dns</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dns\sane_inet.c">
|
||||
<Filter>源文件\dns</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dns\valid_hostname.c">
|
||||
<Filter>源文件\dns</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\channel.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\event.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\fiber.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\fiber_event.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\fiber_io.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\fiber_lock.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\fiber_sem.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\file_event.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\pthread.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\fifo.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\gettimeofday.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\fiber\fiber_unix.c">
|
||||
<Filter>源文件\fiber</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\fiber\fiber_win.c">
|
||||
<Filter>源文件\fiber</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\common\memory.c">
|
||||
<Filter>源文件\common</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
/* 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
|
||||
}
|
||||
|
@ -1,9 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#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) {
|
||||
|
341
lib_fiber/c/src/common/fifo.c
Normal file
341
lib_fiber/c/src/common/fifo.c
Normal file
@ -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;
|
||||
}
|
150
lib_fiber/c/src/common/fifo.h
Normal file
150
lib_fiber/c/src/common/fifo.h
Normal file
@ -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
|
143
lib_fiber/c/src/common/gettimeofday.c
Normal file
143
lib_fiber/c/src/common/gettimeofday.c
Normal file
@ -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 <windows.h>
|
||||
#include <time.h>
|
||||
|
||||
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
|
10
lib_fiber/c/src/common/gettimeofday.h
Normal file
10
lib_fiber/c/src/common/gettimeofday.h
Normal file
@ -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
|
@ -1,11 +1,12 @@
|
||||
#include "stdafx.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
@ -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
|
||||
}
|
||||
|
89
lib_fiber/c/src/common/memory.c
Normal file
89
lib_fiber/c/src/common/memory.c
Normal file
@ -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;
|
||||
}
|
8
lib_fiber/c/src/common/memory.h
Normal file
8
lib_fiber/c/src/common/memory.h
Normal file
@ -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
|
@ -1,19 +1,9 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
@ -1,10 +1,20 @@
|
||||
#include "stdafx.h"
|
||||
#include <fcntl.h>
|
||||
|
||||
#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
|
||||
|
@ -1,14 +1,15 @@
|
||||
#include "stdafx.h"
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
/* 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 <stdio.h>
|
||||
|
||||
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
|
||||
|
305
lib_fiber/c/src/common/pthread.c
Normal file
305
lib_fiber/c/src/common/pthread.c
Normal file
@ -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 接口定义
|
||||
* 有些怪异,需要做硬性指定参数类型,参见 <Windows 高级编程指南>
|
||||
* 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 */
|
50
lib_fiber/c/src/common/pthread.h
Normal file
50
lib_fiber/c/src/common/pthread.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef PTHREAD_INCLUDE_H
|
||||
#define PTHREAD_INCLUDE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <time.h>
|
||||
|
||||
#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
|
@ -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
|
||||
|
@ -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__ */
|
||||
|
@ -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 <stdlib.h> /* malloc(3) realloc(3) free(3) rand(3) random(3) arc4random(3) */
|
||||
#include <stdio.h> /* FILE fopen(3) fclose(3) getc(3) rewind(3) */
|
||||
#include <string.h> /* memcpy(3) strlen(3) memmove(3) memchr(3) memcmp(3) strchr(3) strsep(3) strcspn(3) */
|
||||
#ifdef SYS_UNIX
|
||||
#include <strings.h> /* strcasecmp(3) strncasecmp(3) */
|
||||
#endif
|
||||
#include <ctype.h> /* isspace(3) isdigit(3) */
|
||||
#include <time.h> /* time_t time(2) difftime(3) */
|
||||
#include <signal.h> /* 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
|
||||
|
@ -26,6 +26,10 @@
|
||||
#ifndef DNS_H
|
||||
#define DNS_H
|
||||
|
||||
#include "define.h"
|
||||
|
||||
#ifdef SYS_UNIX
|
||||
|
||||
#include <stddef.h> /* size_t offsetof() */
|
||||
#include <stdio.h> /* FILE */
|
||||
|
||||
@ -48,6 +52,9 @@
|
||||
#include <netdb.h> /* 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
|
||||
|
@ -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
|
||||
|
@ -1,6 +1,9 @@
|
||||
#ifndef EVENT_INCLUDE_H
|
||||
#define EVENT_INCLUDE_H
|
||||
|
||||
#include "define.h"
|
||||
#include "common/gettimeofday.h"
|
||||
|
||||
#ifdef HAS_EPOLL
|
||||
#include <sys/epoll.h>
|
||||
#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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
#ifndef FIBER_INCLUDE_H
|
||||
#define FIBER_INCLUDE_H
|
||||
|
||||
#include <ucontext.h>
|
||||
#include <setjmp.h>
|
||||
#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 */
|
||||
|
254
lib_fiber/c/src/fiber/fiber_unix.c
Normal file
254
lib_fiber/c/src/fiber/fiber_unix.c
Normal file
@ -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
|
1
lib_fiber/c/src/fiber/fiber_win.c
Normal file
1
lib_fiber/c/src/fiber/fiber_win.c
Normal file
@ -0,0 +1 @@
|
||||
#include "stdafx.h"
|
@ -1,6 +1,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "common.h"
|
||||
|
||||
#ifdef SYS_UNIX
|
||||
|
||||
#ifdef LINUX
|
||||
# include <linux/version.h>
|
||||
# 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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include <netdb.h>
|
||||
#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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
#if defined(SYS_UNIX)
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/select.h>
|
||||
#include <poll.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <signal.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define STRDUP strdup
|
||||
#define GETPID getpid
|
||||
|
||||
#elif defined(SYS_WIN)
|
||||
# if(_MSC_VER >= 1300)
|
||||
# include <winsock2.h>
|
||||
# include <mswsock.h>
|
||||
# else
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# include <ws2tcpip.h> /* for getaddrinfo */
|
||||
# include <process.h>
|
||||
# include <stdint.h>
|
||||
|
||||
#define STRDUP _strdup
|
||||
#define GETPID _getpid
|
||||
#define ssize_t long int
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
# include <sys/sendfile.h>
|
||||
# include <sys/epoll.h>
|
||||
#elif defined(__FreeBSD__)
|
||||
# include <sys/uio.h>
|
||||
#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
|
||||
|
Loading…
Reference in New Issue
Block a user