00001 /* 00002 * netrq.h 00003 * 00004 * Copyright (c) 2009 Thomas A. Vaughan 00005 * All rights reserved. 00006 * 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * * Neither the name of the <organization> nor the 00016 * names of its contributors may be used to endorse or promote products 00017 * derived from this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY 00020 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY 00023 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00026 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * 00031 * Simple library for handling network request queues. 00032 */ 00033 00034 #ifndef WAVEPACKET_NETRQ_H__ 00035 #define WAVEPACKET_NETRQ_H__ 00036 00037 00038 // includes -------------------------------------------------------------------- 00039 #include "xdrbuf/xdrbuf.h" // depends on XDR buffer library 00040 00041 #include "threadsafe/smart_ptr.h" 00042 00043 00044 namespace netrq { 00045 00046 // doxygen block 00047 00048 /// \ingroup networking 00049 /*@{*/ 00050 00051 //////////////////////////////////////////////////////////////////////////////// 00052 /// 00053 /// \defgroup netrq Network Request Queue 00054 /// 00055 /// \n 00056 /// A network request queue. Clients can add requests with an ID and priority. 00057 /// Later, clients can pull the most immediate requests from the queue, 00058 /// and that request will be backed off. Finally, clients can remove requests 00059 /// altogether. 00060 /// 00061 /// The client must construct IDs on its own. 00062 /// 00063 /// This library makes use of a "clock". In the context of a network request 00064 /// queue, this is just a serial counter, not a timer. There is a clock tick 00065 /// per datagram sent out. This library relies on the client maintaining its 00066 /// own clock, and respects whatever the client provides as far as current and 00067 /// requested clock values. 00068 /// 00069 //////////////////////////////////////////////////////////////////////////////// 00070 /*@{*/ 00071 00072 00073 /// Base class from which clients can inherit. This is how you can store 00074 /// per-request context (state) in the queue, and have it automatically cleaned 00075 /// up. 00076 class Request { 00077 public: 00078 // virtual destructor -------------------------------------------------- 00079 virtual ~Request(void) throw(); 00080 00081 // netrq::Request class interface methods ------------------------------ 00082 virtual const char * getId(void) const throw() = 0; 00083 virtual int getMaxBytes(void) const throw() = 0; 00084 virtual void write(IO xdrbuf::Output * output) = 0; 00085 00086 /// if non-zero, this request is asking to be resent after the 00087 /// specified clock interval 00088 virtual int getRetryInterval(void) const throw() { return 0; } 00089 }; 00090 00091 00092 00093 /// basic network request queue. 00094 /// 00095 /// This class is \b threadsafe . In some situations (single-threaded client) 00096 /// this may be unnecessary overhead, but given the common use case (reacting to 00097 /// or sending UDP diagrams) this isn't expected to be much overhead. 00098 class Queue { 00099 public: 00100 // public enums -------------------------------------------------------- 00101 enum eInsertResult { 00102 eQueue_Success = 0, 00103 eQueue_Failed_CurrentEntryHasLaterClock = 1, 00104 eQueue_Failed_CurrentEntryHasEarlierClock = 2, 00105 00106 // keep this last 00107 eQueue_Failed_Unknown = 3 00108 }; 00109 00110 // virtual destructor -------------------------------------------------- 00111 virtual ~Queue(void) throw(); 00112 00113 // netrq::Queue class interface methods -------------------------------- 00114 00115 /// Returns count of requests in queue. Approximate only, since other 00116 /// threads may update the queue by the time the caller gets the count. 00117 virtual int size(void) = 0; 00118 00119 /// If the addRequest fails due to a collision, the return value will 00120 /// tell the client whether the existing request has an earlier or later 00121 /// clock than what was just requested. 00122 virtual eInsertResult addRequest( 00123 IN dword_t sendClock, ///< send at this clock 00124 IN smart_ptr<Request>& request) = 0; 00125 00126 /// returns the next request that should be sent. The clock value is 00127 /// the current packet count, not the time. So for instance, if you are 00128 /// using this queue to manage UDP data, increment the clock everytime 00129 /// you send a UDP packet. 00130 virtual bool getNextRequest(IN dword_t clock, ///< current clock 00131 OUT smart_ptr<Request>& request) = 0; 00132 00133 /// does the queue already contain a request with this id? 00134 virtual bool containsRequest(IN const char * id) = 0; 00135 00136 virtual bool removeRequest(IN const char * id) = 0; 00137 00138 // static factory methods ---------------------------------------------- 00139 static smart_ptr<Queue> create(void); 00140 }; 00141 00142 00143 00144 // 00145 // helper methods 00146 // 00147 00148 /// Given an output buffer, write as many pending requests as possible. All 00149 /// sent messages are removed from the queue. Returns the number of messages 00150 /// sent. See the netrq library comments regarding the clock values. 00151 int sendMessagesFromQueue(IO xdrbuf::Output * output, 00152 IN dword_t clock, ///< current clock 00153 IO Queue * queue); 00154 00155 00156 }; // netrq namespace 00157 00158 /*@}*/ // end of documentation block 00159 00160 #endif // WAVEPACKET_NETRQ_H__ 00161