summaryrefslogtreecommitdiff
path: root/indra/llcorehttp/_httpservice.h
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2012-11-13 10:50:16 -0500
committerOz Linden <oz@lindenlab.com>2012-11-13 10:50:16 -0500
commit7e779a29c142feaa34a30dff39b72d0ae7c0fdc3 (patch)
tree401447b5d265520c12de5c4929f0e72468882b68 /indra/llcorehttp/_httpservice.h
parent42c957e9d823ee5124fa1ac992fc0e803a3b0d9a (diff)
parent7cef2e02565977d3894dbd7c9bde91fb39d9066a (diff)
merge changes for DRTVWR-209
Diffstat (limited to 'indra/llcorehttp/_httpservice.h')
-rw-r--r--indra/llcorehttp/_httpservice.h224
1 files changed, 224 insertions, 0 deletions
diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h
new file mode 100644
index 0000000000..ffe0349d4d
--- /dev/null
+++ b/indra/llcorehttp/_httpservice.h
@@ -0,0 +1,224 @@
+/**
+ * @file _httpservice.h
+ * @brief Declarations for internal class providing HTTP service.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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$
+ */
+
+#ifndef _LLCORE_HTTP_SERVICE_H_
+#define _LLCORE_HTTP_SERVICE_H_
+
+
+#include <vector>
+
+#include "linden_common.h"
+#include "llapr.h"
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "_httppolicyglobal.h"
+#include "_httppolicyclass.h"
+
+
+namespace LLCoreInt
+{
+
+class HttpThread;
+
+}
+
+
+namespace LLCore
+{
+
+
+class HttpRequestQueue;
+class HttpPolicy;
+class HttpLibcurl;
+
+
+/// The HttpService class does the work behind the request queue. It
+/// oversees the HTTP workflow carrying out a number of tasks:
+/// - Pulling requests from the global request queue
+/// - Executing 'immediate' requests directly
+/// - Prioritizing and re-queuing on internal queues the slower requests
+/// - Providing cpu cycles to the libcurl plumbing
+/// - Overseeing retry operations
+///
+/// Note that the service object doesn't have a pointer to any
+/// reply queue. These are kept by HttpRequest and HttpOperation
+/// only.
+///
+/// Service, Policy and Transport
+///
+/// HttpService could have been a monolithic class combining a request
+/// queue servicer, request policy manager and network transport.
+/// Instead, to prevent monolithic growth and allow for easier
+/// replacement, it was developed as three separate classes: HttpService,
+/// HttpPolicy and HttpLibcurl (transport). These always exist in a
+/// 1:1:1 relationship with HttpService managing instances of the other
+/// two. So, these classes do not use reference counting to refer
+/// to one another, their lifecycles are always managed together.
+
+class HttpService
+{
+protected:
+ HttpService();
+ virtual ~HttpService();
+
+private:
+ HttpService(const HttpService &); // Not defined
+ void operator=(const HttpService &); // Not defined
+
+public:
+ enum EState
+ {
+ NOT_INITIALIZED = -1,
+ INITIALIZED, ///< init() has been called
+ RUNNING, ///< thread created and running
+ STOPPED ///< thread has committed to exiting
+ };
+
+ // Ordered enumeration of idling strategies available to
+ // threadRun's loop. Ordered so that std::min on values
+ // produces the most conservative result of multiple
+ // requests.
+ enum ELoopSpeed
+ {
+ NORMAL, ///< continuous polling of request, ready, active queues
+ REQUEST_SLEEP ///< can sleep indefinitely waiting for request queue write
+ };
+
+ static void init(HttpRequestQueue *);
+ static void term();
+
+ /// Threading: callable by any thread once inited.
+ inline static HttpService * instanceOf()
+ {
+ return sInstance;
+ }
+
+ /// Return the state of the worker thread. Note that the
+ /// transition from RUNNING to STOPPED is performed by the
+ /// worker thread itself. This has two weaknesses:
+ /// - race where the thread hasn't really stopped but will
+ /// - data ordering between threads where a non-worker thread
+ /// may see a stale RUNNING status.
+ ///
+ /// This transition is generally of interest only to unit tests
+ /// and these weaknesses shouldn't be any real burden.
+ ///
+ /// Threading: callable by any thread with above exceptions.
+ static EState getState()
+ {
+ return sState;
+ }
+
+ /// Threading: callable by any thread but uses @see getState() and
+ /// acquires its weaknesses.
+ static bool isStopped();
+
+ /// Threading: callable by consumer thread *once*.
+ void startThread();
+
+ /// Threading: callable by worker thread.
+ void stopRequested();
+
+ /// Threading: callable by worker thread.
+ void shutdown();
+
+ /// Try to find the given request handle on any of the request
+ /// queues and reset the priority (and queue position) of the
+ /// request if found.
+ ///
+ /// @return True if the request was found somewhere.
+ ///
+ /// Threading: callable by worker thread.
+ bool changePriority(HttpHandle handle, HttpRequest::priority_t priority);
+
+ /// Try to find the given request handle on any of the request
+ /// queues and cancel the operation.
+ ///
+ /// @return True if the request was found and canceled.
+ ///
+ /// Threading: callable by worker thread.
+ bool cancel(HttpHandle handle);
+
+ /// Threading: callable by worker thread.
+ HttpPolicy & getPolicy()
+ {
+ return *mPolicy;
+ }
+
+ /// Threading: callable by worker thread.
+ HttpLibcurl & getTransport()
+ {
+ return *mTransport;
+ }
+
+ /// Threading: callable by worker thread.
+ HttpRequestQueue & getRequestQueue()
+ {
+ return *mRequestQueue;
+ }
+
+ /// Threading: callable by consumer thread.
+ HttpPolicyGlobal & getGlobalOptions()
+ {
+ return mPolicyGlobal;
+ }
+
+ /// Threading: callable by consumer thread.
+ HttpRequest::policy_t createPolicyClass();
+
+ /// Threading: callable by consumer thread.
+ HttpPolicyClass & getClassOptions(HttpRequest::policy_t policy_class)
+ {
+ llassert(policy_class >= 0 && policy_class < mPolicyClasses.size());
+ return mPolicyClasses[policy_class];
+ }
+
+protected:
+ void threadRun(LLCoreInt::HttpThread * thread);
+
+ ELoopSpeed processRequestQueue(ELoopSpeed loop);
+
+protected:
+ static HttpService * sInstance;
+
+ // === shared data ===
+ static volatile EState sState;
+ HttpRequestQueue * mRequestQueue; // Refcounted
+ LLAtomicU32 mExitRequested;
+ LLCoreInt::HttpThread * mThread;
+
+ // === consumer-thread-only data ===
+ HttpPolicyGlobal mPolicyGlobal;
+ std::vector<HttpPolicyClass> mPolicyClasses;
+
+ // === working-thread-only data ===
+ HttpPolicy * mPolicy; // Simple pointer, has ownership
+ HttpLibcurl * mTransport; // Simple pointer, has ownership
+}; // end class HttpService
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_SERVICE_H_