本篇分析fdevent.c的源**。
這個源**檔案的工作時建立、監聽和處理讀寫事件。
static fdevent **fd_table = 0;
static int fd_table_max = 0;
fd_table儲存的是以fdevent->fd為索引儲存的fdevent指標,即
the_fdevent的值等於fd_table[the_fdevent->fd]。
static void fdevent_register(fdevent *fde) //即將fde新增到fd_table
if(fde->fd >= fd_table_max)
if(fd_table_max == 0)
while(fd_table_max <= fde->fd)
fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max);
if(fd_table == 0)
memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));
}fd_table[fde->fd] = fde; //將fde新增到fd_table
}static void fdevent_unregister(fdevent *fde) //這個函式即將fde從fd_table中刪除
if(fd_table[fde->fd] != fde)
fd_table[fde->fd] = 0;
if(!(fde->state & fde_dont_close))
}
fdevent是**處理事件的載體,它的定義如下:
struct fdevent
;
其中事件可以是:
#define fde_read 0x0001
#define fde_write 0x0002
#define fde_error 0x0004
#define fde_timeout 0x0008
#define fde_dont_close 0x0080
//掩碼
#define fde_eventmask 0x00ff
狀態可以是:
#define fde_active 0x0100
#define fde_pending 0x0200
#define fde_created 0x0400
//掩碼
#define fde_statemask 0xff00
注意,這些狀態是可以同時存在的。
當呼叫fdevent_create()後,fde_created標誌被設定,當呼叫fdevent_install()後, fde_created標誌被設定,但在fdevent_create()內部呼叫了fdevent_install(),所以呼叫fdevent_create()都被設定了。當有事件在呼叫select發生後,相應的事件state會設定為fde_pending,當事件處理完後這個標誌又被刪除。相應的**是:
void fdevent_loop()
}}
//變數定義和初始化
static fdevent list_pending = ;
//新增乙個元素
static void fdevent_plist_enqueue(fdevent *node)
//刪除乙個指定元素
static void fdevent_plist_remove(fdevent *node)
//從list中取出乙個元素
static fdevent *fdevent_plist_dequeue(void)
事件的處理是阻塞方式的,可以有兩種**實現方法。定義巨集craptastic表示使用epoll的方式,否則使用select方式。我這裡只講select的處理方式:
static fd_set read_fds; //讀事件集合
static fd_set write_fds; //寫事件集合
static fd_set error_fds; //發生錯誤事件集合
static int select_n = 0;
static void fdevent_init(void) //初始化
static void fdevent_connect(fdevent *fde) //新增
}static void fdevent_disconnect(fdevent *fde) //從所有事件集合刪除fde
select_n = n + 1;
}static void fdevent_update(fdevent *fde, unsigned events)//根據events設定事件集合
else
if(events & fde_write) else
if(events & fde_error) else
fde->state = (fde->state & fde_statemask) | events;
}/* looks at fd_table for bad fds and sets bit in fds.
** returns the number of bad fds.
*/static int fdevent_fd_check(fd_set *fds) //通過呼叫fcntl來判斷是否是乙個有效的fdevent
}return n;
}
android adb原始碼分析 2
本篇分析usb linux client.c中的usb init 它的 如下 void usb init else 呼叫usb adb init static void usb adb init else d usb init starting thread n if adb thread crea...
Android ADB 命令及原始碼編譯命令筆記
adb 常用命令 adb root 獲取root 許可權 adb remount 重新掛載 adb shell 進入terminal adb devices s serialnumber 檢視指定裝置狀態 adb devices 獲取裝置列表及裝置狀態 adb kill server adb sta...
spring原始碼分析 spring原始碼分析
1.spring 執行原理 spring 啟動時讀取應用程式提供的 bean 配置資訊,並在 spring 容器中生成乙份相應的 bean 配置登錄檔,然後根據這張登錄檔例項化 bean,裝配好 bean 之間的依賴關係,為上 層應用提供準備就緒的執行環境。二 spring 原始碼分析 1.1spr...