Index: webrtc/test/channel_transport/udp_socket2_manager_win.cc |
diff --git a/webrtc/test/channel_transport/udp_socket2_manager_win.cc b/webrtc/test/channel_transport/udp_socket2_manager_win.cc |
deleted file mode 100644 |
index 9f40350287b61b8a810800a8e73901371a51291c..0000000000000000000000000000000000000000 |
--- a/webrtc/test/channel_transport/udp_socket2_manager_win.cc |
+++ /dev/null |
@@ -1,608 +0,0 @@ |
-/* |
- * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
- * |
- * Use of this source code is governed by a BSD-style license |
- * that can be found in the LICENSE file in the root of the source |
- * tree. An additional intellectual property rights grant can be found |
- * in the file PATENTS. All contributing project authors may |
- * be found in the AUTHORS file in the root of the source tree. |
- */ |
- |
-#include "webrtc/test/channel_transport/udp_socket2_manager_win.h" |
- |
-#include <assert.h> |
-#include <stdio.h> |
- |
-#include "webrtc/system_wrappers/include/aligned_malloc.h" |
-#include "webrtc/test/channel_transport/udp_socket2_win.h" |
- |
-namespace webrtc { |
-namespace test { |
- |
-uint32_t UdpSocket2ManagerWindows::_numOfActiveManagers = 0; |
-bool UdpSocket2ManagerWindows::_wsaInit = false; |
- |
-UdpSocket2ManagerWindows::UdpSocket2ManagerWindows() |
- : UdpSocketManager(), |
- _id(-1), |
- _stopped(false), |
- _init(false), |
- _pCrit(CriticalSectionWrapper::CreateCriticalSection()), |
- _ioCompletionHandle(NULL), |
- _numActiveSockets(0), |
- _event(EventWrapper::Create()) |
-{ |
- _managerNumber = _numOfActiveManagers++; |
- |
- if(_numOfActiveManagers == 1) |
- { |
- WORD wVersionRequested = MAKEWORD(2, 2); |
- WSADATA wsaData; |
- _wsaInit = WSAStartup(wVersionRequested, &wsaData) == 0; |
- // TODO (hellner): seems safer to use RAII for this. E.g. what happens |
- // if a UdpSocket2ManagerWindows() created and destroyed |
- // without being initialized. |
- } |
-} |
- |
-UdpSocket2ManagerWindows::~UdpSocket2ManagerWindows() |
-{ |
- WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, |
- "UdpSocket2ManagerWindows(%d)::~UdpSocket2ManagerWindows()", |
- _managerNumber); |
- |
- if(_init) |
- { |
- _pCrit->Enter(); |
- if(_numActiveSockets) |
- { |
- _pCrit->Leave(); |
- _event->Wait(INFINITE); |
- } |
- else |
- { |
- _pCrit->Leave(); |
- } |
- StopWorkerThreads(); |
- |
- for (WorkerList::iterator iter = _workerThreadsList.begin(); |
- iter != _workerThreadsList.end(); ++iter) { |
- delete *iter; |
- } |
- _workerThreadsList.clear(); |
- _ioContextPool.Free(); |
- |
- _numOfActiveManagers--; |
- if(_ioCompletionHandle) |
- { |
- CloseHandle(_ioCompletionHandle); |
- } |
- if (_numOfActiveManagers == 0) |
- { |
- if(_wsaInit) |
- { |
- WSACleanup(); |
- } |
- } |
- } |
- if(_pCrit) |
- { |
- delete _pCrit; |
- } |
- if(_event) |
- { |
- delete _event; |
- } |
-} |
- |
-bool UdpSocket2ManagerWindows::Init(int32_t id, |
- uint8_t& numOfWorkThreads) { |
- CriticalSectionScoped cs(_pCrit); |
- if ((_id != -1) || (_numOfWorkThreads != 0)) { |
- assert(_id != -1); |
- assert(_numOfWorkThreads != 0); |
- return false; |
- } |
- _id = id; |
- _numOfWorkThreads = numOfWorkThreads; |
- return true; |
-} |
- |
-bool UdpSocket2ManagerWindows::Start() |
-{ |
- WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, |
- "UdpSocket2ManagerWindows(%d)::Start()",_managerNumber); |
- if(!_init) |
- { |
- StartWorkerThreads(); |
- } |
- |
- if(!_init) |
- { |
- return false; |
- } |
- _pCrit->Enter(); |
- // Start worker threads. |
- _stopped = false; |
- int32_t error = 0; |
- for (WorkerList::iterator iter = _workerThreadsList.begin(); |
- iter != _workerThreadsList.end() && !error; ++iter) { |
- if(!(*iter)->Start()) |
- error = 1; |
- } |
- if(error) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows(%d)::Start() error starting worker\ |
- threads", |
- _managerNumber); |
- _pCrit->Leave(); |
- return false; |
- } |
- _pCrit->Leave(); |
- return true; |
-} |
- |
-bool UdpSocket2ManagerWindows::StartWorkerThreads() |
-{ |
- if(!_init) |
- { |
- _pCrit->Enter(); |
- |
- _ioCompletionHandle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, |
- 0, 0); |
- if(_ioCompletionHandle == NULL) |
- { |
- int32_t error = GetLastError(); |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows(%d)::StartWorkerThreads()" |
- "_ioCompletioHandle == NULL: error:%d", |
- _managerNumber,error); |
- _pCrit->Leave(); |
- return false; |
- } |
- |
- // Create worker threads. |
- uint32_t i = 0; |
- bool error = false; |
- while(i < _numOfWorkThreads && !error) |
- { |
- UdpSocket2WorkerWindows* pWorker = |
- new UdpSocket2WorkerWindows(_ioCompletionHandle); |
- if(pWorker->Init() != 0) |
- { |
- error = true; |
- delete pWorker; |
- break; |
- } |
- _workerThreadsList.push_front(pWorker); |
- i++; |
- } |
- if(error) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows(%d)::StartWorkerThreads() error " |
- "creating work threads", |
- _managerNumber); |
- // Delete worker threads. |
- for (WorkerList::iterator iter = _workerThreadsList.begin(); |
- iter != _workerThreadsList.end(); ++iter) { |
- delete *iter; |
- } |
- _workerThreadsList.clear(); |
- _pCrit->Leave(); |
- return false; |
- } |
- if(_ioContextPool.Init()) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows(%d)::StartWorkerThreads() error " |
- "initiating _ioContextPool", |
- _managerNumber); |
- _pCrit->Leave(); |
- return false; |
- } |
- _init = true; |
- WEBRTC_TRACE( |
- kTraceDebug, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows::StartWorkerThreads %d number of work " |
- "threads created and initialized", |
- _numOfWorkThreads); |
- _pCrit->Leave(); |
- } |
- return true; |
-} |
- |
-bool UdpSocket2ManagerWindows::Stop() |
-{ |
- WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, |
- "UdpSocket2ManagerWindows(%d)::Stop()",_managerNumber); |
- |
- if(!_init) |
- { |
- return false; |
- } |
- _pCrit->Enter(); |
- _stopped = true; |
- if(_numActiveSockets) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows(%d)::Stop() there is still active\ |
- sockets", |
- _managerNumber); |
- _pCrit->Leave(); |
- return false; |
- } |
- // No active sockets. Stop all worker threads. |
- bool result = StopWorkerThreads(); |
- _pCrit->Leave(); |
- return result; |
-} |
- |
-bool UdpSocket2ManagerWindows::StopWorkerThreads() |
-{ |
- int32_t error = 0; |
- WEBRTC_TRACE( |
- kTraceDebug, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows(%d)::StopWorkerThreads() Worker\ |
- threadsStoped, numActicve Sockets=%d", |
- _managerNumber, |
- _numActiveSockets); |
- |
- // Release all threads waiting for GetQueuedCompletionStatus(..). |
- if(_ioCompletionHandle) |
- { |
- uint32_t i = 0; |
- for(i = 0; i < _workerThreadsList.size(); i++) |
- { |
- PostQueuedCompletionStatus(_ioCompletionHandle, 0 ,0 , NULL); |
- } |
- } |
- for (WorkerList::iterator iter = _workerThreadsList.begin(); |
- iter != _workerThreadsList.end(); ++iter) { |
- if((*iter)->Stop() == false) |
- { |
- error = -1; |
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1, |
- "failed to stop worker thread"); |
- } |
- } |
- |
- if(error) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows(%d)::StopWorkerThreads() error stopping\ |
- worker threads", |
- _managerNumber); |
- return false; |
- } |
- return true; |
-} |
- |
-bool UdpSocket2ManagerWindows::AddSocketPrv(UdpSocket2Windows* s) |
-{ |
- WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, |
- "UdpSocket2ManagerWindows(%d)::AddSocketPrv()",_managerNumber); |
- if(!_init) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows(%d)::AddSocketPrv() manager not\ |
- initialized", |
- _managerNumber); |
- return false; |
- } |
- _pCrit->Enter(); |
- if(s == NULL) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows(%d)::AddSocketPrv() socket == NULL", |
- _managerNumber); |
- _pCrit->Leave(); |
- return false; |
- } |
- if(s->GetFd() == NULL || s->GetFd() == INVALID_SOCKET) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows(%d)::AddSocketPrv() socket->GetFd() ==\ |
- %d", |
- _managerNumber, |
- (int32_t)s->GetFd()); |
- _pCrit->Leave(); |
- return false; |
- |
- } |
- _ioCompletionHandle = CreateIoCompletionPort((HANDLE)s->GetFd(), |
- _ioCompletionHandle, |
- (ULONG_PTR)(s), 0); |
- if(_ioCompletionHandle == NULL) |
- { |
- int32_t error = GetLastError(); |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows(%d)::AddSocketPrv() Error adding to IO\ |
- completion: %d", |
- _managerNumber, |
- error); |
- _pCrit->Leave(); |
- return false; |
- } |
- _numActiveSockets++; |
- _pCrit->Leave(); |
- return true; |
-} |
-bool UdpSocket2ManagerWindows::RemoveSocketPrv(UdpSocket2Windows* s) |
-{ |
- if(!_init) |
- { |
- return false; |
- } |
- _pCrit->Enter(); |
- _numActiveSockets--; |
- if(_numActiveSockets == 0) |
- { |
- _event->Set(); |
- } |
- _pCrit->Leave(); |
- return true; |
-} |
- |
-PerIoContext* UdpSocket2ManagerWindows::PopIoContext() |
-{ |
- if(!_init) |
- { |
- return NULL; |
- } |
- |
- PerIoContext* pIoC = NULL; |
- if(!_stopped) |
- { |
- pIoC = _ioContextPool.PopIoContext(); |
- }else |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceTransport, |
- _id, |
- "UdpSocket2ManagerWindows(%d)::PopIoContext() Manager Not started", |
- _managerNumber); |
- } |
- return pIoC; |
-} |
- |
-int32_t UdpSocket2ManagerWindows::PushIoContext(PerIoContext* pIoContext) |
-{ |
- return _ioContextPool.PushIoContext(pIoContext); |
-} |
- |
-IoContextPool::IoContextPool() |
- : _pListHead(NULL), |
- _init(false), |
- _size(0), |
- _inUse(0) |
-{ |
-} |
- |
-IoContextPool::~IoContextPool() |
-{ |
- Free(); |
- assert(_size.Value() == 0); |
- AlignedFree(_pListHead); |
-} |
- |
-int32_t IoContextPool::Init(uint32_t /*increaseSize*/) |
-{ |
- if(_init) |
- { |
- return 0; |
- } |
- |
- _pListHead = (PSLIST_HEADER)AlignedMalloc(sizeof(SLIST_HEADER), |
- MEMORY_ALLOCATION_ALIGNMENT); |
- if(_pListHead == NULL) |
- { |
- return -1; |
- } |
- InitializeSListHead(_pListHead); |
- _init = true; |
- return 0; |
-} |
- |
-PerIoContext* IoContextPool::PopIoContext() |
-{ |
- if(!_init) |
- { |
- return NULL; |
- } |
- |
- PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(_pListHead); |
- if(pListEntry == NULL) |
- { |
- IoContextPoolItem* item = (IoContextPoolItem*) |
- AlignedMalloc( |
- sizeof(IoContextPoolItem), |
- MEMORY_ALLOCATION_ALIGNMENT); |
- if(item == NULL) |
- { |
- return NULL; |
- } |
- memset(&item->payload.ioContext,0,sizeof(PerIoContext)); |
- item->payload.base = item; |
- pListEntry = &(item->itemEntry); |
- ++_size; |
- } |
- ++_inUse; |
- return &((IoContextPoolItem*)pListEntry)->payload.ioContext; |
-} |
- |
-int32_t IoContextPool::PushIoContext(PerIoContext* pIoContext) |
-{ |
- // TODO (hellner): Overlapped IO should be completed at this point. Perhaps |
- // add an assert? |
- const bool overlappedIOCompleted = HasOverlappedIoCompleted( |
- (LPOVERLAPPED)pIoContext); |
- |
- IoContextPoolItem* item = ((IoContextPoolItemPayload*)pIoContext)->base; |
- |
- const int32_t usedItems = --_inUse; |
- const int32_t totalItems = _size.Value(); |
- const int32_t freeItems = totalItems - usedItems; |
- if(freeItems < 0) |
- { |
- assert(false); |
- AlignedFree(item); |
- return -1; |
- } |
- if((freeItems >= totalItems>>1) && |
- overlappedIOCompleted) |
- { |
- AlignedFree(item); |
- --_size; |
- return 0; |
- } |
- InterlockedPushEntrySList(_pListHead, &(item->itemEntry)); |
- return 0; |
-} |
- |
-int32_t IoContextPool::Free() |
-{ |
- if(!_init) |
- { |
- return 0; |
- } |
- |
- int32_t itemsFreed = 0; |
- PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(_pListHead); |
- while(pListEntry != NULL) |
- { |
- IoContextPoolItem* item = ((IoContextPoolItem*)pListEntry); |
- AlignedFree(item); |
- --_size; |
- itemsFreed++; |
- pListEntry = InterlockedPopEntrySList(_pListHead); |
- } |
- return itemsFreed; |
-} |
- |
-int32_t UdpSocket2WorkerWindows::_numOfWorkers = 0; |
- |
-UdpSocket2WorkerWindows::UdpSocket2WorkerWindows(HANDLE ioCompletionHandle) |
- : _ioCompletionHandle(ioCompletionHandle), |
- _pThread(Run, this, "UdpSocket2ManagerWindows_thread"), |
- _init(false) { |
- _workerNumber = _numOfWorkers++; |
- WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1, |
- "UdpSocket2WorkerWindows created"); |
-} |
- |
-UdpSocket2WorkerWindows::~UdpSocket2WorkerWindows() |
-{ |
- WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1, |
- "UdpSocket2WorkerWindows deleted"); |
-} |
- |
-bool UdpSocket2WorkerWindows::Start() |
-{ |
- WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1, |
- "Start UdpSocket2WorkerWindows"); |
- _pThread.Start(); |
- |
- _pThread.SetPriority(rtc::kRealtimePriority); |
- return true; |
-} |
- |
-bool UdpSocket2WorkerWindows::Stop() |
-{ |
- WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1, |
- "Stop UdpSocket2WorkerWindows"); |
- _pThread.Stop(); |
- return true; |
-} |
- |
-int32_t UdpSocket2WorkerWindows::Init() |
-{ |
- _init = true; |
- return 0; |
-} |
- |
-bool UdpSocket2WorkerWindows::Run(void* obj) |
-{ |
- UdpSocket2WorkerWindows* pWorker = |
- static_cast<UdpSocket2WorkerWindows*>(obj); |
- return pWorker->Process(); |
-} |
- |
-// Process should always return true. Stopping the worker threads is done in |
-// the UdpSocket2ManagerWindows::StopWorkerThreads() function. |
-bool UdpSocket2WorkerWindows::Process() |
-{ |
- int32_t success = 0; |
- DWORD ioSize = 0; |
- UdpSocket2Windows* pSocket = NULL; |
- PerIoContext* pIOContext = 0; |
- OVERLAPPED* pOverlapped = 0; |
- success = GetQueuedCompletionStatus(_ioCompletionHandle, |
- &ioSize, |
- (ULONG_PTR*)&pSocket, &pOverlapped, 200); |
- |
- uint32_t error = 0; |
- if(!success) |
- { |
- error = GetLastError(); |
- if(error == WAIT_TIMEOUT) |
- { |
- return true; |
- } |
- // This may happen if e.g. PostQueuedCompletionStatus() has been called. |
- // The IO context still needs to be reclaimed or re-used which is done |
- // in UdpSocket2Windows::IOCompleted(..). |
- } |
- if(pSocket == NULL) |
- { |
- WEBRTC_TRACE( |
- kTraceDebug, |
- kTraceTransport, |
- -1, |
- "UdpSocket2WorkerWindows(%d)::Process(), pSocket == 0, end thread", |
- _workerNumber); |
- return true; |
- } |
- pIOContext = (PerIoContext*)pOverlapped; |
- pSocket->IOCompleted(pIOContext,ioSize,error); |
- return true; |
-} |
- |
-} // namespace test |
-} // namespace webrtc |