diff options
| author | Oz Linden <oz@lindenlab.com> | 2017-02-02 15:49:16 -0500 | 
|---|---|---|
| committer | Oz Linden <oz@lindenlab.com> | 2017-02-02 15:49:16 -0500 | 
| commit | 1925fd2b8b9216e5d9388e6a0c077c99aa782cad (patch) | |
| tree | 2507c9889eb825302f7c3f1650b85e6208b04e4e /indra/llmessage | |
| parent | 7f544db197fcaa8a697ee9d9694d11b297a20266 (diff) | |
| parent | 080744d8990e6b18a80858803a20a5ec87020d82 (diff) | |
merge changes for 5.0.1-release
Diffstat (limited to 'indra/llmessage')
| -rw-r--r-- | indra/llmessage/llcoproceduremanager.h | 6 | ||||
| -rw-r--r-- | indra/llmessage/llexperiencecache.h | 3 | ||||
| -rw-r--r-- | indra/llmessage/llproxy.h | 8 | ||||
| -rw-r--r-- | indra/llmessage/llxfer_file.cpp | 6 | ||||
| -rw-r--r-- | indra/llmessage/llxfermanager.cpp | 2 | ||||
| -rw-r--r-- | indra/llmessage/message.cpp | 7 | ||||
| -rw-r--r-- | indra/llmessage/message.h | 7 | ||||
| -rw-r--r-- | indra/llmessage/tests/llhttpclient_test.cpp | 3 | ||||
| -rw-r--r-- | indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp | 3 | ||||
| -rw-r--r-- | indra/llmessage/tests/lltrustedmessageservice_test.cpp | 3 | ||||
| -rw-r--r-- | indra/llmessage/tests/networkio.h | 3 | ||||
| -rwxr-xr-x | indra/llmessage/tests/test_llsdmessage_peer.py | 27 | ||||
| -rwxr-xr-x | indra/llmessage/tests/testrunner.py | 87 | 
13 files changed, 109 insertions, 56 deletions
| diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index 497367b80c..7d0e83180c 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -37,7 +37,8 @@ class LLCoprocedurePool;  class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager >  { -    friend class LLSingleton < LLCoprocedureManager > ; +    LLSINGLETON(LLCoprocedureManager); +    virtual ~LLCoprocedureManager();  public:      typedef boost::function<U32(const std::string &)> SettingQuery_t; @@ -45,9 +46,6 @@ public:      typedef boost::function<void(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, const LLUUID &id)> CoProcedure_t; -    LLCoprocedureManager(); -    virtual ~LLCoprocedureManager(); -      /// Places the coprocedure on the queue for processing.       ///       /// @param name Is used for debugging and should identify this coroutine. diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h index 1002b33f80..8ee7080d38 100644 --- a/indra/llmessage/llexperiencecache.h +++ b/indra/llmessage/llexperiencecache.h @@ -43,7 +43,7 @@ class LLUUID;  class LLExperienceCache: public LLSingleton < LLExperienceCache >  { -    friend class LLSingleton < LLExperienceCache > ; +    LLSINGLETON(LLExperienceCache);  public:      typedef boost::function<std::string(const std::string &)> CapabilityQuery_t; @@ -103,7 +103,6 @@ public:      static const int PROPERTY_SUSPENDED;	// 1 << 7  private: -    LLExperienceCache();      virtual ~LLExperienceCache();      virtual void initSingleton(); diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index bd23dd39de..688dff7c83 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -218,14 +218,14 @@ enum LLSocks5AuthType   */  class LLProxy: public LLSingleton<LLProxy>  { -	LOG_CLASS(LLProxy); -public:  	/*###########################################################################################  	METHODS THAT DO NOT LOCK mProxyMutex!  	###########################################################################################*/  	// Constructor, cannot have parameters due to LLSingleton parent class. Call from main thread only. -	LLProxy(); +	LLSINGLETON(LLProxy); +	LOG_CLASS(LLProxy); +public:  	// Static check for enabled status for UDP packets. Call from main thread only.  	static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; } @@ -239,9 +239,11 @@ public:  	/*###########################################################################################  	METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!  	###########################################################################################*/ +private:  	// Destructor, closes open connections. Do not call directly, use cleanupClass().  	~LLProxy(); +public:  	// Delete LLProxy singleton. Allows the apr_socket used in the SOCKS 5 control channel to be  	// destroyed before the call to apr_terminate. Call from main thread only.  	static void cleanupClass(); diff --git a/indra/llmessage/llxfer_file.cpp b/indra/llmessage/llxfer_file.cpp index 257a13f277..8e2ed890e7 100644 --- a/indra/llmessage/llxfer_file.cpp +++ b/indra/llmessage/llxfer_file.cpp @@ -98,12 +98,12 @@ void LLXfer_File::cleanup ()  		mFp = NULL;  	} -	LLFile::remove(mTempFilename); +	LLFile::remove(mTempFilename, ENOENT);  	if (mDeleteLocalOnCompletion)  	{  		LL_DEBUGS() << "Removing file: " << mLocalFilename << LL_ENDL; -		LLFile::remove(mLocalFilename); +		LLFile::remove(mLocalFilename, ENOENT);  	}  	else  	{ @@ -321,7 +321,7 @@ S32 LLXfer_File::processEOF()  		mCallbackResult = flushval;  	} -	LLFile::remove(mLocalFilename); +	LLFile::remove(mLocalFilename, ENOENT);  	if (!mCallbackResult)  	{ diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp index 272dbbc785..2ceb64ce8f 100644 --- a/indra/llmessage/llxfermanager.cpp +++ b/indra/llmessage/llxfermanager.cpp @@ -444,7 +444,7 @@ U64 LLXferManager::requestFile(const std::string& local_filename,  			&& (remote_filename.substr(remote_filename.length()-4) == ".tmp")  			&& gDirUtilp->fileExists(local_filename))  		{ -			LLFile::remove(local_filename); +			LLFile::remove(local_filename, ENOENT);  		}  		xfer_id = getNextID();  		((LLXfer_File *)xferp)->initializeRequest( diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 290b67feb3..6ef4025ab1 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -76,6 +76,7 @@  #include "v4math.h"  #include "lltransfertargetvfile.h"  #include "llcorehttputil.h" +#include "llpounceable.h"  // Constants  //const char* MESSAGE_LOG_FILENAME = "message.log"; @@ -1724,7 +1725,9 @@ std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg)  	return s;  } -LLMessageSystem	*gMessageSystem = NULL; +// LLPounceable supports callWhenReady(), to permit clients to queue up (e.g.) +// callback registrations for when gMessageSystem is first assigned +LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;  // update appropriate ping info  void	process_complete_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/) @@ -2641,7 +2644,7 @@ void end_messaging_system(bool print_summary)  			LL_INFOS("Messaging") << str.str().c_str() << LL_ENDL;  		} -		delete gMessageSystem; +		delete static_cast<LLMessageSystem*>(gMessageSystem);  		gMessageSystem = NULL;  	}  } diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index 133db620e6..f6c5d9e228 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -60,6 +60,7 @@  #include "llstoredmessage.h"  #include "boost/function.hpp" +#include "llpounceable.h"  const U32 MESSAGE_MAX_STRINGS_LENGTH = 64;  const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192; @@ -68,10 +69,10 @@ const S32 MESSAGE_MAX_PER_FRAME = 400;  class LLMessageStringTable : public LLSingleton<LLMessageStringTable>  { -public: -	LLMessageStringTable(); +	LLSINGLETON(LLMessageStringTable);  	~LLMessageStringTable(); +public:  	char *getString(const char *str);  	U32	 mUsed; @@ -832,7 +833,7 @@ private:  // external hook into messaging system -extern LLMessageSystem	*gMessageSystem; +extern LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;  // Must specific overall system version, which is used to determine  // if a patch is available in the message template checksum verification. diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp index a32bfa59ce..9356a14f1f 100644 --- a/indra/llmessage/tests/llhttpclient_test.cpp +++ b/indra/llmessage/tests/llhttpclient_test.cpp @@ -42,6 +42,7 @@  #include "lliosocket.h"  #include "stringize.h" +#include "llcleanup.h"  namespace tut  { @@ -66,7 +67,7 @@ namespace tut  		~HTTPClientTestData()  		{  			delete mClientPump; -			LLProxy::cleanupClass(); +			SUBSYSTEM_CLEANUP(LLProxy);  			apr_pool_destroy(mPool);  		} diff --git a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp index 3b04530c1a..e20f61b73f 100644 --- a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp +++ b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp @@ -31,11 +31,12 @@  #include "llhost.h"  #include "message.h"  #include "llsd.h" +#include "llpounceable.h"  #include "llhost.cpp" // Needed for copy operator  #include "net.cpp" // Needed by LLHost. -LLMessageSystem * gMessageSystem = NULL; +LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;  // sensor test doubles  bool gClearRecvWasCalled = false; diff --git a/indra/llmessage/tests/lltrustedmessageservice_test.cpp b/indra/llmessage/tests/lltrustedmessageservice_test.cpp index 55748ad27e..41f982a7e2 100644 --- a/indra/llmessage/tests/lltrustedmessageservice_test.cpp +++ b/indra/llmessage/tests/lltrustedmessageservice_test.cpp @@ -33,8 +33,9 @@  #include "message.h"  #include "llmessageconfig.h"  #include "llhttpnode_stub.cpp" +#include "llpounceable.h" -LLMessageSystem* gMessageSystem = NULL; +LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;  LLMessageConfig::SenderTrust  LLMessageConfig::getSenderTrustedness(const std::string& msg_name) diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h index 5eb739393f..5986524342 100644 --- a/indra/llmessage/tests/networkio.h +++ b/indra/llmessage/tests/networkio.h @@ -44,7 +44,7 @@  // init time. Use the lazy, on-demand initialization we get from LLSingleton.  class NetworkIO: public LLSingleton<NetworkIO>  { -public: +    LLSINGLETON(NetworkIO);      NetworkIO():          mServicePump(NULL),          mDone(false) @@ -69,6 +69,7 @@ public:                                                         boost::bind(&NetworkIO::done, this, _1));      } +public:      bool pump(F32 timeout=10)      {          // Reset the done flag so we don't pop out prematurely diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py index bac18fa374..9cd2959ea1 100755 --- a/indra/llmessage/tests/test_llsdmessage_peer.py +++ b/indra/llmessage/tests/test_llsdmessage_peer.py @@ -31,7 +31,6 @@ $/LicenseInfo$  import os  import sys -from threading import Thread  from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler  from llbase.fastest_elementtree import parse as xml_parse @@ -155,17 +154,23 @@ class Server(HTTPServer):      allow_reuse_address = False  if __name__ == "__main__": -    # Instantiate a Server(TestHTTPRequestHandler) on the first free port -    # in the specified port range. Doing this inline is better than in a -    # daemon thread: if it blows up here, we'll get a traceback. If it blew up -    # in some other thread, the traceback would get eaten and we'd run the -    # subject test program anyway. -    httpd, port = freeport(xrange(8000, 8020), -                           lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler)) +    # function to make a server with specified port +    make_server = lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler) + +    if not sys.platform.startswith("win"): +        # Instantiate a Server(TestHTTPRequestHandler) on a port chosen by the +        # runtime. +        httpd = make_server(0) +    else: +        # "Then there's Windows" +        # Instantiate a Server(TestHTTPRequestHandler) on the first free port +        # in the specified port range. +        httpd, port = freeport(xrange(8000, 8020), make_server) +      # Pass the selected port number to the subject test program via the      # environment. We don't want to impose requirements on the test program's      # command-line parsing -- and anyway, for C++ integration tests, that's      # performed in TUT code rather than our own. -    os.environ["PORT"] = str(port) -    debug("$PORT = %s", port) -    sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), *sys.argv[1:])) +    os.environ["PORT"] = str(httpd.server_port) +    debug("$PORT = %s", httpd.server_port) +    sys.exit(run(server_inst=httpd, *sys.argv[1:])) diff --git a/indra/llmessage/tests/testrunner.py b/indra/llmessage/tests/testrunner.py index 5b9beb359b..c25945067e 100755 --- a/indra/llmessage/tests/testrunner.py +++ b/indra/llmessage/tests/testrunner.py @@ -27,13 +27,12 @@ Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA  $/LicenseInfo$  """ -from __future__ import with_statement -  import os  import sys  import re  import errno  import socket +import subprocess  VERBOSE = os.environ.get("INTEGRATION_TEST_VERBOSE", "0") # default to quiet  # Support usage such as INTEGRATION_TEST_VERBOSE=off -- distressing to user if @@ -47,6 +46,9 @@ if VERBOSE:  else:      debug = lambda *args: None +class Error(Exception): +    pass +  def freeport(portlist, expr):      """      Find a free server port to use. Specifically, evaluate 'expr' (a @@ -141,34 +143,73 @@ def freeport(portlist, expr):          raise  def run(*args, **kwds): -    """All positional arguments collectively form a command line, executed as -    a synchronous child process. -    In addition, pass server=new_thread_instance as an explicit keyword (to -    differentiate it from an additional command-line argument). -    new_thread_instance should be an instantiated but not yet started Thread -    subclass instance, e.g.: -    run("python", "-c", 'print "Hello, world!"', server=TestHTTPServer(name="httpd"))      """ -    # If there's no server= keyword arg, don't start a server thread: simply -    # run a child process. +    Run a specified command as a synchronous child process, optionally +    launching a server Thread during the run. + +    All positional arguments collectively form a command line. The first +    positional argument names the program file to execute. + +    Returns the termination code of the child process. + +    In addition, you may pass keyword-only arguments: + +    use_path=True: allow a simple filename as command and search PATH for that +    filename. (This argument is retained for backwards compatibility but is +    now the default behavior.) + +    server_inst: an instance of a subclass of SocketServer.BaseServer. + +    When you pass server_inst, run() calls its handle_request() method in a +    loop until the child process terminates. +    """ +    # server= keyword arg is discontinued      try:          thread = kwds.pop("server")      except KeyError:          pass      else: -        # Start server thread. Note that this and all other comm server -        # threads should be daemon threads: we'll let them run "forever," -        # confident that the whole process will terminate when the main thread -        # terminates, which will be when the child process terminates. -        thread.setDaemon(True) -        thread.start() -    # choice of os.spawnv(): -    # - [v vs. l] pass a list of args vs. individual arguments, -    # - [no p] don't use the PATH because we specifically want to invoke the -    #   executable passed as our first arg, -    # - [no e] child should inherit this process's environment. +        raise Error("Obsolete call to testrunner.run(): pass server_inst=, not server=") +      debug("Running %s...", " ".join(args)) -    rc = os.spawnv(os.P_WAIT, args[0], args) + +    try: +        server_inst = kwds.pop("server_inst") +    except KeyError: +        # Without server_inst, this is very simple: just run child process. +        rc = subprocess.call(args) +    else: +        # We're being asked to run a local server while the child process +        # runs. We used to launch a daemon thread calling +        # server_inst.serve_forever(), then eventually call sys.exit() with +        # the daemon thread still running -- but in recent versions of Python +        # 2, even when you call sys.exit(0), apparently killing the thread +        # causes the Python runtime to force the process termination code +        # nonzero. So now we avoid the extra thread altogether. + +        # SocketServer.BaseServer.handle_request() honors a 'timeout' +        # attribute, if it's set to something other than None. +        # We pick 0.5 seconds because that's the default poll timeout for +        # BaseServer.serve_forever(), which is what we used to use. +        server_inst.timeout = 0.5 + +        child = subprocess.Popen(args) +        while child.poll() is None: +            # Setting server_inst.timeout is what keeps this handle_request() +            # call from blocking "forever." Interestingly, looping over +            # handle_request() with a timeout is very like the implementation +            # of serve_forever(). We just check a different flag to break out. +            # It might be interesting if handle_request() returned an +            # indication of whether it in fact handled a request or timed out. +            # Oddly, it doesn't. We could discover that by overriding +            # handle_timeout(), whose default implementation does nothing -- +            # but in fact we really don't care. All that matters is that we +            # regularly poll both the child process and the server socket. +            server_inst.handle_request() +        # We don't bother to capture the rc returned by child.poll() because +        # poll() is already defined to capture that in its returncode attr. +        rc = child.returncode +      debug("%s returned %s", args[0], rc)      return rc | 
