leslie_linden avatar leslie_linden committed fb8c30e Merge

Merge from viewer-experience-merge

Comments (0)

Files changed (28)

doc/contributions.txt

 	VWR-24917
 Argent Stonecutter
 	VWR-68
+ArminWeatherHax
+	STORM-1532
 Armin Weatherwax
 	VWR-8436
 ArminasX Saiman
 	STORM-1276
 	STORM-1462
 	STORM-1459
+	STORM-1297
 	STORM-1522
 	STORM-1567
 	STORM-1572

indra/llcommon/CMakeLists.txt

   LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}"
                           "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/setpython.py")
+  LL_ADD_INTEGRATION_TEST(llsingleton "" "${test_libs}")                          
   LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")

indra/llcommon/llinstancetracker.cpp

 //static 
 void * & LLInstanceTrackerBase::getInstances(std::type_info const & info)
 {
-	static std::map<std::string, void *> instances;
+	typedef std::map<std::string, void *> InstancesMap;
+	static InstancesMap instances;
 
-	std::string k = info.name();
-	if(instances.find(k) == instances.end())
-	{
-		instances[k] = NULL;
-	}
-
-	return instances[k];
+	// std::map::insert() is just what we want here. You attempt to insert a
+	// (key, value) pair. If the specified key doesn't yet exist, it inserts
+	// the pair and returns a std::pair of (iterator, true). If the specified
+	// key DOES exist, insert() simply returns (iterator, false). One lookup
+	// handles both cases.
+	return instances.insert(InstancesMap::value_type(info.name(),
+													 InstancesMap::mapped_type()))
+		.first->second;
 }
-

indra/llcommon/llinstancetracker.h

 #define LL_LLINSTANCETRACKER_H
 
 #include <map>
+#include <typeinfo>
 
 #include "string_table.h"
 #include <boost/utility.hpp>
 #include <boost/iterator/transform_iterator.hpp>
 #include <boost/iterator/indirect_iterator.hpp>
 
+/**
+ * Base class manages "class-static" data that must actually have singleton
+ * semantics: one instance per process, rather than one instance per module as
+ * sometimes happens with data simply declared static.
+ */
 class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
 {
-	protected:
-		static void * & getInstances(std::type_info const & info);
+protected:
+	/// Get a process-unique void* pointer slot for the specified type_info
+	static void * & getInstances(std::type_info const & info);
+
+	/// Find or create a STATICDATA instance for the specified TRACKED class.
+	/// STATICDATA must be default-constructible.
+	template<typename STATICDATA, class TRACKED>
+	static STATICDATA& getStatic()
+	{
+		void *& instances = getInstances(typeid(TRACKED));
+		if (! instances)
+		{
+			instances = new STATICDATA;
+		}
+		return *static_cast<STATICDATA*>(instances);
+	}
+
+    /// It's not essential to derive your STATICDATA (for use with
+    /// getStatic()) from StaticBase; it's just that both known
+    /// implementations do.
+    struct StaticBase
+    {
+        StaticBase():
+            sIterationNestDepth(0)
+        {}
+        S32 sIterationNestDepth;
+    };
 };
 
 /// This mix-in class adds support for tracking all instances of the specified class parameter T
 template<typename T, typename KEY = T*>
 class LLInstanceTracker : public LLInstanceTrackerBase
 {
+	typedef LLInstanceTracker<T, KEY> MyT;
 	typedef typename std::map<KEY, T*> InstanceMap;
-	typedef LLInstanceTracker<T, KEY> MyT;
+	struct StaticData: public StaticBase
+	{
+		InstanceMap sMap;
+	};
+	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+	static InstanceMap& getMap_() { return getStatic().sMap; }
+
 public:
 	class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
 	{
 		instance_iter(const typename InstanceMap::iterator& it)
 		:	mIterator(it)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		~instance_iter()
 		{
-			--sIterationNestDepth;
+			--getStatic().sIterationNestDepth;
 		}
 
 
 		key_iter(typename InstanceMap::iterator it)
 			:	mIterator(it)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		key_iter(const key_iter& other)
 			:	mIterator(other.mIterator)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		~key_iter()
 		{
-			--sIterationNestDepth;
+			--getStatic().sIterationNestDepth;
 		}
 
 
 	virtual ~LLInstanceTracker() 
 	{ 
 		// it's unsafe to delete instances of this type while all instances are being iterated over.
-		llassert(sIterationNestDepth == 0);
-		remove_(); 		
+		llassert_always(getStatic().sIterationNestDepth == 0);
+		remove_();		
 	}
 	virtual void setKey(KEY key) { remove_(); add_(key); }
 	virtual const KEY& getKey() const { return mInstanceKey; }
 		getMap_().erase(mInstanceKey);
 	}
 
-    static InstanceMap& getMap_()
-    {
-		void * & instances = getInstances(typeid(MyT));
-        if (! instances)
-        {
-            instances = new InstanceMap;
-        }
-        return * static_cast<InstanceMap*>(instances);
-    }
-
 private:
-
 	KEY mInstanceKey;
-	static S32 sIterationNestDepth;
 };
 
-template <typename T, typename KEY> S32 LLInstanceTracker<T, KEY>::sIterationNestDepth = 0;
-
 /// explicit specialization for default case where KEY is T*
 /// use a simple std::set<T*>
 template<typename T>
 class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
 {
+	typedef LLInstanceTracker<T, T*> MyT;
 	typedef typename std::set<T*> InstanceSet;
-	typedef LLInstanceTracker<T, T*> MyT;
+	struct StaticData: public StaticBase
+	{
+		InstanceSet sSet;
+	};
+	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+	static InstanceSet& getSet_() { return getStatic().sSet; }
+
 public:
 
 	/// for completeness of analogy with the generic implementation
 		instance_iter(const typename InstanceSet::iterator& it)
 		:	mIterator(it)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		instance_iter(const instance_iter& other)
 		:	mIterator(other.mIterator)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		~instance_iter()
 		{
-			--sIterationNestDepth;
+			--getStatic().sIterationNestDepth;
 		}
 
 	private:
 protected:
 	LLInstanceTracker()
 	{
-		// it's safe but unpredictable to create instances of this type while all instances are being iterated over.  I hate unpredictable.  This assert will probably be turned on early in the next development cycle.
+		// it's safe but unpredictable to create instances of this type while all instances are being iterated over.  I hate unpredictable.	 This assert will probably be turned on early in the next development cycle.
 		getSet_().insert(static_cast<T*>(this));
 	}
 	virtual ~LLInstanceTracker()
 	{
 		// it's unsafe to delete instances of this type while all instances are being iterated over.
-		llassert(sIterationNestDepth == 0);
+		llassert_always(getStatic().sIterationNestDepth == 0);
 		getSet_().erase(static_cast<T*>(this));
 	}
 
 	{
 		getSet_().insert(static_cast<T*>(this));
 	}
-
-	static InstanceSet& getSet_()
-	{
-		void * & instances = getInstances(typeid(MyT));
-		if (! instances)
-		{
-			instances = new InstanceSet;
-		}
-		return * static_cast<InstanceSet *>(instances);
-	}
-
-	static S32 sIterationNestDepth;
 };
 
