Home | History | Annotate | Download | only in channel_transport
      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