co_routine.h
#ifndef __CO_ROUTINE_H__
#define __CO_ROUTINE_H__
#include <stdint.h>
#include <sys/poll.h>
#include <pthread.h>
//1.struct
struct stCoRoutine_t;//協程的結構體 用來存儲協程相關的信息 具體含義會在 co_routine.cpp 給出
struct stShareStack_t;//共享棧結構體 存儲共享棧相關信息 具體信息會在 co_routine_inner.h 給出
struct stCoRoutineAttr_t // 用來初始化共享棧時使用的結構體。
{
int stack_size; //棧的大小
stShareStack_t* share_stack; //分配的共享棧
stCoRoutineAttr_t()//默認構造函數
{
stack_size = 128 * 1024;
share_stack = NULL;
}
}__attribute__ ((packed));
/*
__attribute__ ((packed)) 的作用就是告訴編譯器取消結構在編譯過程中的優化對齊,按照實際佔用字節
數進行對齊,是GCC特有的語法。(http://blog.chinaunix.net/uid-25768133-id-3485479.html)
*/
struct stCoEpoll_t;//控制定時的結構體 用來管理時間請求
typedef int (*pfn_co_eventloop_t)(void *); //定義一個函數指針 參數類型爲一個 void * 返回值類型爲int
typedef void *(*pfn_co_routine_t)( void * );// 基本同上
//2.co_routine
int co_create( stCoRoutine_t **co,const stCoRoutineAttr_t *attr,void *(*routine)(void*),void *arg );
/*
線程create函數,用來創建創建一個線程,注意和線程不同,create只會創建協程,不會去運行協程。
stCoRoutine_t **co 當前協程 調用函數之後會對co進行賦值。
const stCoRoutineAttr_t *attr 使用哪個棧進行分配,以及分配的大小。傳參不爲NULL的話,cIsShareStack會賦值true。
void *(*routine)(void*) 協程調用的函數
void *arg 協程調用的函數 使用的參數 類似於線程的用法。
*/
void co_resume( stCoRoutine_t *co );//運行當前的協程,協程加入調用棧中,然後調用co_swap,交換,使進程/線程 運行當前協程
void co_yield( stCoRoutine_t *co );//作用同下
void co_yield_ct();
/*ct = current thread
讓出協程,調用上一個入棧的協程。除非加入事件到時間輪中,不然當前協程不會再次運行。
底層調用co_yield_env。 libco協程是按照調用棧的順序運行的,
因此傳參的co其實是沒用的x co_yield co_yield_ct co_yield_env 作用一樣。
*/
void co_release( stCoRoutine_t *co );//調用co_free 釋放內存
stCoRoutine_t *co_self(); //返回當前協程 其實就是調用棧棧頂的協程。
int co_poll( stCoEpoll_t *ctx,struct pollfd fds[], nfds_t nfds, int timeout_ms );
/*
調用了co_poll_inner
主要的作用爲將需要監聽的事件加入時間輪中,並讓出協程。以及在事件觸發後恢複函數執行,清理添加的事件。
stCoEpoll_t *ctx 當前協成,會使用協成中的參數
struct pollfd fds[] 時間數組
nfds_t nfds 數組大小
int timeout_ms 定時時間
*/
void co_eventloop( stCoEpoll_t *ctx,pfn_co_eventloop_t pfn,void *arg );
/*
主要功能爲對時間進行輪詢,不斷調用epoll,超時事件則運行對應的協程。
stCoEpoll_t *ctx 存儲定時事件
pfn_co_eventloop_t pfn,void *arg
if( pfn )
{
if( -1 == pfn( arg ) )
{
break;
}
}
函數中使用這個兩個參數用來檢測是否推出函數,通常爲NULL,NULL。
*/
//3.specific
int co_setspecific( pthread_key_t key, const void *value );//設置key對應的value。
void * co_getspecific( pthread_key_t key );//獲取key對應的value
//4.event
stCoEpoll_t * co_get_epoll_ct(); //ct = current thread 獲取環境中存儲定時事件的結構體
//5.hook syscall ( poll/read/write/recv/send/recvfrom/sendto )
void co_enable_hook_sys(); //修改當前協程的cEnableSysHook屬性爲true
void co_disable_hook_sys(); //修改當前協程的cEnableSysHook屬性爲false
bool co_is_enable_sys_hook(); //查詢當前協程的cEnableSysHook屬性
//6.sync
struct stCoCond_t;//信號量結構體 存儲timewait添加的事件
stCoCond_t *co_cond_alloc();//分配內存
int co_cond_free( stCoCond_t * cc );//釋放內存
int co_cond_signal( stCoCond_t * );//添加最近一次入棧的timedwait事件到活動事件中,co_eventloop輪詢時會運行協程。
int co_cond_broadcast( stCoCond_t * );//廣播 添加所有timewait事件。
int co_cond_timedwait( stCoCond_t *,int timeout_ms );//定時時間添加到epoll中,非定時事件添加到棧中。事件觸發後會刪除事件。
//7.share stack
stShareStack_t* co_alloc_sharestack(int iCount, int iStackSize);//分配共享棧內存
//8.init envlist for hook get/set env
void co_set_env_list( const char *name[],size_t cnt);//初始化環境變量
void co_log_err( const char *fmt,... );//錯誤日誌
#endif
個人理解:co_routine.h文件的作用主要是聲明一些結構體和函數,用於使用庫時調用。後續會介紹協成如何管理,調用棧+時間輪。以及libco的hook,co_swap的實現,方便開發者的閉包實現,個人分析,如有不足,歡迎指出。