ircproxy The Ultimate Cyborg |
00001 // ircproxy -- An IRC bouncer. 00002 // 00003 //! @file Queue.cc 00004 //! @brief This file contains the implementation of class Queue. 00005 // 00006 // Copyright (C) 2007 by 00007 // 00008 // Carlo Wood, Run on IRC <carlo@alinoe.com> 00009 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt 00010 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61 00011 // 00012 // This file may be distributed under the terms of the Q Public License 00013 // version 1.0 as appearing in the file LICENSE.QPL included in the 00014 // packaging of this file. 00015 00016 #ifndef USE_PCH 00017 #include "sys.h" 00018 #include <sys/time.h> 00019 #endif 00020 00021 #include <cmath> 00022 #include "Queue.h" 00023 #include "Identity.h" 00024 #include "keys.h" 00025 00026 timeval operator-(timeval const& a, timeval const& b) 00027 { 00028 timeval result; 00029 timersub(&a, &b, &result); 00030 return result; 00031 } 00032 00033 void Queue::flush(void) 00034 { 00035 DoutEntering(dc::debug, "Queue::flush() with M_free_messages = " << M_free_messages); 00036 timeval elapsed_time = timer_event_server_ct::instance().get_now() - M_time; 00037 float elapsed_seconds = elapsed_time.tv_sec + elapsed_time.tv_usec * 0.000001; 00038 // Calculate the number of free messages that we can send in a burst now. 00039 M_free_messages += elapsed_seconds * M_messages_per_second; 00040 if (M_free_messages > M_max_free_messages) 00041 M_free_messages = M_max_free_messages; 00042 while (!M_priority_queue.empty()) 00043 { 00044 MessageOut const& msg(M_priority_queue.top()); 00045 // We are still not hidden! Don't send any message yet. 00046 // However, allow to send WHO/WHOIS/WHOWAS and other safe queries. 00047 if (M_server_connection.state() < real_nick_sent && !msg.is_safe()) 00048 M_free_messages = 0; 00049 if (M_free_messages < 1) // FIXME: A more complex algorithm is needed. 00050 break; 00051 // Send this message to the server. 00052 msg.write_to(M_server_connection.server_session()); 00053 M_free_messages -= 1; 00054 M_priority_queue.pop(); 00055 } 00056 // Store the time at which M_free_messages was last updated. 00057 M_time = timer_event_server_ct::instance().get_now(); 00058 // If there are still messages in the queue, set a timer to process them. 00059 if (!M_priority_queue.empty()) 00060 { 00061 // Use 1.001 instead of 1 to avoid calling the function a micro second too soon due to rounding errors. 00062 float needed_seconds = (1.001 - M_free_messages) / M_messages_per_second; 00063 timeval delay; 00064 delay.tv_sec = floorf(needed_seconds); 00065 delay.tv_usec = floorf((needed_seconds - delay.tv_sec) * 1000000); 00066 timerRequest(delay, *this, &Queue::send_next_message); 00067 } 00068 } 00069 00070 void Queue::send_next_message(timer_event_type_ct const& LIBCW_UNUSED_UNLESS_DEBUG(expired_at)) 00071 { 00072 DoutEntering(dc::debug, "Queue::send_next_message(" << expired_at.get_expire_time() << ")"); 00073 // For now, just call flush. 00074 flush(); 00075 } 00076
Copyright © 2005-2007 Carlo Wood. All rights reserved. |
---|