void middleman_event_handler::update() { BOOST_ACTOR_LOG_TRACE(""); auto mless = [](const fd_meta_info& lhs, native_socket_type rhs) { return lhs.fd < rhs; }; for (auto& elem_pair : m_alterations) { auto& elem = elem_pair.first; auto old = event::none; auto last = m_meta.end(); auto iter = std::lower_bound(m_meta.begin(), last, elem.fd, mless); if (iter != last) old = iter->mask; auto mask = next_bitmask(old, elem.mask, elem_pair.second); auto ptr = elem.ptr; BOOST_ACTOR_LOG_DEBUG("new bitmask for " << elem.ptr << ": " << eb2str(mask)); if (iter == last || iter->fd != elem.fd) { if (mask != event::none) { // element has been removed from m_meta by an // previous alteration but is not put back in m_meta.insert(iter, elem); handle_event(fd_meta_event::add, elem.fd, event::none, mask, ptr); } } else if (iter->fd == elem.fd) { BOOST_ACTOR_REQUIRE(iter->ptr == elem.ptr); if (mask == event::none) { // note: we cannot decide whether it's safe to dispose `ptr`, // because we didn't parse all alterations yet m_dispose_list.emplace_back(ptr); m_meta.erase(iter); handle_event(fd_meta_event::erase, elem.fd, old, mask, ptr); } else { iter->mask = mask; handle_event(fd_meta_event::mod, elem.fd, old, mask, ptr); } } } m_alterations.clear(); // m_meta won't be touched inside loop auto first = m_meta.begin(); auto last = m_meta.end(); // checks whether an element can be safely deleted, // i.e., was not put back into m_meta by some alteration auto is_alive = [&](native_socket_type fd) -> bool { auto iter = std::lower_bound(first, last, fd, mless); return iter != last && iter->fd == fd; }; // dispose everything that wasn't put back into m_meta again for (auto elem : m_dispose_list) { auto rd = elem->read_handle(); auto wr = elem->write_handle(); if ( (rd == wr && !is_alive(rd)) || (rd != wr && !is_alive(rd) && !is_alive(wr))) { elem->dispose(); } } m_dispose_list.clear(); }
void update() { CPPA_LOG_TRACE(""); for (auto& elem_pair : m_alterations) { auto& elem = elem_pair.first; auto old = event::none; auto last = end(m_meta); auto iter = lower_bound(begin(m_meta), last, elem.fd, m_less); if (iter != last) old = iter->mask; auto mask = next_bitmask(old, elem.mask, elem_pair.second); auto ptr = elem.ptr.get(); CPPA_LOG_DEBUG("new bitmask for " << elem.ptr.get() << ": " << eb2str(mask)); if (iter == last || iter->fd != elem.fd) { CPPA_LOG_INFO_IF(mask == event::none, "cannot erase " << ptr << " (not found in m_meta)"); if (mask != event::none) { m_meta.insert(iter, elem); d()->handle_event(fd_meta_event::add, elem.fd, event::none, mask, ptr); } } else if (iter->fd == elem.fd) { CPPA_REQUIRE(iter->ptr == elem.ptr); if (mask == event::none) { m_meta.erase(iter); d()->handle_event(fd_meta_event::erase, elem.fd, old, mask, ptr); } else { iter->mask = mask; d()->handle_event(fd_meta_event::mod, elem.fd, old, mask, ptr); } } } m_alterations.clear(); }