1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef WEBRTC_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_MANAGER_WINDOWS_H_ 12 #define WEBRTC_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_MANAGER_WINDOWS_H_ 13 14 #include <winsock2.h> 15 #include <list> 16 17 #include "webrtc/system_wrappers/interface/atomic32.h" 18 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 19 #include "webrtc/system_wrappers/interface/event_wrapper.h" 20 #include "webrtc/system_wrappers/interface/thread_wrapper.h" 21 #include "webrtc/test/channel_transport/udp_socket2_win.h" 22 #include "webrtc/test/channel_transport/udp_socket_manager_wrapper.h" 23 #include "webrtc/test/channel_transport/udp_transport.h" 24 25 #define MAX_IO_BUFF_SIZE 1600 26 27 namespace webrtc { 28 namespace test { 29 30 enum IO_OPERATION { 31 OP_READ, 32 OP_WRITE 33 }; 34 35 class UdpSocket2Windows; 36 37 // Struct used for all socket I/O operations. 38 struct PerIoContext { 39 WSAOVERLAPPED overlapped; 40 char buffer[MAX_IO_BUFF_SIZE]; 41 WSABUF wsabuf; 42 int nTotalBytes; 43 int nSentBytes; 44 int bytes; 45 IO_OPERATION ioOperation; 46 SocketAddress from; 47 int fromLen; 48 // Should be set to true if the I/O context was passed to the system by 49 // a thread not controlled by the socket implementation. 50 bool ioInitiatedByThreadWrapper; 51 // TODO (hellner): Not used. Delete it. 52 PerIoContext* pNextFree; 53 }; 54 55 struct IoContextPoolItem; 56 struct IoContextPoolItemPayload 57 { 58 PerIoContext ioContext; 59 IoContextPoolItem* base; 60 }; 61 62 struct IoContextPoolItem 63 { 64 // Atomic single linked list entry header. 65 SLIST_ENTRY itemEntry; 66 // Atomic single linked list payload 67 IoContextPoolItemPayload payload; 68 }; 69 70 class IoContextPool 71 { 72 public: 73 IoContextPool(); 74 virtual ~IoContextPool(); 75 virtual int32_t Init(uint32_t increaseSize = 128); 76 // Re-use an old unused IO context or create a new one. 77 virtual PerIoContext* PopIoContext(); 78 virtual int32_t PushIoContext(PerIoContext* pIoContext); 79 virtual inline int32_t GetSize(uint32_t* inUse = 0) 80 {return _size.Value();} 81 virtual int32_t Free(); 82 private: 83 // Sample code for use of msfts single linked atomic list can be found here: 84 // http://msdn.microsoft.com/en-us/library/ms686962(VS.85).aspx 85 86 // Atomic single linked list head. 87 PSLIST_HEADER _pListHead; 88 89 bool _init; 90 Atomic32 _size; 91 Atomic32 _inUse; 92 }; 93 94 class UdpSocket2WorkerWindows 95 { 96 public: 97 UdpSocket2WorkerWindows(HANDLE ioCompletionHandle); 98 virtual ~UdpSocket2WorkerWindows(); 99 100 virtual bool Start(); 101 virtual bool Stop(); 102 virtual int32_t Init(); 103 virtual void SetNotAlive(); 104 protected: 105 static bool Run(ThreadObj obj); 106 bool Process(); 107 private: 108 HANDLE _ioCompletionHandle; 109 ThreadWrapper*_pThread; 110 static int32_t _numOfWorkers; 111 int32_t _workerNumber; 112 volatile bool _stop; 113 bool _init; 114 }; 115 116 class UdpSocket2ManagerWindows : public UdpSocketManager 117 { 118 public: 119 UdpSocket2ManagerWindows(); 120 virtual ~UdpSocket2ManagerWindows(); 121 122 virtual bool Init(int32_t id, uint8_t& numOfWorkThreads); 123 virtual int32_t ChangeUniqueId(const int32_t id); 124 125 virtual bool Start(); 126 virtual bool Stop(); 127 128 virtual inline bool AddSocket(UdpSocketWrapper* s) 129 {if(s) return AddSocketPrv(reinterpret_cast<UdpSocket2Windows*>(s)); 130 return false;} 131 virtual bool RemoveSocket(UdpSocketWrapper* s) 132 {if(s) return RemoveSocketPrv(reinterpret_cast<UdpSocket2Windows*>(s)); 133 return false;} 134 135 PerIoContext* PopIoContext(void); 136 int32_t PushIoContext(PerIoContext* pIoContext); 137 138 private: 139 typedef std::list<UdpSocket2WorkerWindows*> WorkerList; 140 bool StopWorkerThreads(); 141 bool StartWorkerThreads(); 142 bool AddSocketPrv(UdpSocket2Windows* s); 143 bool RemoveSocketPrv(UdpSocket2Windows* s); 144 145 static uint32_t _numOfActiveManagers; 146 static bool _wsaInit; 147 148 int32_t _id; 149 CriticalSectionWrapper* _pCrit; 150 int32_t _managerNumber; 151 volatile bool _stopped; 152 bool _init; 153 int32_t _numActiveSockets; 154 WorkerList _workerThreadsList; 155 EventWrapper* _event; 156 157 HANDLE _ioCompletionHandle; 158 IoContextPool _ioContextPool; 159 }; 160 161 } // namespace test 162 } // namespace webrtc 163 164 #endif // WEBRTC_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_MANAGER_WINDOWS_H_ 165