From: James Turner Date: Tue, 30 Aug 2011 12:41:06 +0000 (+0100) Subject: Revert "Asynchronous host lookups+caching, attempt #2" X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=eafea282664cbbf3316a068ce6683990cb1d5486;p=simgear.git Revert "Asynchronous host lookups+caching, attempt #2" Bah, SGThread is a pain, need to switch to OpenThreads This reverts commit 1cb9a79fd48ce6151f6a2cf8d07ef23e002a81b1. --- diff --git a/simgear/io/CMakeLists.txt b/simgear/io/CMakeLists.txt index b3af0663..a2638e1b 100644 --- a/simgear/io/CMakeLists.txt +++ b/simgear/io/CMakeLists.txt @@ -37,17 +37,17 @@ set(SOURCES simgear_component(io io "${SOURCES}" "${HEADERS}") add_executable(test_sock socktest.cxx) -target_link_libraries(test_sock sgio sgstructure sgdebug sgthreads) +target_link_libraries(test_sock sgio sgstructure sgdebug) add_executable(test_http test_HTTP.cxx) target_link_libraries(test_http - sgio sgstructure sgtiming sgmisc sgdebug sgthreads + sgio sgstructure sgtiming sgmisc sgdebug ${RT_LIBRARY}) add_test(http ${EXECUTABLE_OUTPUT_PATH}/test_http) add_executable(httpget httpget.cxx) target_link_libraries(httpget - sgio sgstructure sgtiming sgmisc sgdebug sgthreads + sgio sgstructure sgtiming sgmisc sgdebug ${RT_LIBRARY}) \ No newline at end of file diff --git a/simgear/io/Makefile.am b/simgear/io/Makefile.am index 05d05a03..760676a3 100644 --- a/simgear/io/Makefile.am +++ b/simgear/io/Makefile.am @@ -44,7 +44,6 @@ tcp_server_LDADD = \ $(top_builddir)/simgear/debug/libsgdebug.a \ $(top_builddir)/simgear/bucket/libsgbucket.a \ $(top_builddir)/simgear/misc/libsgmisc.a \ - $(top_builddir)/simgear/threads/libsgthreads.a \ -lz \ $(network_LIBS) \ $(base_LIBS) @@ -57,7 +56,6 @@ tcp_client_LDADD = \ $(top_builddir)/simgear/debug/libsgdebug.a \ $(top_builddir)/simgear/bucket/libsgbucket.a \ $(top_builddir)/simgear/misc/libsgmisc.a \ - $(top_builddir)/simgear/threads/libsgthreads.a \ -lz \ $(network_LIBS) \ $(base_LIBS) @@ -70,7 +68,6 @@ socktest_LDADD = \ $(top_builddir)/simgear/debug/libsgdebug.a \ $(top_builddir)/simgear/bucket/libsgbucket.a \ $(top_builddir)/simgear/misc/libsgmisc.a \ - $(top_builddir)/simgear/threads/libsgthreads.a \ -lz \ $(network_LIBS) \ $(base_LIBS) @@ -83,7 +80,6 @@ lowtest_LDADD = \ $(top_builddir)/simgear/debug/libsgdebug.a \ $(top_builddir)/simgear/bucket/libsgbucket.a \ $(top_builddir)/simgear/misc/libsgmisc.a \ - $(top_builddir)/simgear/threads/libsgthreads.a \ $(base_LIBS) -lz decode_binobj_SOURCES = decode_binobj.cxx @@ -93,5 +89,4 @@ decode_binobj_LDADD = \ $(top_builddir)/simgear/debug/libsgdebug.a \ $(top_builddir)/simgear/bucket/libsgbucket.a \ $(top_builddir)/simgear/misc/libsgmisc.a \ - $(top_builddir)/simgear/threads/libsgthreads.a \ $(base_LIBS) -lz diff --git a/simgear/io/raw_socket.cxx b/simgear/io/raw_socket.cxx index 2ef5d4c4..d972c145 100644 --- a/simgear/io/raw_socket.cxx +++ b/simgear/io/raw_socket.cxx @@ -57,161 +57,8 @@ #define socklen_t int #endif -#include - #include #include -#include - -namespace { - - - -class Resolver : public SGThread -{ -public: - static Resolver* instance() - { - if (!static_instance) { - static_instance = new Resolver; - atexit(&Resolver::cleanup); - static_instance->start(); - } - - return static_instance; - } - - static void cleanup() - { - static_instance->cancel(); - } - - Resolver() - { - // take the lock initially, thread will wait upon it once running - _lock.lock(); - } - - simgear::IPAddress* lookup(const string& host) - { - simgear::IPAddress* result = NULL; - _lock.lock(); - AddressCache::iterator it = _cache.find(host); - if (it == _cache.end()) { - _cache[host] = NULL; // mark as needing looked up - _wait.signal(); // if the thread was sleeping, poke it - } else { - result = it->second; - } - _lock.unlock(); - return result; - } - - simgear::IPAddress* lookupSync(const string& host) - { - simgear::IPAddress* result = NULL; - _lock.lock(); - AddressCache::iterator it = _cache.find(host); - if (it == _cache.end()) { - _lock.unlock(); - result = new simgear::IPAddress; - bool ok = lookupHost(host.c_str(), *result); - _lock.lock(); - if (ok) { - _cache[host] = result; // mark as needing looked up - } else { - delete result; - result = NULL; - } - } else { // found in cache, easy - result = it->second; - } - _lock.unlock(); - return result; - } -protected: - /** - * run method waits on a condition (_wait), and when awoken, - * finds any unresolved entries in _cache, resolves them, and goes - * back to sleep. - */ - virtual void run() - { - while (true) { - _wait.wait(_lock); - AddressCache::iterator it; - - for (it = _cache.begin(); it != _cache.end(); ++it) { - if (it->second == NULL) { - string h = it->first; - - _lock.unlock(); - simgear::IPAddress* addr = new simgear::IPAddress; - // may take seconds or even minutes! - lookupHost(h.c_str(), *addr); - _lock.lock(); - - // cahce may have changed while we had the lock released - - // so iterators may be invalid: restart the traversal - it = _cache.begin(); - _cache[h] = addr; - } // of found un-resolved entry - } // of un-resolved address iteration - } // of thread run loop - } -private: - static Resolver* static_instance; - - /** - * The actual synchronous, blocking host lookup function - * do *not* call this with any locks (mutexs) held, since depending - * on local system configuration / network availability, it - * may block for seconds or minutes. - */ - bool lookupHost(const char* host, simgear::IPAddress& addr) - { - struct addrinfo hints; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_INET; - bool ok = false; - - struct addrinfo* result0 = NULL; - int err = getaddrinfo(host, NULL, &hints, &result0); - if (err) { - SG_LOG(SG_IO, SG_WARN, "getaddrinfo failed for '" << host << "' : " << gai_strerror(err)); - return false; - } else { - struct addrinfo* result; - for (result = result0; result != NULL; result = result->ai_next) { - if (result->ai_family != AF_INET) { // only accept IP4 for the moment - continue; - } - - if (result->ai_addrlen != addr.getAddrLen()) { - SG_LOG(SG_IO, SG_ALERT, "mismatch in socket address sizes: got " << - result->ai_addrlen << ", expected " << addr.getAddrLen()); - continue; - } - - memcpy(addr.getAddr(), result->ai_addr, result->ai_addrlen); - ok = true; - break; - } // of getaddrinfo results iteration - } // of getaddrinfo succeeded - - freeaddrinfo(result0); - return ok; - } - - SGMutex _lock; - SGPthreadCond _wait; - typedef std::map AddressCache; - AddressCache _cache; -}; - -Resolver* Resolver::static_instance = NULL; - -} // of anonymous namespace namespace simgear { @@ -268,12 +115,33 @@ void IPAddress::set ( const char* host, int port ) return; } -// check the cache - IPAddress* cached = Resolver::instance()->lookupSync(host); - if (cached) { - memcpy(addr, cached->getAddr(), cached->getAddrLen()); - } + struct addrinfo hints; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_INET; + struct addrinfo* result0 = NULL; + int err = getaddrinfo(host, NULL, &hints, &result0); + if (err) { + SG_LOG(SG_IO, SG_WARN, "getaddrinfo failed for '" << host << "' : " << gai_strerror(err)); + } else { + struct addrinfo* result; + for (result = result0; result != NULL; result = result->ai_next) { + if (result->ai_family != AF_INET) { // only accept IP4 for the moment + continue; + } + + if (result->ai_addrlen != getAddrLen()) { + SG_LOG(SG_IO, SG_ALERT, "mismatch in socket address sizes: got " << + result->ai_addrlen << ", expected " << getAddrLen()); + continue; + } + + memcpy(addr, result->ai_addr, result->ai_addrlen); + break; + } // of getaddrinfo results iteration + } // of getaddrinfo succeeded + + freeaddrinfo(result0); addr->sin_port = htons (port); // fix up port after getaddrinfo } @@ -284,17 +152,6 @@ IPAddress::~IPAddress() } } -bool IPAddress::lookupNonblocking(const char* host, IPAddress& addr) -{ - IPAddress* cached = Resolver::instance()->lookup(host); - if (!cached) { - return false; - } - - addr = *cached; - return true; -} - /* Create a string object representing an IP address. This is always a string of the form 'dd.dd.dd.dd' (with variable size numbers). */ @@ -319,11 +176,6 @@ unsigned int IPAddress::getPort() const return ntohs(addr->sin_port); } -void IPAddress::setPort(int port) -{ - addr->sin_port = htons(port); -} - unsigned int IPAddress::getFamily () const { return addr->sin_family; @@ -363,11 +215,6 @@ unsigned int IPAddress::getAddrLen() const struct sockaddr* IPAddress::getAddr() const { - if (addr == NULL) { - addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in)); - memset(addr, 0, sizeof(struct sockaddr_in)); - } - return (struct sockaddr*) addr; } diff --git a/simgear/io/raw_socket.hxx b/simgear/io/raw_socket.hxx index 9450e9eb..2b5031f3 100644 --- a/simgear/io/raw_socket.hxx +++ b/simgear/io/raw_socket.hxx @@ -40,22 +40,18 @@ namespace simgear */ class IPAddress { - mutable struct sockaddr_in* addr; + struct sockaddr_in* addr; public: IPAddress () : addr(0) {} IPAddress ( const char* host, int port ) ; ~IPAddress(); - static bool lookupNonblocking(const char* host, IPAddress& addr); - IPAddress( const IPAddress& other ); const IPAddress& operator=(const IPAddress& other); void set ( const char* host, int port ) ; const char* getHost () const ; unsigned int getPort() const ; - void setPort(int port); - unsigned int getIP () const ; unsigned int getFamily () const ; static const char* getLocalHost () ; @@ -73,7 +69,7 @@ public: class Socket { int handle ; - + public: Socket () ; diff --git a/simgear/io/sg_netChannel.cxx b/simgear/io/sg_netChannel.cxx index 86839e71..c3644b6c 100644 --- a/simgear/io/sg_netChannel.cxx +++ b/simgear/io/sg_netChannel.cxx @@ -38,7 +38,6 @@ #include - namespace simgear { static NetChannel* channels = 0 ; @@ -47,7 +46,6 @@ NetChannel::NetChannel () { closed = true ; connected = false ; - resolving_host = false; accepting = false ; write_blocked = false ; should_delete = false ; @@ -85,6 +83,7 @@ NetChannel::setHandle (int handle, bool is_connected) close () ; Socket::setHandle ( handle ) ; connected = is_connected ; + //if ( connected ) this->handleConnect(); closed = false ; } @@ -108,12 +107,21 @@ NetChannel::listen ( int backlog ) } int -NetChannel::connect ( const char* h, int p ) +NetChannel::connect ( const char* host, int port ) { - host = h; - port = p; - resolving_host = true; - return handleResolve(); + int result = Socket::connect ( host, port ) ; + if (result == 0) { + connected = true ; + //this->handleConnect(); + return 0; + } else if (isNonBlockingError ()) { + return 0; + } else { + // some other error condition + this->handleError (result); + close(); + return -1; + } } int @@ -181,10 +189,12 @@ NetChannel::handleReadEvent (void) if (accepting) { if (!connected) { connected = true ; + //this->handleConnect(); } this->handleAccept(); } else if (!connected) { connected = true ; + //this->handleConnect(); this->handleRead(); } else { this->handleRead(); @@ -196,35 +206,12 @@ NetChannel::handleWriteEvent (void) { if (!connected) { connected = true ; + //this->handleConnect(); } write_blocked = false ; this->handleWrite(); } -int -NetChannel::handleResolve() -{ - IPAddress addr; - if (!IPAddress::lookupNonblocking(host.c_str(), addr)) { - return 0; // not looked up yet, wait longer - } - - resolving_host = false; - addr.setPort(port); - int result = Socket::connect ( &addr ) ; - if (result == 0) { - connected = true ; - return 0; - } else if (isNonBlockingError ()) { - return 0; - } else { - // some other error condition - handleError (result); - close(); - return -1; - } -} - bool NetChannel::poll (unsigned int timeout) { @@ -249,12 +236,6 @@ NetChannel::poll (unsigned int timeout) } else if ( ! ch -> closed ) { - if (ch -> resolving_host ) - { - ch -> handleResolve(); - continue; - } - nopen++ ; if (ch -> readable()) { assert(nreads -#include namespace simgear { class NetChannel : public Socket { - bool closed, connected, accepting, write_blocked, should_delete, resolving_host ; + bool closed, connected, accepting, write_blocked, should_delete ; NetChannel* next_channel ; - std::string host; - int port; friend bool netPoll (unsigned int timeout); @@ -99,7 +96,6 @@ public: void handleReadEvent (void); void handleWriteEvent (void); - int handleResolve (void); // These are meant to be overridden. virtual void handleClose (void) {