-template <typename T> S32 LLInstanceTracker<T, T*>::sIterationNestDepth = 0;
-
 #endif

indra/llcommon/llsingleton.h

 
 		~SingletonInstanceData()
 		{
-			SingletonInstanceData& data = getData();
-			if (data.mInitState != DELETED)
+			if (mInitState != DELETED)
 			{
 				deleteSingleton();
 			}
 		data.mInitState = DELETED;
 	}
 
-	// Can be used to control when the singleton is deleted.  Not normally needed.
+	/**
+	 * @brief Immediately delete the singleton.
+	 *
+	 * A subsequent call to LLProxy::getInstance() will construct a new
+	 * instance of the class.
+	 *
+	 * LLSingletons are normally destroyed after main() has exited and the C++
+	 * runtime is cleaning up statically-constructed objects. Some classes
+	 * derived from LLSingleton have objects that are part of a runtime system
+	 * that is terminated before main() exits. Calling the destructor of those
+	 * objects after the termination of their respective systems can cause
+	 * crashes and other problems during termination of the project. Using this
+	 * method to destroy the singleton early can prevent these crashes.
+	 *
+	 * An example where this is needed is for a LLSingleton that has an APR
+	 * object as a member that makes APR calls on destruction. The APR system is
+	 * shut down explicitly before main() exits. This causes a crash on exit.
+	 * Using this method before the call to apr_terminate() and NOT calling
+	 * getInstance() again will prevent the crash.
+	 */
 	static void deleteSingleton()
 	{
 		delete getData().mSingletonInstance;

indra/llcommon/tests/llinstancetracker_test.cpp

 #include <boost/scoped_ptr.hpp>
 // other Linden headers
 #include "../test/lltut.h"
+#include "wrapllerrs.h"
 
 struct Keyed: public LLInstanceTracker<Keyed, std::string>
 {
 
         ensure_equals("unreported instance", instances.size(), 0);
     }
+
+    template<> template<>
+    void object::test<5>()
+    {
+        set_test_name("delete Keyed with outstanding instance_iter");
+        std::string what;
+        Keyed* keyed = new Keyed("one");
+        {
+            WrapLL_ERRS wrapper;
+            Keyed::instance_iter i(Keyed::beginInstances());
+            try
+            {
+                delete keyed;
+            }
+            catch (const WrapLL_ERRS::FatalException& e)
+            {
+                what = e.what();
+            }
+        }
+        ensure(! what.empty());
+    }
+
+    template<> template<>
+    void object::test<6>()
+    {
+        set_test_name("delete Keyed with outstanding key_iter");
+        std::string what;
+        Keyed* keyed = new Keyed("one");
+        {
+            WrapLL_ERRS wrapper;
+            Keyed::key_iter i(Keyed::beginKeys());
+            try
+            {
+                delete keyed;
+            }
+            catch (const WrapLL_ERRS::FatalException& e)
+            {
+                what = e.what();
+            }
+        }
+        ensure(! what.empty());
+    }
+
+    template<> template<>
+    void object::test<7>()
+    {
+        set_test_name("delete Unkeyed with outstanding instance_iter");
+        std::string what;
+        Unkeyed* unkeyed = new Unkeyed;
+        {
+            WrapLL_ERRS wrapper;
+            Unkeyed::instance_iter i(Unkeyed::beginInstances());
+            try
+            {
+                delete unkeyed;
+            }
+            catch (const WrapLL_ERRS::FatalException& e)
+            {
+                what = e.what();
+            }
+        }
+        ensure(! what.empty());
+    }
 } // namespace tut

indra/llcommon/tests/llsingleton_test.cpp

