- void zmq::select_t::loop ()
-
{
-
while (!stopping) {
-
-
// Execute any due timers.
- /*
- 1. 执行到期的timer;
- 2. 如果没有到期的timer,则返回距最近timer的值,保证可以及时执行timer;
- 3. 如果没有任何的timer,那么返回0.
- 这里,我有两个问题:
- 1.如果timeout为0,那么后面的select就没有设置timeout的值。那么除非有事件发生,不然select就不 会返回了。
- 2.由于这里的timeout是基于已有的timer计算的。那么当计算完timeout后,插入了新的timer,这个tim
- er的到期时间要小于timeout的值。那么光看这些代码,似乎这个timer不能及时处理啊。
- */
-
int timeout = (int) execute_timers ();
-
-
// Intialise the pollsets.
- /*
- 需要将描述符复制,不然select会在fset中清除掉没有event的描述符。
- */
-
memcpy (&readfds, &source_set_in, sizeof source_set_in);
-
memcpy (&writefds, &source_set_out, sizeof source_set_out);
-
memcpy (&exceptfds, &source_set_err, sizeof source_set_err);
/*
后面的流程很简单,就是普通的select流程。
select后,检查描述符,是否可读,可写,或出错。如是的话,则调用相应的处理函数。
*/
-
// Wait for events.
-
struct timeval tv = {(long) (timeout / 1000),
-
(long) (timeout % 1000 * 1000)};
-
int rc = select (maxfd + 1, &readfds, &writefds, &exceptfds,
-
timeout ? &tv : NULL);
-
-
#ifdef ZMQ_HAVE_WINDOWS
-
wsa_assert (rc != SOCKET_ERROR);
-
#else
-
if (rc == -1 && errno == EINTR)
-
continue;
-
errno_assert (rc != -1);
-
#endif
-
-
// If there are no events (i.e. it's a timeout) there's no point
-
// in checking the pollset.
-
if (rc == 0)
-
continue;
-
-
for (fd_set_t::size_type i = 0; i < fds.size (); i ++) {
-
if (fds [i].fd == retired_fd)
-
continue;
-
if (FD_ISSET (fds [i].fd, &exceptfds))
-
fds [i].events->in_event ();
-
if (fds [i].fd == retired_fd)
-
continue;
-
if (FD_ISSET (fds [i].fd, &writefds))
-
fds [i].events->out_event ();
-
if (fds [i].fd == retired_fd)
-
continue;
-
if (FD_ISSET (fds [i].fd, &readfds))
-
fds [i].events->in_event ();
-
}
-
-
// Destroy retired event sources.
- /* 如注释所说,删除retired描述符*/
-
if (retired) {
-
fds.erase (std::remove_if (fds.begin (), fds.end (),
-
zmq::select_t::is_retired_fd), fds.end ());
-
retired = false;
-
}
-
}
-
}