platformNetAsync.cpp
Engine/source/platform/platformNetAsync.cpp
Classes:
class
Work item issued to the thread pool for each lookup request.
Detailed Description
Public Variables
NetAsync gNetAsync
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platformNetAsync.h" 25#include "core/strings/stringFunctions.h" 26#include "platform/threads/threadPool.h" 27#include "console/console.h" 28 29#if defined(TORQUE_OS_WIN) 30# include <winsock.h> 31#else 32# include <netdb.h> 33# include <unistd.h> 34#endif 35 36#include <errno.h> 37 38NetAsync gNetAsync; 39 40//-------------------------------------------------------------------------- 41// NetAsync::NameLookupRequest. 42//-------------------------------------------------------------------------- 43 44// internal structure for storing information about a name lookup request 45struct NetAsync::NameLookupRequest 46{ 47 NetSocket sock; 48 char remoteAddr[4096]; 49 char out_h_addr[4096]; 50 S32 out_h_length; 51 bool complete; 52 53 NameLookupRequest() 54 { 55 sock = NetSocket::INVALID; 56 remoteAddr[0] = 0; 57 out_h_addr[0] = 0; 58 out_h_length = -1; 59 complete = false; 60 } 61}; 62 63//-------------------------------------------------------------------------- 64// NetAsync::NameLookupWorkItem. 65//-------------------------------------------------------------------------- 66 67/// Work item issued to the thread pool for each lookup request. 68 69struct NetAsync::NameLookupWorkItem : public ThreadPool::WorkItem 70{ 71 typedef ThreadPool::WorkItem Parent; 72 73 NameLookupWorkItem( NameLookupRequest& request, ThreadPool::Context* context = 0 ) 74 : Parent( context ), 75 mRequest( request ) 76 { 77 } 78 79protected: 80 virtual void execute() 81 { 82 NetAddress address; 83 Net::Error error = Net::stringToAddress(mRequest.remoteAddr, &address, true); 84 85 // do it 86 if (error != Net::NoError) 87 { 88 // oh well! leave the lookup data unmodified (h_length) should 89 // still be -1 from initialization 90 mRequest.complete = true; 91 } 92 else 93 { 94 // copy the stuff we need from the hostent 95 dMemset(mRequest.out_h_addr, 0, 96 sizeof(mRequest.out_h_addr)); 97 dMemcpy(mRequest.out_h_addr, &address, sizeof(address)); 98 99 mRequest.out_h_length = sizeof(address); 100 mRequest.complete = true; 101 } 102 } 103 104private: 105 NameLookupRequest& mRequest; 106}; 107 108//-------------------------------------------------------------------------- 109// NetAsync. 110//-------------------------------------------------------------------------- 111 112NetAsync::NetAsync() 113{ 114 VECTOR_SET_ASSOCIATION( mLookupRequests ); 115} 116 117void NetAsync::queueLookup(const char* remoteAddr, NetSocket socket) 118{ 119 // do we have it already? 120 121 U32 i = 0; 122 for (i = 0; i < mLookupRequests.size(); ++i) 123 { 124 if (mLookupRequests[i].sock == socket) 125 // found it. ignore more than one lookup at a time for a socket. 126 return; 127 } 128 129 // not found, so add it 130 131 mLookupRequests.increment(); 132 NameLookupRequest& lookupRequest = mLookupRequests.last(); 133 lookupRequest.sock = socket; 134 dStrncpy(lookupRequest.remoteAddr, remoteAddr, sizeof(lookupRequest.remoteAddr)); 135 136 ThreadSafeRef< NameLookupWorkItem> workItem( new NameLookupWorkItem( lookupRequest ) ); 137 ThreadPool::GLOBAL().queueWorkItem( workItem ); 138} 139 140bool NetAsync::checkLookup(NetSocket socket, void* out_h_addr, 141 S32* out_h_length, S32 out_h_addr_size) 142{ 143 bool found = false; 144 145 // search for the socket 146 RequestIterator iter; 147 for (iter = mLookupRequests.begin(); 148 iter != mLookupRequests.end(); 149 ++iter) 150 // if we found it and it is complete... 151 if (socket == iter->sock && iter->complete) 152 { 153 // copy the lookup data to the callers parameters 154 dMemcpy(out_h_addr, iter->out_h_addr, out_h_addr_size); 155 *out_h_length = iter->out_h_length; 156 found = true; 157 break; 158 } 159 160 // we found the socket, so we are done with it. erase. 161 if (found) 162 mLookupRequests.erase(iter); 163 164 return found; 165} 166