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 int GetWriteEp() const { return m_writeEp; }
00103 int GetReadEp() const { return m_readEp; }
00104
00105
00106
00107
00108
00109 void SetUsbDevice(Usb::Device *dev, int writeEp, int readEp);
00110 void ClearUsbDevice();
00111 bool UsbDeviceReady();
00112 Usb::Device* GetUsbDevice() { return m_dev; }
00113
00114
00115
00116
00117 void AllocateBuffers(int count);
00118
00119
00120
00121
00122
00123
00124 bool DefaultRead(Data &receive, int timeout = -1);
00125 DataHandle DefaultRead(int timeout = -1);
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 void RegisterInterest(SocketId socket, SocketDataHandler handler = 0, void *context = 0);
00138
00139
00140
00141
00142 void UnregisterInterest(SocketId socket);
00143
00144
00145
00146
00147
00148
00149
00150 bool SocketRead(SocketId socket, Data &receive, int timeout = -1);
00151 DataHandle SocketRead(SocketId socket, int timeout = -1);
00152
00153
00154 bool IsAvailable(SocketId socket) const;
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 bool DoRead(std::string &msg, int timeout = -1);
00168
00169
00170
00171
00172
00173
00174
00175 void SpinoffSimpleReadThread();
00176 };
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 class BXEXPORT DataHandle
00187 {
00188 private:
00189 SocketRoutingQueue &m_queue;
00190 mutable Data *m_data;
00191
00192 protected:
00193 void clear()
00194 {
00195 if( m_data ) {
00196 m_queue.ReturnBuffer(m_data);
00197 m_data = 0;
00198 }
00199 }
00200
00201 public:
00202 DataHandle(SocketRoutingQueue &q, Data *data)
00203 : m_queue(q)
00204 , m_data(data)
00205 {
00206 }
00207
00208 DataHandle(const DataHandle &other)
00209 : m_queue(other.m_queue)
00210 , m_data(other.m_data)
00211 {
00212
00213 other.m_data = 0;
00214 }
00215
00216 ~DataHandle()
00217 {
00218 clear();
00219 }
00220
00221 Data* get()
00222 {
00223 return m_data;
00224 }
00225
00226 Data* release()
00227 {
00228 Data *ret = m_data;
00229 m_data = 0;
00230 return ret;
00231 }
00232
00233 Data* operator->()
00234 {
00235 return m_data;
00236 }
00237
00238 const Data* operator->() const
00239 {
00240 return m_data;
00241 }
00242
00243 DataHandle& operator=(const DataHandle &other)
00244 {
00245 if( &m_queue != &other.m_queue )
00246 throw std::logic_error("Trying to copy DataHandles of different queues!");
00247
00248
00249 clear();
00250
00251
00252 m_data = other.m_data;
00253
00254
00255 other.m_data = 0;
00256
00257 return *this;
00258 }
00259
00260 };
00261
00262
00263 }
00264
00265 #endif
00266