- 論壇徽章:
- 0
|
版本5.02
在一個(gè)非阻塞的socket上讀取8字節(jié),并不能保證每次都讀取到8字節(jié),若由于系統(tǒng)繁忙沒有讀取到8字節(jié),將導(dǎo)致異常。
1)線程間的通知采用pipe來產(chǎn)生兩個(gè)socket (storage_service.c 1639)
if (pipe(pThreadData->thread_data.pipe_fds) != 0)
{
result = errno != 0 ? errno : EPERM;
logError("file: "__FILE__", line: %d, " \
"call pipe fail, " \
"errno: %d, error info: %s", \
__LINE__, result, STRERROR(result));
break;
}
2)將讀socket設(shè)置成非阻塞,寫socket還是阻塞的 (storage_service.c 1650)
if ((result=fd_add_flags(pThreadData->thread_data.pipe_fds[0], \
O_NONBLOCK | O_NOATIME)) != 0)
{
break;
}
3)創(chuàng)建一個(gè)任務(wù)并將該任務(wù)的地址寫入到 pipe_fds[1] (storage_service.c 174
task_addr = (long)pTask;
write(pThreadData->thread_data.pipe_fds[1], &task_addr, sizeof(task_addr)) != sizeof(task_addr)
4) pipe_fds[0]讀事件處理函數(shù),他這里直接使用一個(gè)read讀取8字節(jié),因?yàn)槭欠亲枞⒉荒鼙WC都會(huì)讀到8個(gè)字節(jié)吧
如果沒有讀到8個(gè)字節(jié)那么這個(gè)task_addr就是異常的吧 (storage_nio.c 134)
while (1)
{
if ((bytes=read(sock, &task_addr, sizeof(task_addr))) < 0)
{
if (!(errno == EAGAIN || errno == EWOULDBLOCK))
{
logError("file: "__FILE__", line: %d, " \
"call read failed, " \
"errno: %d, error info: %s", \
__LINE__, errno, STRERROR(errno));
}
break;
}
else if (bytes == 0)
{
logError("file: "__FILE__", line: %d, " \
"call read failed, end of file", __LINE__);
break;
}
pTask = (struct fast_task_info *)task_addr;
|
|