+/** 
+ * @file llsingleton_test.cpp
+ * @date 2011-08-11
+ * @brief Unit test for the LLSingleton class
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llsingleton.h"
+#include "../test/lltut.h"
+
+namespace tut
+{
+	struct singleton
+	{
+		// We need a class created with the LLSingleton template to test with.
+		class LLSingletonTest: public LLSingleton<LLSingletonTest>
+		{
+
+		};
+	};
+
+	typedef test_group<singleton> singleton_t;
+	typedef singleton_t::object singleton_object_t;
+	tut::singleton_t tut_singleton("LLSingleton");
+
+	template<> template<>
+	void singleton_object_t::test<1>()
+	{
+
+	}
+	template<> template<>
+	void singleton_object_t::test<2>()
+	{
+		LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
+		ensure(singleton_test);
+	}
+	template<> template<>
+	void singleton_object_t::test<3>()
+	{
+		//Construct the instance
+		LLSingletonTest::getInstance();
+		ensure(LLSingletonTest::instanceExists());
+
+		//Delete the instance
+		LLSingletonTest::deleteSingleton();
+		ensure(LLSingletonTest::destroyed());
+		ensure(!LLSingletonTest::instanceExists());
+
+		//Construct it again.
+		LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
+		ensure(singleton_test);
+		ensure(LLSingletonTest::instanceExists());
+	}
+}

indra/llmessage/llcurl.cpp

 	
 	//don't verify host name so urls with scrubbed host names will work (improves DNS performance)
 	setopt(CURLOPT_SSL_VERIFYHOST, 0);
-	setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT);
+	setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT));
 
 	setoptString(CURLOPT_URL, url);
 
 }
 
 const unsigned int LLCurl::MAX_REDIRECTS = 5;
+
+// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
+void LLCurlFF::check_easy_code(CURLcode code)
+{
+	check_curl_code(code);
+}
+void LLCurlFF::check_multi_code(CURLMcode code)
+{
+	check_curl_multi_code(code);
+}

indra/llmessage/llcurl.h

 	bool mResultReturned;
 };
 
-void check_curl_code(CURLcode code);
-void check_curl_multi_code(CURLMcode code);
+// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
+namespace LLCurlFF
+{
+	void check_easy_code(CURLcode code);
+	void check_multi_code(CURLMcode code);
+}
 
 #endif // LL_LLCURL_H

indra/llmessage/llpacketring.cpp

 		if (LLProxy::isSOCKSProxyEnabled())
 		{
 			U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
-			packet_size = receive_packet(socket, reinterpret_cast<char *>(buffer));
+			packet_size = receive_packet(socket, static_cast<char*>(static_cast<void*>(buffer)));
 			
 			if (packet_size > SOCKS_HEADER_SIZE)
 			{
 				// *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6)
 				memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size - SOCKS_HEADER_SIZE);
-				proxywrap_t * header = reinterpret_cast<proxywrap_t *>(buffer);
+				proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer));
 				mLastSender.setAddress(header->addr);
 				mLastSender.setPort(ntohs(header->port));
 
 		return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort());
 	}
 
-	proxywrap_t *socks_header = reinterpret_cast<proxywrap_t *>(&mProxyWrappedSendBuffer);
+	char headered_send_buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
+
+	proxywrap_t *socks_header = static_cast<proxywrap_t*>(static_cast<void*>(&headered_send_buffer));
 	socks_header->rsv   = 0;
 	socks_header->addr  = host.getAddress();
 	socks_header->port  = htons(host.getPort());
 	socks_header->atype = ADDRESS_IPV4;
 	socks_header->frag  = 0;
 
-	memcpy(mProxyWrappedSendBuffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
+	memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
 
-	return send_packet(h_socket, (const char*) mProxyWrappedSendBuffer, buf_size + 10, LLProxy::getInstance()->getUDPProxy().getAddress(), LLProxy::getInstance()->getUDPProxy().getPort());
+	return send_packet(	h_socket,
+						headered_send_buffer,
+						buf_size + SOCKS_HEADER_SIZE,
+						LLProxy::getInstance()->getUDPProxy().getAddress(),
+						LLProxy::getInstance()->getUDPProxy().getPort());
 }

indra/llmessage/llpacketring.h

 	LLHost mLastSender;
 	LLHost mLastReceivingIF;
 
-
-	U8 mProxyWrappedSendBuffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
-
 private:
 	BOOL sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host);
 };

indra/llmessage/llproxy.cpp

 bool LLProxy::sUDPProxyEnabled = false;
 
 // Some helpful TCP static functions.
-static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
+static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
 static LLSocket::ptr_t tcp_open_channel(LLHost host); // Open a TCP channel to a given host
 static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP channel
 
 LLProxy::~LLProxy()
 {
 	stopSOCKSProxy();
-	sUDPProxyEnabled  = false;
-	mHTTPProxyEnabled = false;
+	disableHTTPProxy();
 }
 
 /**
  * @brief Open the SOCKS 5 TCP control channel.
  *
- * Perform a SOCKS 5 authentication and UDP association to the proxy server.
+ * Perform a SOCKS 5 authentication and UDP association with the proxy server.
  *
  * @param proxy The SOCKS 5 server to connect to.
  * @return SOCKS_OK if successful, otherwise a socks error code from llproxy.h.
 	socks_auth_request_t  socks_auth_request;
 	socks_auth_response_t socks_auth_response;
 
-	socks_auth_request.version     = SOCKS_VERSION;       // SOCKS version 5
-	socks_auth_request.num_methods = 1;                   // Sending 1 method.
-	socks_auth_request.methods     = getSelectedAuthMethod(); // Send only the selected method.
+	socks_auth_request.version		= SOCKS_VERSION;				// SOCKS version 5
+	socks_auth_request.num_methods	= 1;							// Sending 1 method.
+	socks_auth_request.methods		= getSelectedAuthMethod();		// Send only the selected method.
 
-	result = tcp_handshake(mProxyControlChannel, (char*)&socks_auth_request, sizeof(socks_auth_request), (char*)&socks_auth_response, sizeof(socks_auth_response));
+	result = tcp_blocking_handshake(mProxyControlChannel,
+									static_cast<char*>(static_cast<void*>(&socks_auth_request)),
+									sizeof(socks_auth_request),
+									static_cast<char*>(static_cast<void*>(&socks_auth_response)),
+									sizeof(socks_auth_response));
 	if (result != APR_SUCCESS)
 	{
 		LL_WARNS("Proxy") << "SOCKS authentication request failed, error on TCP control channel : " << result << LL_ENDL;
 
 	if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE)
 	{
-		LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods" << LL_ENDL;
+		LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods." << LL_ENDL;
 		stopSOCKSProxy();
 		return SOCKS_NOT_ACCEPTABLE;
 	}
 
-	// SOCKS 5 USERNAME/PASSWORD authentication
+	/* SOCKS 5 USERNAME/PASSWORD authentication */
 	if (socks_auth_response.method == METHOD_PASSWORD)
 	{
 		// The server has requested a username/password combination
 		password_auth[1] = socks_username.size();
 		memcpy(&password_auth[2], socks_username.c_str(), socks_username.size());
 		password_auth[socks_username.size() + 2] = socks_password.size();
-		memcpy(&password_auth[socks_username.size()+3], socks_password.c_str(), socks_password.size());
+		memcpy(&password_auth[socks_username.size() + 3], socks_password.c_str(), socks_password.size());
 
 		authmethod_password_reply_t password_reply;
 
-		result = tcp_handshake(mProxyControlChannel, password_auth, request_size, (char*)&password_reply, sizeof(password_reply));
+		result = tcp_blocking_handshake(mProxyControlChannel,
+										password_auth,
+										request_size,
+										static_cast<char*>(static_cast<void*>(&password_reply)),
+										sizeof(password_reply));
 		delete[] password_auth;
 
 		if (result != APR_SUCCESS)
 	// "If the client is not in possession of the information at the time of the UDP ASSOCIATE,
 	//  the client MUST use a port number and address of all zeros. RFC 1928"
 
-	result = tcp_handshake(mProxyControlChannel, (char*)&connect_request, sizeof(connect_request), (char*)&connect_reply, sizeof(connect_reply));
+	result = tcp_blocking_handshake(mProxyControlChannel,
+									static_cast<char*>(static_cast<void*>(&connect_request)),
+									sizeof(connect_request),
+									static_cast<char*>(static_cast<void*>(&connect_reply)),
+									sizeof(connect_reply));
 	if (result != APR_SUCCESS)
 	{
 		LL_WARNS("Proxy") << "SOCKS connect request failed, error on TCP control channel : " << result << LL_ENDL;
 	mUDPProxy.setAddress(proxy.getAddress());
 	// The connection was successful. We now have the UDP port to send requests that need forwarding to.
 	LL_INFOS("Proxy") << "SOCKS 5 UDP proxy connected on " << mUDPProxy << LL_ENDL;
+
 	return SOCKS_OK;
 }
 
  * @brief Initiates a SOCKS 5 proxy session.
  *
  * Performs basic checks on host to verify that it is a valid address. Opens the control channel
- * and then negotiates the proxy connection with the server.
+ * and then negotiates the proxy connection with the server. Closes any existing SOCKS
+ * connection before proceeding. Also disables an HTTP proxy if it is using SOCKS as the proxy.
  *
  *
  * @param host Socks server to connect to.
  */
 S32 LLProxy::startSOCKSProxy(LLHost host)
 {
-	S32 status = SOCKS_OK;
-
 	if (host.isOk())
 	{
 		mTCPProxy = host;
 	}
 	else
 	{
-		status = SOCKS_INVALID_HOST;
+		return SOCKS_INVALID_HOST;
 	}
 
-	if (mProxyControlChannel && status == SOCKS_OK)
+	// Close any running SOCKS connection.
+	stopSOCKSProxy();
+
+	mProxyControlChannel = tcp_open_channel(mTCPProxy);
+	if (!mProxyControlChannel)
 	{
-		tcp_close_channel(&mProxyControlChannel);
+		return SOCKS_HOST_CONNECT_FAILED;
 	}
 
-	if (status == SOCKS_OK)
+	S32 status = proxyHandshake(mTCPProxy);
+
+	if (status != SOCKS_OK)
 	{
-		mProxyControlChannel = tcp_open_channel(mTCPProxy);
-		if (!mProxyControlChannel)
-		{
-			status = SOCKS_HOST_CONNECT_FAILED;
-		}
-	}
-
-	if (status == SOCKS_OK)
-	{
-		status = proxyHandshake(mTCPProxy);
-	}
-	if (status == SOCKS_OK)
-	{
-		sUDPProxyEnabled = true;
+		// Shut down the proxy if any of the above steps failed.
+		stopSOCKSProxy();
 	}
 	else
 	{
-		stopSOCKSProxy();
+		// Connection was successful.
+		sUDPProxyEnabled = true;
 	}
+
 	return status;
 }
 
 
 	if (LLPROXY_SOCKS == getHTTPProxyType())
 	{
-		void disableHTTPProxy();
+		disableHTTPProxy();
 	}
 
 	if (mProxyControlChannel)
 }
 
 /**
- * @brief Get the HTTP proxy address and port
- */
-//
-LLHost LLProxy::getHTTPProxy() const
-{
-	LLMutexLock lock(&mProxyMutex);
-	return mHTTPProxy;
-}
-
-/**
  * @brief Get the currently selected HTTP proxy type
  */
 LLHttpProxyType LLProxy::getHTTPProxyType() const
 		// Now test again to verify that the proxy wasn't disabled between the first check and the lock.
 		if (mHTTPProxyEnabled)
 		{
-			check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()));
-			check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()));
+			LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()));
+			LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()));
 
 			if (mProxyType == LLPROXY_SOCKS)
 			{
-				check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
+				LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
 				if (mAuthMethodSelected == METHOD_PASSWORD)
 				{
 					std::string auth_string = mSocksUsername + ":" + mSocksPassword;
-					check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()));
+					LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()));
 				}
 			}
 			else
 			{
-				check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
+				LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
 			}
 		}
 	}
  * @param maxinlen		Maximum possible length of received data.  Short reads are allowed.
  * @return 				Indicates APR status code of exchange. APR_SUCCESS if exchange was successful, -1 if invalid data length was received.
  */
