/* doscan - Denial Of Service Capable Auditing of Networks -*- C++ -*- * Copyright (C) 2003 Florian Weimer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "event_queue.h" #include #include // handler event_queue::handler::handler(event_queue& q) : m_queue(q), timeout(0) { timeout_ptr = m_queue.timeouts.insert(this); } event_queue::handler::~handler() { if (timeout_ptr != m_queue.timeouts.end()) { m_queue.timeouts.erase(timeout_ptr); timeout_ptr = m_queue.timeouts.end(); } } void event_queue::handler::set_absolute_timeout(ticks_t ticks) { if (timeout_ptr != m_queue.timeouts.end()) { m_queue.timeouts.erase(timeout_ptr); timeout_ptr = m_queue.timeouts.end(); } timeout = ticks; timeout_ptr = m_queue.timeouts.insert(this); } // fd_handler event_queue::fd_handler::fd_handler(event_queue& q, int fd, watch_options w) : handler(q), real_fd(fd) { if (fd >= 0) { m_queue.add_fd(this, w); } } event_queue::fd_handler::~fd_handler() { unwatch(); } void event_queue::fd_handler::watch(int fd, watch_options w) { if (real_fd >= 0) { if (real_fd != fd) { m_queue.remove_fd(this); real_fd = fd; m_queue.add_fd(this, w); } else { m_queue.update_fd(this, w); } } else { // real_fd == -1 (or negative) real_fd = fd; m_queue.add_fd(this, w); } } void event_queue::fd_handler::unwatch() { if (real_fd >= 0) { m_queue.remove_fd(this); real_fd = -1; } } // event_queue event_queue::event_queue() { } event_queue::~event_queue() { // Delete all remaining handlers. while (! timeouts.empty()) { delete *timeouts.begin(); } } void event_queue::dispatch_end() { timeouts_t::iterator p = timeouts.begin(); for (;;) { if (p == timeouts.end() || (*p)->timeout > dispatch_start_ticks) { break; } if (!(*p)->on_timeout(dispatch_start_ticks)) { timeouts_t::iterator q = p; ++q; delete *p; p = q; } } } int event_queue::next_timeout() { if (timeouts.empty()) { return -1; } unsigned timeout = (*timeouts.begin())->timeout; if (timeout == TICKS_LAST) { return -1; } ticks_t ticks = ticks_get(); if (timeout <= ticks) { return 0; } else { return timeout - ticks; } } void event_queue::remove_fd(fd_handler*) { // Dummy implementation to aid during destruction. } void event_queue::dump() { if (timeouts.empty()) { std::cerr << "No handlers installed." << std::cerr; } else { std::cerr << "Timeout handlers:" << std::endl; for (timeouts_t::iterator p = timeouts.begin(); p != timeouts.end(); ++p) { std::cerr << " " << (*p)->timeout << ": " << typeid(**p).name() << std::endl; } } } // arch-tag: 57694226-cb95-4c27-a4b0-8ae1b3ae1d80