Torque3D Documentation / _generateds / platformNetAsync.cpp

platformNetAsync.cpp

Engine/source/platform/platformNetAsync.cpp

More...

Classes:

class

Work item issued to the thread pool for each lookup request.

Public Variables

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