-static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
+static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
 {
 	apr_socket_t* apr_socket = handle->getSocket();
 	apr_status_t rv = APR_SUCCESS;
  *
  * Checks for a successful connection, and makes sure the connection is closed if it fails.
  *
- * @param pool		APR pool to pass into the LLSocket.
  * @param host		The host to open the connection to.
  * @return			The created socket.  Will evaluate as NULL if the connection is unsuccessful.
  */
 /**
  * @brief Close the socket.
  *
- * @param handle_ptr A pointer-to-pointer to avoid increasing the use count.
+ * @param handle_ptr The handle of the socket being closed. A pointer-to-pointer to avoid increasing the use count.
  */
 static void tcp_close_channel(LLSocket::ptr_t* handle_ptr)
 {

indra/llmessage/llproxy.h

 #include <string>
 
 // SOCKS error codes returned from the StartProxy method
-
 #define SOCKS_OK 0
 #define SOCKS_CONNECT_ERROR (-1)
 #define SOCKS_NOT_PERMITTED (-2)
 #define SOCKS_HOST_CONNECT_FAILED (-6)
 #define SOCKS_INVALID_HOST (-7)
 
-
 #ifndef MAXHOSTNAMELEN
 #define	MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */
 #endif
 {
 	LOG_CLASS(LLProxy);
 public:
-	// METHODS THAT DO NOT LOCK mProxyMutex!
-
+	/*###########################################################################################
+	METHODS THAT DO NOT LOCK mProxyMutex!
+	###########################################################################################*/
+	// Constructor, cannot have parameters due to LLSingleton parent class. Call from main thread only.
 	LLProxy();
 
-	// static check for enabled status for UDP packets
+	// Static check for enabled status for UDP packets. Call from main thread only.
 	static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; }
 
-	// check for enabled status for HTTP packets
-	// mHTTPProxyEnabled is atomic, so no locking is required for thread safety.
-	bool isHTTPProxyEnabled() const { return mHTTPProxyEnabled; }
-
-	// Get the UDP proxy address and port
+	// Get the UDP proxy address and port. Call from main thread only.
 	LLHost getUDPProxy() const { return mUDPProxy; }
 
-	// Get the SOCKS 5 TCP control channel address and port
-	LLHost getTCPProxy() const { return mTCPProxy; }
+	/*###########################################################################################
+	END OF NON-LOCKING METHODS
+	###########################################################################################*/
 
-	// END OF NON-LOCKING METHODS
-
-	// METHODS THAT DO LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
-
+	/*###########################################################################################
+	METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
+	###########################################################################################*/
+	// Destructor, closes open connections. Do not call directly, use cleanupClass().
 	~LLProxy();
 
-	// Start a connection to the SOCKS 5 proxy
-	S32 startSOCKSProxy(LLHost host);
-
-	// Disconnect and clean up any connection to the SOCKS 5 proxy
-	void stopSOCKSProxy();
-
-	// Delete LLProxy singleton, destroying the APR pool used by the control channel.
+	// 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();
 
-	// Set up to use Password auth when connecting to the SOCKS proxy
-	bool setAuthPassword(const std::string &username, const std::string &password);
-
-	// Set up to use No Auth when connecting to the SOCKS proxy
-	void setAuthNone();
-
-	// Get the currently selected auth method.
-	LLSocks5AuthType getSelectedAuthMethod() const;
-
-	// Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy
-	// as specified in type
-	bool enableHTTPProxy(LLHost httpHost, LLHttpProxyType type);
-	bool enableHTTPProxy();
-
-	// Stop proxying HTTP packets
-	void disableHTTPProxy();
-
 	// Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false.
+	// Safe to call from any thread.
 	void applyProxySettings(CURL* handle);
 	void applyProxySettings(LLCurl::Easy* handle);
 	void applyProxySettings(LLCurlEasyRequest* handle);
 
-	// Get the HTTP proxy address and port
-	LLHost getHTTPProxy() const;
+	// Start a connection to the SOCKS 5 proxy. Call from main thread only.
+	S32 startSOCKSProxy(LLHost host);
+
+	// Disconnect and clean up any connection to the SOCKS 5 proxy. Call from main thread only.
+	void stopSOCKSProxy();
+
+	// Use Password auth when connecting to the SOCKS proxy. Call from main thread only.
+	bool setAuthPassword(const std::string &username, const std::string &password);
+
+	// Disable authentication when connecting to the SOCKS proxy. Call from main thread only.
+	void setAuthNone();
+
+	// Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy.
+	// as specified in type. Call from main thread only.
+	bool enableHTTPProxy(LLHost httpHost, LLHttpProxyType type);
+	bool enableHTTPProxy();
+
+	// Stop proxying HTTP packets. Call from main thread only.
+	void disableHTTPProxy();
+
+	/*###########################################################################################
+	END OF LOCKING METHODS
+	###########################################################################################*/
+private:
+	/*###########################################################################################
+	METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
+	###########################################################################################*/
+
+	// Perform a SOCKS 5 authentication and UDP association with the proxy server.
+	S32 proxyHandshake(LLHost proxy);
+
+	// Get the currently selected auth method.
+	LLSocks5AuthType getSelectedAuthMethod() const;
 
 	// Get the currently selected HTTP proxy type
 	LLHttpProxyType getHTTPProxyType() const;
 	std::string getSocksPwd() const;
 	std::string getSocksUser() const;
 
-	// END OF LOCKING METHODS
-private:
-	// Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort
-	S32 proxyHandshake(LLHost proxy);
+	/*###########################################################################################
+	END OF LOCKING METHODS
+	###########################################################################################*/
 
 private:
-	// Is the HTTP proxy enabled?
-	// Safe to read in any thread, do not write directly,
-	// use enableHTTPProxy() and disableHTTPProxy() instead.
+	// Is the HTTP proxy enabled? Safe to read in any thread, but do not write directly.
+	// Instead use enableHTTPProxy() and disableHTTPProxy() instead.
 	mutable LLAtomic32<bool> mHTTPProxyEnabled;
 
-	// Mutex to protect shared members in non-main thread calls to applyProxySettings()
+	// Mutex to protect shared members in non-main thread calls to applyProxySettings().
 	mutable LLMutex mProxyMutex;
 
-	// MEMBERS READ AND WRITTEN ONLY IN THE MAIN THREAD. DO NOT SHARE!
+	/*###########################################################################################
+	MEMBERS READ AND WRITTEN ONLY IN THE MAIN THREAD. DO NOT SHARE!
+	###########################################################################################*/
 
 	// Is the UDP proxy enabled?
 	static bool sUDPProxyEnabled;
 	// socket handle to proxy TCP control channel
 	LLSocket::ptr_t mProxyControlChannel;
 
-	// END OF UNSHARED MEMBERS
+	/*###########################################################################################
+	END OF UNSHARED MEMBERS
+	###########################################################################################*/
 
-	// MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex!
+	/*###########################################################################################
+	MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex!
+	###########################################################################################*/
 
 	// HTTP proxy address and port
 	LLHost mHTTPProxy;
 	// Currently selected HTTP proxy type. Can be web or socks.
 	LLHttpProxyType mProxyType;
 
-	// SOCKS 5 auth method selected
+	// SOCKS 5 selected authentication method.
 	LLSocks5AuthType mAuthMethodSelected;
 
 	// SOCKS 5 username
 	// SOCKS 5 password
 	std::string mSocksPassword;
 
-	// END OF SHARED MEMBERS
+	/*###########################################################################################
+	END OF SHARED MEMBERS
+	###########################################################################################*/
 };
 
 #endif

indra/newview/app_settings/settings.xml

     <key>Type</key>
     <string>Boolean</string>
     <key>Value</key>
-    <integer>0</integer>
+    <integer>1</integer>
   </map>
     <key>Cursor3D</key>
     <map>
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>http://search.secondlife.com/viewer/[CATEGORY]/?q=[QUERY]</string>
+      <string>http://search.secondlife.com/viewer/[CATEGORY]/?q=[QUERY]&amp;p=[AUTH_TOKEN]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
     </map>
     <key>WebProfileURL</key>
     <map>

indra/newview/llappviewer.cpp

 		&LLUI::sGLScaleFactor);
 	LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
 
