Commits

Monty Brandenberg committed 117a201

SH-3244 Syscall avoidance in HttpRequest::update() method
Well, achieved that by doing work in bulk when needed. But
turned into some additional things. Change timebase from
mS to uS as, well, things are headed that way. Implement
an HttpReplyQueue::fetchAll method (advertised one, hadn't
implemented it).

  • Participants
  • Parent commits a652483

Comments (0)

Files changed (8)

indra/llcorehttp/_httpreplyqueue.cpp

 	return result;
 }
 
+
+void HttpReplyQueue::fetchAll(OpContainer & ops)
+{
+	// Not valid putting something back on the queue...
+	llassert_always(ops.empty());
+
+	{
+		HttpScopedLock lock(mQueueMutex);
+
+		if (! mQueue.empty())
+		{
+			mQueue.swap(ops);
+		}
+	}
+
+	// Caller also acquires the reference counts on each op.
+	return;
+}
+
+
 }  // end namespace LLCore

indra/llcorehttp/_httprequestqueue.cpp

 
 void HttpRequestQueue::fetchAll(bool wait, OpContainer & ops)
 {
-	// Note:  Should probably test whether we're empty or not here.
-	// A target passed in with entries is likely also carrying
-	// reference counts and we're going to leak something.
-	ops.clear();
+	// Not valid putting something back on the queue...
+	llassert_always(ops.empty());
+
 	{
 		HttpScopedLock lock(mQueueMutex);
 

indra/llcorehttp/examples/http_texture_load.cpp

 	int passes(0);
 	while (! ws.reload(hr))
 	{
-		hr->update(5000);
+		hr->update(5000000);
 		ms_sleep(2);
 		if (0 == (++passes % 200))
 		{

indra/llcorehttp/httprequest.cpp

 }
 
 
-HttpStatus HttpRequest::update(long millis)
+HttpStatus HttpRequest::update(long usecs)
 {
-	const HttpTime limit(totalTime() + (1000 * HttpTime(millis)));
 	HttpOperation * op(NULL);
-	while (limit >= totalTime() && (op = mReplyQueue->fetchOp()))
+	
+	if (usecs)
 	{
-		// Process operation
-		op->visitNotifier(this);
+		const HttpTime limit(totalTime() + HttpTime(usecs));
+		while (limit >= totalTime() && (op = mReplyQueue->fetchOp()))
+		{
+			// Process operation
+			op->visitNotifier(this);
 		
-		// We're done with the operation
-		op->release();
+			// We're done with the operation
+			op->release();
+		}
+	}
+	else
+	{
+		// Same as above, just no time limit
+		HttpReplyQueue::OpContainer replies;
+		mReplyQueue->fetchAll(replies);
+		if (! replies.empty())
+		{
+			for (HttpReplyQueue::OpContainer::iterator iter(replies.begin());
+				 replies.end() != iter;
+				 ++iter)
+			{
+				// Swap op pointer for NULL;
+				op = *iter; *iter = NULL;	
+			
+				// Process operation
+				op->visitNotifier(this);
+		
+				// We're done with the operation
+				op->release();
+			}
+		}
 	}
 	
 	return HttpStatus();

indra/llcorehttp/httprequest.h

 	/// are expected to return 'quickly' and do any significant processing
 	/// outside of the notification callback to onCompleted().
 	///
-	/// @param	millis			Maximum number of wallclock milliseconds to
+	/// @param	usecs			Maximum number of wallclock microseconds to
 	///							spend in the call.  As hinted at above, this
 	///							is partly a function of application code so it's
-	///							a soft limit.
+	///							a soft limit.  A '0' value will run without
+	///							time limit.
 	///
 	/// @return					Standard status code.
-	HttpStatus update(long millis);
+	HttpStatus update(long usecs);
 
 	/// @}
 	

indra/llcorehttp/tests/test_httprequest.hpp

 		int limit(20);
 		while (count++ < limit && mHandlerCalls < 1)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Request executed in reasonable time", count < limit);
 		limit = 100;
 		while (count++ < limit && mHandlerCalls < 2)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Second request executed in reasonable time", count < limit);
 		int limit(20);
 		while (count++ < limit && mHandlerCalls < 2)
 		{
-			req1->update(1000);
-			req2->update(1000);
+			req1->update(1000000);
+			req2->update(1000000);
 			usleep(100000);
 		}
 		ensure("Request executed in reasonable time", count < limit);
 		limit = 100;
 		while (count++ < limit && mHandlerCalls < 3)
 		{
-			req1->update(1000);
-			req2->update(1000);
+			req1->update(1000000);
+			req2->update(1000000);
 			usleep(100000);
 		}
 		ensure("Second request executed in reasonable time", count < limit);
 		int limit(10);
 		while (count++ < limit && mHandlerCalls < 1)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("NoOp notification received", mHandlerCalls == 1);
 		int limit(10);
 		while (count++ < limit && mHandlerCalls < 1)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("No notifications received", mHandlerCalls == 0);
 		int limit(50);				// With one retry, should fail quickish
 		while (count++ < limit && mHandlerCalls < 1)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Request executed in reasonable time", count < limit);
 		limit = 100;
 		while (count++ < limit && mHandlerCalls < 2)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Second request executed in reasonable time", count < limit);
 		int limit(10);
 		while (count++ < limit && mHandlerCalls < 1)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Request executed in reasonable time", count < limit);
 		limit = 10;
 		while (count++ < limit && mHandlerCalls < 2)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Second request executed in reasonable time", count < limit);
 		int limit(10);
 		while (count++ < limit && mHandlerCalls < 1)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Request executed in reasonable time", count < limit);
 		limit = 10;
 		while (count++ < limit && mHandlerCalls < 2)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Second request executed in reasonable time", count < limit);
 		int limit(10);
 		while (count++ < limit && mHandlerCalls < 1)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Request executed in reasonable time", count < limit);
 		limit = 10;
 		while (count++ < limit && mHandlerCalls < 2)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Second request executed in reasonable time", count < limit);
 		int limit(10);
 		while (count++ < limit && mHandlerCalls < 1)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Request executed in reasonable time", count < limit);
 		limit = 10;
 		while (count++ < limit && mHandlerCalls < 2)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Second request executed in reasonable time", count < limit);
 		int limit(10);
 		while (count++ < limit && mHandlerCalls < 1)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Request executed in reasonable time", count < limit);
 		limit = 10;
 		while (count++ < limit && mHandlerCalls < 2)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Second request executed in reasonable time", count < limit);
 		int limit(10);
 		while (count++ < limit && mHandlerCalls < 1)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Request executed in reasonable time", count < limit);
 		limit = 10;
 		while (count++ < limit && mHandlerCalls < 2)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Second request executed in reasonable time", count < limit);
 		int limit(50);				// With one retry, should fail quickish
 		while (count++ < limit && mHandlerCalls < 1)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Request executed in reasonable time", count < limit);
 		limit = 100;
 		while (count++ < limit && mHandlerCalls < 2)
 		{
-			req->update(1000);
+			req->update(1000000);
 			usleep(100000);
 		}
 		ensure("Second request executed in reasonable time", count < limit);

indra/newview/llappviewer.cpp

 	{
 		while (! mStopped && LLTimer::getTotalSeconds() < (mStopRequested + MAX_THREAD_WAIT_TIME))
 		{
-			mRequest->update(200);
+			mRequest->update(200000);
 			ms_sleep(50);
 		}
 		if (! mStopped)

indra/newview/lltexturefetch.cpp

 	// Run a cross-thread command, if any.
 	cmdDoWork();
 	
-	// Update Curl on same thread as mCurlGetRequest was constructed
-	LLCore::HttpStatus status = mHttpRequest->update(200);
+	// Deliver all completion notifications
+	LLCore::HttpStatus status = mHttpRequest->update(0);
 	if (! status)
 	{
 		LL_INFOS_ONCE("Texture") << "Problem during HTTP servicing.  Reason:  "
 								 << status.toString()
 								 << LL_ENDL;
 	}
-		
-#if 0
-	// *FIXME:  maybe implement this another way...
-	if (processed > 0)
-	{
-		lldebugs << "processed: " << processed << " messages." << llendl;
-	}
-#endif
 }
 
 
 void LLTextureFetch::threadedUpdate()
 {
 	llassert_always(mHttpRequest);
-	
+
+#if 0
 	// Limit update frequency
 	const F32 PROCESS_TIME = 0.05f; 
 	static LLFrameTimer process_timer;
 		return;
 	}
 	process_timer.reset();
+#endif
 	
 	commonUpdate();
-
+	
 #if 0
 	const F32 INFO_TIME = 1.0f; 
 	static LLFrameTimer info_timer;
 		}
 	}
 #endif
-	
 }
 
 //////////////////////////////////////////////////////////////////////////////