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 #include "error.h"
00033 #include "usbwrap.h"
00034
00035 namespace Barry {
00036
00037 class DataHandle;
00038
00039 class BXEXPORT SocketRoutingQueue
00040 {
00041 friend class DataHandle;
00042
00043 public:
00044
00045
00046 class BXEXPORT SocketDataHandler
00047 {
00048 public:
00049
00050
00051
00052
00053
00054 virtual void DataReceived(Data& data) = 0;
00055
00056
00057
00058
00059
00060
00061 virtual void Error(Barry::Error &error);
00062
00063 virtual ~SocketDataHandler();
00064 };
00065
00066 typedef std::tr1::shared_ptr<SocketDataHandler> SocketDataHandlerPtr;
00067
00068
00069 template<typename T> class SimpleSocketDataHandler : public SocketDataHandler
00070 {
00071 void (*m_callback)(T&, Data*);
00072 T& m_context;
00073 public:
00074 SimpleSocketDataHandler<T>(T& context, void (*callback)(T& context, Data* data))
00075 : m_callback(callback)
00076 , m_context(context)
00077 {}
00078 virtual void DataReceived(Data& data)
00079 {
00080 m_callback(m_context, &data);
00081 }
00082 };
00083
00084 struct QueueEntry
00085 {
00086 SocketDataHandlerPtr m_handler;
00087 DataQueue m_queue;
00088
00089 QueueEntry(SocketDataHandlerPtr h)
00090 : m_handler(h)
00091 {}
00092 };
00093 typedef std::tr1::shared_ptr<QueueEntry> QueueEntryPtr;
00094 typedef uint16_t SocketId;
00095 typedef std::map<SocketId, QueueEntryPtr> SocketQueueMap;
00096
00097 private:
00098 Usb::Device * volatile m_dev;
00099 volatile int m_writeEp, m_readEp;
00100
00101 volatile bool m_interest;
00102
00103
00104 mutable pthread_mutex_t m_mutex;
00105
00106
00107
00108 pthread_mutex_t m_readwaitMutex;
00109 pthread_cond_t m_readwaitCond;
00110 bool m_seen_usb_error;
00111 SocketDataHandlerPtr m_usb_error_dev_callback;
00112
00113 DataQueue m_free;
00114 DataQueue m_default;
00115 SocketQueueMap m_socketQueues;
00116
00117 int m_timeout;
00118
00119
00120 pthread_t m_usb_read_thread;
00121 volatile bool m_continue_reading;
00122
00123
00124
00125
00126 protected:
00127
00128
00129
00130 void ReturnBuffer(Data *buf);
00131
00132
00133
00134
00135 bool QueuePacket(SocketId socket, DataHandle &buf);
00136 bool QueuePacket(DataQueue &queue, DataHandle &buf);
00137 bool RouteOrQueuePacket(SocketId socket, DataHandle &buf);
00138
00139
00140
00141 static void *SimpleReadThread(void *userptr);
00142
00143 void DumpSocketQueue(SocketId socket, const DataQueue &dq);
00144
00145 public:
00146 SocketRoutingQueue(int prealloc_buffer_count = 4,
00147 int default_read_timeout = USBWRAP_DEFAULT_TIMEOUT);
00148 ~SocketRoutingQueue();
00149
00150
00151
00152
00153 int GetWriteEp() const { return m_writeEp; }
00154 int GetReadEp() const { return m_readEp; }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 void SetUsbDevice(Usb::Device *dev, int writeEp, int readEp,
00167 SocketDataHandlerPtr callback = SocketDataHandlerPtr());
00168 void ClearUsbDevice();
00169 bool UsbDeviceReady();
00170 Usb::Device* GetUsbDevice() { return m_dev; }
00171 void ClearUsbError();
00172
00173
00174
00175
00176
00177 void AllocateBuffers(int count);
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 bool DefaultRead(Data &receive, int timeout = -1);
00188 DataHandle DefaultRead(int timeout = -1);
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 void RegisterInterest(SocketId socket, SocketDataHandlerPtr handler);
00201
00202
00203
00204
00205 void UnregisterInterest(SocketId socket);
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 bool SocketRead(SocketId socket, Data &receive, int timeout = -1);
00217 DataHandle SocketRead(SocketId socket, int timeout = -1);
00218
00219
00220 bool IsAvailable(SocketId socket) const;
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 void DoRead(int timeout = -1);
00231
00232
00233
00234
00235
00236
00237
00238 void SpinoffSimpleReadThread();
00239 };
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 class BXEXPORT DataHandle
00250 {
00251 private:
00252 SocketRoutingQueue &m_queue;
00253 mutable Data *m_data;
00254
00255 protected:
00256 void clear()
00257 {
00258 if( m_data ) {
00259 m_queue.ReturnBuffer(m_data);
00260 m_data = 0;
00261 }
00262 }
00263
00264 public:
00265 DataHandle(SocketRoutingQueue &q, Data *data)
00266 : m_queue(q)
00267 , m_data(data)
00268 {
00269 }
00270
00271 DataHandle(const DataHandle &other)
00272 : m_queue(other.m_queue)
00273 , m_data(other.m_data)
00274 {
00275
00276 other.m_data = 0;
00277 }
00278
00279 ~DataHandle()
00280 {
00281 clear();
00282 }
00283
00284 Data* get()
00285 {
00286 return m_data;
00287 }
00288
00289 Data* release()
00290 {
00291 Data *ret = m_data;
00292 m_data = 0;
00293 return ret;
00294 }
00295
00296
00297 void reset(Data *next = 0)
00298 {
00299 clear();
00300 m_data = next;
00301 }
00302
00303 Data* operator->()
00304 {
00305 return m_data;
00306 }
00307
00308 const Data* operator->() const
00309 {
00310 return m_data;
00311 }
00312
00313 DataHandle& operator=(const DataHandle &other)
00314 {
00315 if( &m_queue != &other.m_queue )
00316 throw std::logic_error("Trying to copy DataHandles of different queues!");
00317
00318
00319 clear();
00320
00321
00322 m_data = other.m_data;
00323
00324
00325 other.m_data = 0;
00326
00327 return *this;
00328 }
00329
00330 };
00331
00332
00333 }
00334
00335 #endif
00336