+	// Setup paths and LLTrans after LLUI::initClass has been called.
+	LLUI::setupPaths();
+	LLTransUtil::parseStrings("strings.xml", default_trans_args);
+	LLTransUtil::parseLanguageStrings("language_settings.xml");
+
+	// Setup notifications after LLUI::setupPaths() has been called.
 	LLNotifications::instance();
 	LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ;
 
 		LLError::setPrintLocation(true);
 	}
 
-
-	// Setup paths and LLTrans after LLUI::initClass has been called
-	LLUI::setupPaths();
-	LLTransUtil::parseStrings("strings.xml", default_trans_args);		
-	LLTransUtil::parseLanguageStrings("language_settings.xml");
-	
 	// LLKeyboard relies on LLUI to know what some accelerator keys are called.
 	LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString );
 

indra/newview/llbottomtray.cpp

 };
 
 LLBottomTray::LLBottomTray(const LLSD&)
-:	mChicletPanel(NULL),
+:	mDesiredNearbyChatWidth(0),
+	mChicletPanel(NULL),
 	mSpeakPanel(NULL),
 	mSpeakBtn(NULL),
 	mNearbyChatBar(NULL),
 	if (still_should_be_processed)
 	{
 		processShrinkButtons(delta_width, buttons_freed_width);
+		still_should_be_processed = delta_width < 0;
 	}
