router.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __BARRY_ROUTER_H__
00023 #define __BARRY_ROUTER_H__
00024
00025 #include "dll.h"
00026 #include <stdint.h>
00027 #include <map>
00028 #include <tr1/memory>
00029 #include <stdexcept>
00030 #include <pthread.h>
00031 #include "dataqueue.h"
00032
00033 namespace Usb { class Device; }
00034
00035 namespace Barry {
00036
00037 class DataHandle;
00038
00039 class BXEXPORT SocketRoutingQueue
00040 {
00041 friend class DataHandle;
00042
00043 public:
00044 typedef void (*SocketDataHandler)(void *ctx, Data*);
00045 struct QueueEntry
00046 {
00047 SocketDataHandler m_handler;
00048 void *m_context;
00049 DataQueue m_queue;
00050
00051 QueueEntry(SocketDataHandler h, void *c)
00052 : m_handler(h)
00053 , m_context(c)
00054 {}
00055 };
00056 typedef std::tr1::shared_ptr<QueueEntry> QueueEntryPtr;
00057 typedef uint16_t SocketId;
00058 typedef std::map<SocketId, QueueEntryPtr> SocketQueueMap;
00059
00060 private:
00061 Usb::Device * volatile m_dev;
00062 volatile int m_writeEp, m_readEp;
00063
00064 volatile bool m_interest;
00065
00066
00067 mutable pthread_mutex_t m_mutex;
00068
00069
00070
00071 pthread_mutex_t m_readwaitMutex;
00072 pthread_cond_t m_readwaitCond;
00073
00074 DataQueue m_free;
00075 DataQueue m_default;
00076 SocketQueueMap m_socketQueues;
00077
00078
00079 pthread_t m_usb_read_thread;
00080 volatile bool m_continue_reading;
00081
00082
00083
00084
00085 protected:
00086
00087
00088
00089 void ReturnBuffer(Data *buf);
00090
00091
00092
00093 static void *SimpleReadThread(void *userptr);
00094
00095 public:
00096 SocketRoutingQueue(int prealloc_buffer_count = 4);
00097 ~SocketRoutingQueue();
00098
00099
00100
00101
00102 void SetUsbDevice(Usb::Device *dev, int writeEp, int readEp);
00103 void ClearUsbDevice();
00104 bool UsbDeviceReady();
00105 Usb::Device* GetUsbDevice() { return m_dev; }
00106
00107
00108
00109
00110 void AllocateBuffers(int count);
00111
00112
00113
00114
00115
00116
00117 bool DefaultRead(Data &receive, int timeout = -1);
00118 DataHandle DefaultRead(int timeout = -1);
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 void RegisterInterest(SocketId socket, SocketDataHandler handler = 0, void *context = 0);
00131
00132
00133
00134
00135 void UnregisterInterest(SocketId socket);
00136
00137
00138
00139
00140
00141
00142
00143 bool SocketRead(SocketId socket, Data &receive, int timeout = -1);
00144 DataHandle SocketRead(SocketId socket, int timeout = -1);
00145
00146
00147 bool IsAvailable(SocketId socket) const;
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 bool DoRead(std::string &msg, int timeout = -1);
00161
00162
00163
00164
00165
00166
00167
00168 void SpinoffSimpleReadThread();
00169 };
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 class BXEXPORT DataHandle
00180 {
00181 private:
00182 SocketRoutingQueue &m_queue;
00183 mutable Data *m_data;
00184
00185 protected:
00186 void clear()
00187 {
00188 if( m_data ) {
00189 m_queue.ReturnBuffer(m_data);
00190 m_data = 0;
00191 }
00192 }
00193
00194 public:
00195 DataHandle(SocketRoutingQueue &q, Data *data)
00196 : m_queue(q)
00197 , m_data(data)
00198 {
00199 }
00200
00201 DataHandle(const DataHandle &other)
00202 : m_queue(other.m_queue)
00203 , m_data(other.m_data)
00204 {
00205
00206 other.m_data = 0;
00207 }
00208
00209 ~DataHandle()
00210 {
00211 clear();
00212 }
00213
00214 Data* get()
00215 {
00216 return m_data;
00217 }
00218
00219 Data* release()
00220 {
00221 Data *ret = m_data;
00222 m_data = 0;
00223 return ret;
00224 }
00225
00226 Data* operator->()
00227 {
00228 return m_data;
00229 }
00230
00231 const Data* operator->() const
00232 {
00233 return m_data;
00234 }
00235
00236 DataHandle& operator=(const DataHandle &other)
00237 {
00238 if( &m_queue != &other.m_queue )
00239 throw std::logic_error("Trying to copy DataHandles of different queues!");
00240
00241
00242 clear();
00243
00244
00245 m_data = other.m_data;
00246
00247
00248 other.m_data = 0;
00249
00250 return *this;
00251 }
00252
00253 };
00254
00255
00256 }
00257
00258 #endif
00259