kqueue 引发OS X系统重启

ken_scott 2016-06-27 04:50:27
使用到kqueue的代码


bool append_connection_to_reactor(Connection * connection)
{
struct kevent event[2];
struct timespec wait_timeout = { 0, 0 };
EV_SET(&event[0], connection->get_socket(), EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, connection);
EV_SET(&event[1], connection->get_socket(), EVFILT_WRITE, EV_ADD | EV_DISABLE, 0, 0, connection);
if (-1 == kevent(m_reactor, event, sizeof(event) / sizeof(event[0]), nullptr, 0, &wait_timeout))
{
return(false);
}
return(true);
}



bool delete_connection_from_reactor(Connection * connection)
{
struct kevent event[2];
struct timespec wait_timeout = { 0, 0 };
EV_SET(&event[0], connection->get_socket(), EVFILT_READ, EV_DELETE, 0, 0, connection);
EV_SET(&event[1], connection->get_socket(), EVFILT_WRITE, EV_DELETE, 0, 0, connection);
if (-1 == kevent(m_reactor, event, sizeof(event) / sizeof(event[0]), nullptr, 0, &wait_timeout))
{
return(false);
}
return(true);
}



bool modify_connection_of_reactor(Connection * connection, bool need_send, bool need_recv)
{
struct kevent event[2];
struct timespec wait_timeout = { 0, 0 };
EV_SET(&event[0], connection->get_socket(), EVFILT_READ, (need_recv ? EV_ENABLE : EV_DISABLE), 0, 0, connection);
EV_SET(&event[1], connection->get_socket(), EVFILT_WRITE, (need_send ? EV_ENABLE : EV_DISABLE), 0, 0, connection);
if (-1 == kevent(m_reactor, event, sizeof(event) / sizeof(event[0]), nullptr, 0, &wait_timeout))
{
return(false);
}
return(true);
}



void reactor_connection_process(int fkqueue, Connection * listener)
{
const size_t max_event_count = 256;
struct kevent connection_events[max_event_count];
struct timespec wait_timeout = { 1, 0 }; // seconds

while (running())
{
int event_count = kevent(fkqueue, nullptr, 0, connection_events, max_event_count, &wait_timeout);
if (-1 == event_count)
{
if (-1 == fkqueue)
{
break;
}

if (is_net_blocking_error())
{
continue;
}
else
{
printf("kevent failed: %d\n", net_error());
break;
}
}
else if (0 == event_count)
{
continue;
}

for (int index = 0; index < event_count; ++index)
{
struct kevent & connection_event = connection_events[index];
Connection * connection = reinterpret_cast<Connection *>(connection_event.udata);
if (listener == connection))
{
/* notify to accept */
Connection * new_connection = do_accept(listener);
append_connection_to_reactor(new_connection);
}
else
{
if (EVFILT_READ == connection_event.filter)
{
/* notify to recv */
do_recv(connection);
}
else if (EVFILT_WRITE == connection_event.filter)
{
/* notify to send */
do_send(connection);
if (send_buffer_is_empty()) /* nothing need to send */
{
bool need_send = false;
bool need_recv = true;
modify_connection_of_reactor(Connection * connection, need_send, need_recv);
}
}
}
}
}
}
}


我写了个滚雪球一样的测试程序(单个数据越来越大),当最大数据为30 * 20 bytes时,正常。
当最大数据设定到100 * 20 bytes时,机器就会立即自动异常重启(不论作为请求方还是响应方),看启动报告,是内核崩溃了

用了两台OS X 10.11测试,都是一样的,一设定到100 * 20 bytes 的数据量,就直接重启了
不知道,有没有谁碰到过类似的情况。。。

确定代码其他地方没问题,因为代码原本是用epoll来实现的,改成OS X版本,只是将epoll相关函数改成kevent相关函数
也就是上述代码是不同的,其他代码应该是没问题的

关于kqueue的用法,不是特别了解,按我现有的理解和epoll应该差不多,但是遇到这个问题,我又不敢肯定了
欢迎指出kqueue的用法不当的地方。
...全文
127 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2016-07-05
  • 打赏
  • 举报
回复
这分来的容易啊!
赵4老师 2016-06-27
  • 打赏
  • 举报
回复
OS X下有gdb吗?

64,644

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