+
 	// 3. Decreasing width of nearby chat.
 	const S32 chatbar_panel_min_width = get_panel_min_width(mToolbarStack, mChatBarContainer);
 	const S32 chatbar_panel_width = mChatBarContainer->getRect().getWidth();
 	if (still_should_be_processed && chatbar_panel_width > chatbar_panel_min_width)
 	{
 		// we have some space to decrease chatbar panel
-		S32 panel_delta_min = chatbar_panel_width - chatbar_panel_min_width;
+		S32 chatbar_shrink_headroom = chatbar_panel_width - chatbar_panel_min_width;
 
-		S32 delta_panel = llmin(-delta_width, panel_delta_min);
+		S32 shrink_by = llmin(-delta_width, chatbar_shrink_headroom);
 
 		// is chatbar panel wide enough to process resizing?
-		delta_width += panel_delta_min;
+		delta_width += chatbar_shrink_headroom;
 
 		still_should_be_processed = delta_width < 0;
 
 		// chatbar should only be shrunk here, not stretched
-		if(delta_panel > 0)
+		if (shrink_by > 0)
 		{
-			lldebugs << "Shrinking nearby chat bar by " << delta_panel << " px " << llendl;
-			mChatBarContainer->reshape(mNearbyChatBar->getRect().getWidth() - delta_panel, mChatBarContainer->getRect().getHeight());
+			lldebugs << "Shrinking nearby chat bar by " << shrink_by << " px " << llendl;
+			mChatBarContainer->reshape(mNearbyChatBar->getRect().getWidth() - shrink_by, mChatBarContainer->getRect().getHeight());
 		}
 
 		log(mNearbyChatBar, "after processing panel decreasing via nearby chatbar panel");
 
 		lldebugs << "RS_CHATBAR_INPUT"
-			<< ", delta_panel: " << delta_panel
+			<< ", shrink_by: " << shrink_by
 			<< ", delta_width: " << delta_width
 			<< llendl;
 	}
 		<< ", mDesiredNearbyChatWidth = " << mDesiredNearbyChatWidth << llendl;
 	if (delta_width > 0 && chatbar_panel_width < mDesiredNearbyChatWidth)
 	{
-		S32 delta_panel_max = mDesiredNearbyChatWidth - chatbar_panel_width;
-		S32 delta_panel = llmin(delta_width, delta_panel_max);
-		lldebugs << "Unprocesed delta width: " << delta_width
-			<< ", can be applied to chatbar: " << delta_panel_max
-			<< ", will be applied: " << delta_panel
+		S32 extend_by_max = mDesiredNearbyChatWidth - chatbar_panel_width;
+		S32 extend_by = llmin(delta_width, extend_by_max);
+		lldebugs << "Unprocessed delta width: " << delta_width
+			<< " px, chatbar can be extended by " << extend_by_max
+			<< " px, extending it by " << extend_by << " px"
 			<< llendl;
 
-		delta_width -= delta_panel_max;
-		lldebugs << "Extending nearby chat bar by " << delta_panel << " px " << llendl;
-		mChatBarContainer->reshape(chatbar_panel_width + delta_panel, mChatBarContainer->getRect().getHeight());
+		delta_width -= extend_by_max;
+		lldebugs << "Extending nearby chat bar by " << extend_by << " px " << llendl;
+		mChatBarContainer->reshape(chatbar_panel_width + extend_by, mChatBarContainer->getRect().getHeight());
 		log(mNearbyChatBar, "applied unprocessed delta width");
 	}
 

