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 #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 static void *SimpleReadThread(void *userptr);
00135
00136 public:
00137 SocketRoutingQueue(int prealloc_buffer_count = 4,
00138 int default_read_timeout = USBWRAP_DEFAULT_TIMEOUT);
00139 ~SocketRoutingQueue();
00140
00141
00142
00143
00144 int GetWriteEp() const { return m_writeEp; }
00145 int GetReadEp() const { return m_readEp; }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 void SetUsbDevice(Usb::Device *dev, int writeEp, int readEp,
00158 SocketDataHandlerPtr callback = SocketDataHandlerPtr());
00159 void ClearUsbDevice();
00160 bool UsbDeviceReady();
00161 Usb::Device* GetUsbDevice() { return m_dev; }
00162 void ClearUsbError();
00163
00164
00165
00166
00167
00168 void AllocateBuffers(int count);
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 bool DefaultRead(Data &receive, int timeout = -1);
00179 DataHandle DefaultRead(int timeout = -1);
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 void RegisterInterest(SocketId socket, SocketDataHandlerPtr handler);
00192
00193
00194
00195
00196 void UnregisterInterest(SocketId socket);
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 bool SocketRead(SocketId socket, Data &receive, int timeout = -1);
00208 DataHandle SocketRead(SocketId socket, int timeout = -1);
00209
00210
00211 bool IsAvailable(SocketId socket) const;
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 void DoRead(int timeout = -1);
00222
00223
00224
00225
00226
00227
00228
00229 void SpinoffSimpleReadThread();
00230 };
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 class BXEXPORT DataHandle
00241 {
00242 private:
00243 SocketRoutingQueue &m_queue;
00244 mutable Data *m_data;
00245
00246 protected:
00247 void clear()
00248 {
00249 if( m_data ) {
00250 m_queue.ReturnBuffer(m_data);
00251 m_data = 0;
00252 }
00253 }
00254
00255 public:
00256 DataHandle(SocketRoutingQueue &q, Data *data)
00257 : m_queue(q)
00258 , m_data(data)
00259 {
00260 }
00261
00262 DataHandle(const DataHandle &other)
00263 : m_queue(other.m_queue)
00264 , m_data(other.m_data)
00265 {
00266
00267 other.m_data = 0;
00268 }
00269
00270 ~DataHandle()
00271 {
00272 clear();
00273 }
00274
00275 Data* get()
00276 {
00277 return m_data;
00278 }
00279
00280 Data* release()
00281 {
00282 Data *ret = m_data;
00283 m_data = 0;
00284 return ret;
00285 }
00286
00287 Data* operator->()
00288 {
00289 return m_data;
00290 }
00291
00292 const Data* operator->() const
00293 {
00294 return m_data;
00295 }
00296
00297 DataHandle& operator=(const DataHandle &other)
00298 {
00299 if( &m_queue != &other.m_queue )
00300 throw std::logic_error("Trying to copy DataHandles of different queues!");
00301
00302
00303 clear();
00304
00305
00306 m_data = other.m_data;
00307
00308
00309 other.m_data = 0;
00310
00311 return *this;
00312 }
00313
00314 };
00315
00316
00317 }
00318
00319 #endif
00320