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/include/atomic32.h"
     18 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
     19 #include "webrtc/system_wrappers/include/event_wrapper.h"
     20 #include "webrtc/base/platform_thread.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     size_t 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 ioInitiatedByPlatformThread;
     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 protected:
    104     static bool Run(void* obj);
    105     bool Process();
    106 private:
    107     HANDLE _ioCompletionHandle;
    108     rtc::PlatformThread _pThread;
    109     static int32_t _numOfWorkers;
    110     int32_t _workerNumber;
    111     volatile bool _stop;
    112     bool _init;
    113 };
    114 
    115 class UdpSocket2ManagerWindows : public UdpSocketManager
    116 {
    117 public:
    118     UdpSocket2ManagerWindows();
    119     virtual ~UdpSocket2ManagerWindows();
    120 
    121     virtual bool Init(int32_t id, uint8_t& numOfWorkThreads);
    122 
    123     virtual bool Start();
    124     virtual bool Stop();
    125 
    126     virtual inline bool AddSocket(UdpSocketWrapper* s)
    127     {if(s) return AddSocketPrv(reinterpret_cast<UdpSocket2Windows*>(s));
    128      return false;}
    129     virtual bool RemoveSocket(UdpSocketWrapper* s)
    130     {if(s) return RemoveSocketPrv(reinterpret_cast<UdpSocket2Windows*>(s));
    131      return false;}
    132 
    133     PerIoContext* PopIoContext(void);
    134     int32_t PushIoContext(PerIoContext* pIoContext);
    135 
    136 private:
    137     typedef std::list<UdpSocket2WorkerWindows*> WorkerList;
    138     bool StopWorkerThreads();
    139     bool StartWorkerThreads();
    140     bool AddSocketPrv(UdpSocket2Windows* s);
    141     bool RemoveSocketPrv(UdpSocket2Windows* s);
    142 
    143     static uint32_t _numOfActiveManagers;
    144     static bool _wsaInit;
    145 
    146     int32_t _id;
    147     CriticalSectionWrapper* _pCrit;
    148     int32_t _managerNumber;
    149     volatile bool _stopped;
    150     bool _init;
    151     int32_t _numActiveSockets;
    152     WorkerList _workerThreadsList;
    153     EventWrapper* _event;
    154 
    155     HANDLE _ioCompletionHandle;
    156     IoContextPool _ioContextPool;
    157 };
    158 
    159 }  // namespace test
    160 }  // namespace webrtc
    161 
    162 #endif  // WEBRTC_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_MANAGER_WINDOWS_H_
    163