indra/newview/llbottomtray.h

 	void processExtendButtons(S32& available_width);
 
 	/**
-	 * Extends the Speak button if there is anough headroom.
+	 * Extends the Speak button if there is enough headroom.
 	 *
 	 * Unlike other buttons, the Speak buttons has only two possible widths:
 	 * the minimal one (without label) and the maximal (default) one.

indra/newview/llfloatersearch.cpp

 
 #include "llviewerprecompiledheaders.h"
 
-#include "llappviewer.h"
-#include "llbase64.h"
 #include "llcommandhandler.h"
 #include "llfloaterreg.h"
 #include "llfloatersearch.h"
 #include "llmediactrl.h"
 #include "llnotificationsutil.h"
-#include "llparcel.h"
-#include "llplugincookiestore.h"
 #include "lllogininstance.h"
 #include "lluri.h"
 #include "llagent.h"
-#include "llsdserialize.h"
 #include "llui.h"
 #include "llviewercontrol.h"
-#include "llviewerregion.h"
-#include "llversioninfo.h"
-#include "llviewermedia.h"
-#include "llviewernetwork.h"
-#include "llviewerparcelmgr.h"
 #include "llweb.h"
 
 // support secondlife:///app/search/{CATEGORY}/{QUERY} SLapps
 
 	// add the permissions token that login.cgi gave us
 	// We use "search_token", and fallback to "auth_token" if not present.
-	LLSD search_cookie;
-
 	LLSD search_token = LLLoginInstance::getInstance()->getResponse("search_token");
 	if (search_token.asString().empty())
 	{
 		search_token = LLLoginInstance::getInstance()->getResponse("auth_token");
 	}
-	search_cookie["AUTH_TOKEN"] = search_token.asString();
+	subs["AUTH_TOKEN"] = search_token.asString();
 
 	// add the user's preferred maturity (can be changed via prefs)
 	std::string maturity;
 	{
 		maturity = "13";  // PG
 	}
-	search_cookie["MATURITY"] = maturity;
+	subs["MATURITY"] = maturity;
 
 	// add the user's god status
-	search_cookie["GODLIKE"] = gAgent.isGodlike() ? "1" : "0";
-	search_cookie["VERSION"] = LLVersionInfo::getVersion();
-	search_cookie["VERSION_MAJOR"] = LLVersionInfo::getMajor();
-	search_cookie["VERSION_MINOR"] = LLVersionInfo::getMinor();
-	search_cookie["VERSION_PATCH"] = LLVersionInfo::getPatch();
-	search_cookie["VERSION_BUILD"] = LLVersionInfo::getBuild();
-	search_cookie["CHANNEL"] = LLVersionInfo::getChannel();
-	search_cookie["GRID"] = LLGridManager::getInstance()->getGridLabel();
-	search_cookie["OS"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
-	search_cookie["SESSION_ID"] = gAgent.getSessionID();
-	search_cookie["FIRST_LOGIN"] = gAgent.isFirstLogin();
-
-	std::string lang = LLUI::getLanguage();
-	if (lang == "en-us")
-	{
-		lang = "en";
-	}
-	search_cookie["LANGUAGE"] = lang;
-
-	// find the region ID
-	LLUUID region_id;
-	LLViewerRegion *region = gAgent.getRegion();
-	if (region)
-	{
-		region_id = region->getRegionID();
-	}
-	search_cookie["REGION_ID"] = region_id;
-
-	// find the parcel local ID
-	S32 parcel_id = 0;
-	LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
-	if (parcel)
-	{
-		parcel_id = parcel->getLocalID();
-	}
-	search_cookie["PARCEL_ID"] = llformat("%d", parcel_id);
-
-	std::stringstream cookie_string_stream;
-	LLSDSerialize::toXML(search_cookie, cookie_string_stream);
-	std::string cookie_string = cookie_string_stream.str();
-
-	U8* cookie_string_buffer = (U8*)cookie_string.c_str();
-	std::string cookie_value = LLBase64::encode(cookie_string_buffer, cookie_string.size());
-
-	// for staging services
-	LLViewerMedia::getCookieStore()->setCookiesFromHost(std::string("viewer_session_info=") + cookie_value, ".lindenlab.com");
-	// for live services
-	LLViewerMedia::getCookieStore()->setCookiesFromHost(std::string("viewer_session_info=") + cookie_value, ".secondlife.com");
+	subs["GODLIKE"] = gAgent.isGodlike() ? "1" : "0";
 
 	// get the search URL and expand all of the substitutions
 	// (also adds things like [LANGUAGE], [VERSION], [OS], etc.)

indra/newview/llfolderviewitem.cpp

 		setToolTip(mLabel);
 		setIcon(mListener->getIcon());
 		time_t creation_date = mListener->getCreationDate();
-		if (mCreationDate != creation_date)
+		if ((creation_date > 0) && (mCreationDate != creation_date))
 		{
-			setCreationDate(mListener->getCreationDate());
+			setCreationDate(creation_date);
 			dirtyFilter();
 		}
 		if (mRoot->useLabelSuffix())

indra/newview/llpanelgroupgeneral.cpp

 
 	}
 
+	// After role member data was changed in Roles->Members
+	// need to update role titles. See STORM-918.
+	if (gc == GC_ROLE_MEMBER_DATA)
+		LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID);
+
 	// If this was just a titles update, we are done.
 	if (gc == GC_TITLES) return;
 

indra/newview/llpanelmarketplaceinboxinventory.cpp

 
 void LLInboxFolderViewFolder::computeFreshness()
 {
-	const U32 last_expansion = gSavedPerAccountSettings.getU32("LastInventoryInboxActivity");
+	const U32 last_expansion_utc = gSavedPerAccountSettings.getU32("LastInventoryInboxActivity");
 
-	if (last_expansion > 0)
+	if (last_expansion_utc > 0)
 	{
+		const U32 time_offset_for_pdt = 7 * 60 * 60;
+		const U32 last_expansion = last_expansion_utc - time_offset_for_pdt;
+
 		mFresh = (mCreationDate > last_expansion);
 
 #if DEBUGGING_FRESHNESS

indra/newview/llviewermessage.cpp

 
 void inventory_offer_mute_callback(const LLUUID& blocked_id,
 								   const std::string& full_name,
-								   bool is_group,
-								   boost::shared_ptr<LLNotificationResponderInterface> offer_ptr)
+								   bool is_group)
 {
-	LLOfferInfo* offer =  dynamic_cast<LLOfferInfo*>(offer_ptr.get());
-	
-	std::string from_name = full_name;
-	LLMute::EType type;
-	if (is_group)
-	{
-		type = LLMute::GROUP;
-	}
-	else if(offer && offer->mFromObject)
-	{
-		//we have to block object by name because blocked_id is an id of owner
-		type = LLMute::BY_NAME;
-	}
-	else
-	{
-		type = LLMute::AGENT;
-	}
-
-	// id should be null for BY_NAME mute, see  LLMuteList::add for details  
-	LLMute mute(type == LLMute::BY_NAME ? LLUUID::null : blocked_id, from_name, type);
+	// *NOTE: blocks owner if the offer came from an object
+	LLMute::EType mute_type = is_group ? LLMute::GROUP : LLMute::AGENT;
+
+	LLMute mute(blocked_id, full_name, mute_type);
 	if (LLMuteList::getInstance()->add(mute))
 	{
 		LLPanelBlockedList::showPanelAndSelect(blocked_id);
 		bool matches(const LLNotificationPtr notification) const
 		{
 			if(notification->getName() == "ObjectGiveItem" 
+				|| notification->getName() == "OwnObjectGiveItem"
 				|| notification->getName() == "UserGiveItem")
 			{
 				return (notification->getPayload()["from_id"].asUUID() == blocked_id);
 		llassert(notification_ptr != NULL);
 		if (notification_ptr != NULL)
 		{
-			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr()));
+			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
 		}
 	}
 
 		llassert(notification_ptr != NULL);
 		if (notification_ptr != NULL)
 		{
-			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr()));
+			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
 		}
 	}
 	
 	if(mRespondFunctions.empty())
 	{
 		mRespondFunctions["ObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2);
+		mRespondFunctions["OwnObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2);
 		mRespondFunctions["UserGiveItem"] = boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2);
 	}
 }
 	std::string verb = "select?name=" + LLURI::escape(msg);
 	args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString();
 
-	LLNotification::Params p("ObjectGiveItem");
+	LLNotification::Params p;
 
 	// Object -> Agent Inventory Offer
 	if (info->mFromObject)
 		// Note: sets inventory_task_offer_callback as the callback
 		p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
 		info->mPersist = true;
-		p.name = "ObjectGiveItem";
+
+		// Offers from your own objects need a special notification template.
+		p.name = info->mFromID == gAgentID ? "OwnObjectGiveItem" : "ObjectGiveItem";
+
 		// Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory.
 	    LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, info->mFromGroup == TRUE);
 	}
 				bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
 				info->mType = (LLAssetType::EType) bucketp->asset_type;
 				info->mObjectID = bucketp->object_id;
+				info->mFromObject = FALSE;
 			}
-			else
+			else // IM_TASK_INVENTORY_OFFERED
 			{
 				if (sizeof(S8) != binary_bucket_size)
 				{
 				}
 				info->mType = (LLAssetType::EType) binary_bucket[0];
 				info->mObjectID = LLUUID::null;
+				info->mFromObject = TRUE;
 			}
 
 			info->mIM = dialog;
 			info->mTransactionID = session_id;
 			info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
 
-			if (dialog == IM_TASK_INVENTORY_OFFERED)
-			{
-				info->mFromObject = TRUE;
-			}
-			else
-			{
-				info->mFromObject = FALSE;
-			}
 			info->mFromName = name;
 			info->mDesc = message;
 			info->mHost = msg->getSender();

indra/newview/llvoicevivox.cpp

 
 bool LLVivoxVoiceClient::requestParcelVoiceInfo()
 {
-	LL_DEBUGS("Voice") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << LL_ENDL;
-
-	// grab the cap for parcel voice info from the region.  
 	LLViewerRegion * region = gAgent.getRegion();
-	if (region == NULL)
-	{
+	if (region == NULL || !region->capabilitiesReceived())
+	{
+		// we don't have the cap yet, so return false so the caller can try again later.
+
+		LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest capability not yet available, deferring" << LL_ENDL;
 		return false;
 	}
+
 	// grab the cap.
 	std::string url = gAgent.getRegion()->getCapability("ParcelVoiceInfoRequest");
-	if (!url.empty())
+	if (url.empty())
+	{
+		// Region dosn't have the cap. Stop probing.
+		LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest capability not available in this region" << LL_ENDL;
+		setState(stateDisableCleanup);
+		return false;
+	}
+	else 
 	{
 		// if we've already retrieved the cap from the region, go ahead and make the request,
 		// and return true so we can go into the state that waits for the response.
 		LL_DEBUGS("Voice") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << LL_ENDL;
 		
 		LLHTTPClient::post(
-						   url,
-						   data,
-						   new LLVivoxVoiceClientCapResponder(getState()));
+						url,
+						data,
+						new LLVivoxVoiceClientCapResponder(getState()));
 		return true;
 	}
-	else 
-	{
-		
-		// we don't have the cap yet, so return false so the caller can try again later.
-		LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest cap not yet available, deferring" << LL_ENDL;
-		return false;
-	}
 }
 
 void LLVivoxVoiceClient::switchChannel(

indra/newview/skins/default/xui/en/notifications.xml

       <button
        index="2"
        name="Mute"
-       text="Block"/>
+       text="Block Owner"/>
+    </form>
+  </notification>
+
+  <notification
+   icon="notify.tga"
+   name="OwnObjectGiveItem"
+   type="offer">
+Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you this [OBJECTTYPE]:
+&lt;nolink&gt;[ITEM_SLURL]&lt;/nolink&gt;
+    <form name="form">
+      <button
+       index="0"
+       name="Keep"
+       text="Keep"/>
+      <button
+       index="1"
+       name="Discard"
+       text="Discard"/>
     </form>
   </notification>
 
 [ITEM_SLURL]
     <form name="form">
       <button
-       index="4"
+       index="3"
        name="Show"
        text="Show"/>
       <button

indra/newview/skins/default/xui/en/panel_bottomtray.xml

          mouse_opaque="false"
 		 name="chat_bar_layout_panel"
          user_resize="true"
-     width="310" >
+     width="250" >
           <panel
             name="chat_bar"
             filename="panel_nearby_chat_bar.xml"
             left="0"
             height="28"
-        width="308"
+        width="248"
             top="0"
             mouse_opaque="false"
             follows="left|right"
          height="28"
          layout="topleft"
          min_height="28"
-     min_width="52"
+     min_width="62"
          mouse_opaque="false"
          name="mini_map_btn_panel"
          user_resize="false"

indra/newview/viewer_manifest.py

                 # include the extracted list of contributors
                 contributor_names = self.extract_names("../../doc/contributions.txt")
                 self.put_in_file(contributor_names, "contributors.txt")
+                self.file_list.append(["../../doc/contributions.txt",self.dst_path_of("contributors.txt")])
                 # include the extracted list of translators
                 translator_names = self.extract_names("../../doc/translations.txt")
                 self.put_in_file(translator_names, "translators.txt")
+                self.file_list.append(["../../doc/translations.txt",self.dst_path_of("translators.txt")])
                 # include the list of Lindens (if any)
                 #   see https://wiki.lindenlab.com/wiki/Generated_Linden_Credits
-                linden_names_path = os.getenv("linden_credits")
+                linden_names_path = os.getenv("LINDEN_CREDITS")
                 if linden_names_path :
                     try:
                         linden_file = open(linden_names_path,'r')
                         linden_names = ', '.join(linden_file.readlines())
                         self.put_in_file(linden_names, "lindens.txt")
                         linden_file.close()
+                        print "Linden names extracted from '%s'" % linden_names_path
+                        self.file_list.append([linden_names_path,self.dst_path_of("lindens.txt")])
                     except IOError:
                         print "No Linden names found at '%s', using built-in list" % linden_names_path
                         pass
+                else :
+                    print "No 'LINDEN_CREDITS' specified in environment, using built-in list"
 
                 # ... and the entire windlight directory
                 self.path("windlight")

scripts/templates/template-cpp.cpp

+/** 
+* @file #filename#.cpp
+* @brief Implementation of #filename#
+* @author #getpass.getuser()#@lindenlab.com
+*
+* $LicenseInfo:firstyear=#datetime.datetime.now().year#&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) #datetime.datetime.now().year#, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+
+#'' if ( skip_h ) else '%cinclude "%s.h"' % (35,filename)#
+

scripts/templates/template-h.h

+/** 
+* @file   #filename#.h
+* @brief  Header file for #filename#
+* @author #getpass.getuser()#@lindenlab.com
+*
+* $LicenseInfo:firstyear=#datetime.datetime.now().year#&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) #datetime.datetime.now().year#, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#'%c'%35#ifndef LL_#filename.upper().replace('-','_')#_H
+#'%c'%35#define LL_#filename.upper().replace('-','_')#_H
+
+
+#'%c'%35#endif // LL_#filename.upper().replace('-','_')#_H
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.