235 lines
6.8 KiB
C++
235 lines
6.8 KiB
C++
/**
|
|
* @file _httpservice.h
|
|
* @brief Declarations for internal class providing HTTP service.
|
|
*
|
|
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
|
* Second Life Viewer Source Code
|
|
* Copyright (C) 2012-2013, 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 "llatomic.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;
|
|
class HttpOpSetGet;
|
|
|
|
|
|
/// 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 init 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 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.
|
|
HttpRequest::policy_t createPolicyClass();
|
|
|
|
protected:
|
|
void threadRun(LLCoreInt::HttpThread * thread);
|
|
|
|
ELoopSpeed processRequestQueue(ELoopSpeed loop);
|
|
|
|
protected:
|
|
friend class HttpOpSetGet;
|
|
friend class HttpRequest;
|
|
|
|
// Used internally to describe what operations are allowed
|
|
// on each policy option.
|
|
struct OptionDescriptor
|
|
{
|
|
bool mIsLong;
|
|
bool mIsDynamic;
|
|
bool mIsGlobal;
|
|
bool mIsClass;
|
|
bool mIsCallback;
|
|
};
|
|
|
|
HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
|
|
long * ret_value);
|
|
HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
|
|
std::string * ret_value);
|
|
HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
|
|
HttpRequest::policyCallback_t * ret_value);
|
|
|
|
HttpStatus setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
|
|
long value, long * ret_value);
|
|
HttpStatus setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
|
|
const std::string & value, std::string * ret_value);
|
|
HttpStatus setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
|
|
HttpRequest::policyCallback_t value,
|
|
HttpRequest::policyCallback_t * ret_value);
|
|
|
|
protected:
|
|
static const OptionDescriptor sOptionDesc[HttpRequest::PO_LAST];
|
|
static HttpService * sInstance;
|
|
|
|
// === shared data ===
|
|
static volatile EState sState;
|
|
HttpRequestQueue * mRequestQueue; // Refcounted
|
|
LLAtomicU32 mExitRequested;
|
|
LLCoreInt::HttpThread * mThread;
|
|
|
|
// === working-thread-only data ===
|
|
HttpPolicy * mPolicy; // Simple pointer, has ownership
|
|
HttpLibcurl * mTransport; // Simple pointer, has ownership
|
|
|
|
// === main-thread-only data ===
|
|
HttpRequest::policy_t mLastPolicy;
|
|
|
|
}; // end class HttpService
|
|
|
|
} // end namespace LLCore
|
|
|
|
#endif // _LLCORE_HTTP_SERVICE_H_
|