mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-08-18 06:55:48 +03:00
Added support for AsyncRequests in cHttp.
Added cThreadLocal and tThreadLocalPtr ( needed for the async requests ).
This commit is contained in:
@@ -6,8 +6,14 @@
|
||||
#include <eepp/network/ctcpsocket.hpp>
|
||||
#include <eepp/base/noncopyable.hpp>
|
||||
#include <eepp/system/ctime.hpp>
|
||||
#include <eepp/system/tthreadlocalptr.hpp>
|
||||
#include <eepp/system/cthread.hpp>
|
||||
#include <eepp/system/cmutex.hpp>
|
||||
#include <eepp/system/clock.hpp>
|
||||
#include <eepp/helper/PlusCallback/callback.hpp>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
using namespace EE::System;
|
||||
|
||||
@@ -73,6 +79,9 @@ class EE_API cHttp : NonCopyable {
|
||||
** The body is empty by default.
|
||||
** @param body Content of the body */
|
||||
void SetBody(const std::string& body);
|
||||
|
||||
/** @return The request Uri */
|
||||
const std::string& GetUri() const;
|
||||
private:
|
||||
friend class cHttp;
|
||||
|
||||
@@ -212,6 +221,8 @@ class EE_API cHttp : NonCopyable {
|
||||
** @param port Port to use for connection */
|
||||
cHttp(const std::string& host, unsigned short port = 0);
|
||||
|
||||
~cHttp();
|
||||
|
||||
/** @brief Set the target host
|
||||
** This function just stores the host address and port, it
|
||||
** doesn't actually connect to it until you send a request.
|
||||
@@ -224,7 +235,6 @@ class EE_API cHttp : NonCopyable {
|
||||
** @param port Port to use for connection */
|
||||
void SetHost(const std::string& host, unsigned short port = 0);
|
||||
|
||||
|
||||
/** @brief Send a HTTP request and return the server's response.
|
||||
** You must have a valid host before sending a request (see SetHost).
|
||||
** Any missing mandatory header field in the request will be added
|
||||
@@ -238,12 +248,46 @@ class EE_API cHttp : NonCopyable {
|
||||
** @param timeout Maximum time to wait
|
||||
** @return Server's response */
|
||||
Response SendRequest(const Request& request, cTime timeout = cTime::Zero);
|
||||
|
||||
/** Definition of the async callback response */
|
||||
typedef cb::Callback3<void, const cHttp&, cHttp::Request&, cHttp::Response&> AsyncResponseCallback;
|
||||
|
||||
/** @brief Sends the request and creates a new thread, when got the response informs the result to the callback.
|
||||
** This function does not lock the caller thread.
|
||||
** @see SendRequest */
|
||||
void SendAsyncRequest( AsyncResponseCallback cb, const cHttp::Request& request, cTime timeout = cTime::Zero );
|
||||
|
||||
/** @return The host address */
|
||||
const cIpAddress& GetHost() const;
|
||||
|
||||
/** @return The host name */
|
||||
const std::string& GetHostName() const;
|
||||
|
||||
/** @return The host port */
|
||||
const unsigned short& GetPort() const;
|
||||
private:
|
||||
// Member data
|
||||
cTcpSocket mConnection; ///< Connection to the host
|
||||
cIpAddress mHost; ///< Web host address
|
||||
std::string mHostName; ///< Web host name
|
||||
unsigned short mPort; ///< Port used for connection with host
|
||||
class cAsyncRequest : public cThread {
|
||||
public:
|
||||
cAsyncRequest( cHttp * http, AsyncResponseCallback cb, cHttp::Request request, cTime timeout );
|
||||
|
||||
void Run();
|
||||
protected:
|
||||
friend class cHttp;
|
||||
cHttp * mHttp;
|
||||
AsyncResponseCallback mCb;
|
||||
cHttp::Request mRequest;
|
||||
cTime mTimeout;
|
||||
bool mRunning;
|
||||
};
|
||||
friend class cAsyncRequest;
|
||||
tThreadLocalPtr<cTcpSocket> mConnection; ///< Connection to the host
|
||||
cIpAddress mHost; ///< Web host address
|
||||
std::string mHostName; ///< Web host name
|
||||
unsigned short mPort; ///< Port used for connection with host
|
||||
std::list<cAsyncRequest*> mThreads;
|
||||
cMutex mThreadsMutex;
|
||||
|
||||
void RemoveOldThreads();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -22,5 +22,7 @@
|
||||
#include <eepp/system/cresourceloader.hpp>
|
||||
#include <eepp/system/tresourcemanager.hpp>
|
||||
#include <eepp/system/cpackmanager.hpp>
|
||||
#include <eepp/system/cthreadlocal.hpp>
|
||||
#include <eepp/system/tthreadlocalptr.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -128,29 +128,29 @@ struct ThreadFunc
|
||||
template <typename T>
|
||||
struct ThreadFunctor : ThreadFunc
|
||||
{
|
||||
ThreadFunctor(T functor) : m_functor(functor) {}
|
||||
virtual void Run() {m_functor();}
|
||||
T m_functor;
|
||||
ThreadFunctor(T functor) : mFunctor(functor) {}
|
||||
virtual void Run() {mFunctor();}
|
||||
T mFunctor;
|
||||
};
|
||||
|
||||
// Specialization using a functor (including free functions) with one argument
|
||||
template <typename F, typename A>
|
||||
struct ThreadFunctorWithArg : ThreadFunc
|
||||
{
|
||||
ThreadFunctorWithArg(F function, A arg) : m_function(function), m_arg(arg) {}
|
||||
virtual void Run() {m_function(m_arg);}
|
||||
F m_function;
|
||||
A m_arg;
|
||||
ThreadFunctorWithArg(F function, A arg) : mFunction(function), mArg(arg) {}
|
||||
virtual void Run() {mFunction(mArg);}
|
||||
F mFunction;
|
||||
A mArg;
|
||||
};
|
||||
|
||||
// Specialization using a member function
|
||||
template <typename C>
|
||||
struct ThreadMemberFunc : ThreadFunc
|
||||
{
|
||||
ThreadMemberFunc(void(C::*function)(), C* object) : m_function(function), m_object(object) {}
|
||||
virtual void Run() {(m_object->*m_function)();}
|
||||
void(C::*m_function)();
|
||||
C* m_object;
|
||||
ThreadMemberFunc(void(C::*function)(), C* object) : mFunction(function), mObject(object) {}
|
||||
virtual void Run() {(mObject->*mFunction)();}
|
||||
void(C::*mFunction)();
|
||||
C* mObject;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
35
include/eepp/system/cthreadlocal.hpp
Normal file
35
include/eepp/system/cthreadlocal.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef EE_SYSTEMCTHREADLOCAL_HPP
|
||||
#define EE_SYSTEMCTHREADLOCAL_HPP
|
||||
|
||||
#include <eepp/base.hpp>
|
||||
#include <eepp/base/noncopyable.hpp>
|
||||
|
||||
namespace EE { namespace System { namespace Private {
|
||||
class cThreadLocalImpl;
|
||||
}}}
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
/** @brief Defines variables with thread-local storage */
|
||||
class EE_API cThreadLocal : NonCopyable {
|
||||
public:
|
||||
/** @brief Default constructor
|
||||
** @param value Optional value to initalize the variable */
|
||||
cThreadLocal(void* value = NULL);
|
||||
|
||||
~cThreadLocal();
|
||||
|
||||
/** @brief Set the thread-specific value of the variable
|
||||
** @param value Value of the variable for the current thread */
|
||||
void Value(void* value);
|
||||
|
||||
/** @brief Retrieve the thread-specific value of the variable
|
||||
** @return Value of the variable for the current thread */
|
||||
void* Value() const;
|
||||
private :
|
||||
Private::cThreadLocalImpl* mImpl; ///< Pointer to the OS specific implementation
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
122
include/eepp/system/tthreadlocalptr.hpp
Normal file
122
include/eepp/system/tthreadlocalptr.hpp
Normal file
@@ -0,0 +1,122 @@
|
||||
#ifndef EE_SYSTEMCTHREADLOCALPTR_HPP
|
||||
#define EE_SYSTEMCTHREADLOCALPTR_HPP
|
||||
|
||||
#include <eepp/system/cthreadlocal.hpp>
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
/** @brief Pointer to a thread-local variable */
|
||||
template <typename T>
|
||||
class tThreadLocalPtr : private cThreadLocal
|
||||
{
|
||||
public :
|
||||
/** @brief Default constructor
|
||||
** @param value Optional value to initalize the variable */
|
||||
tThreadLocalPtr(T* value = NULL);
|
||||
|
||||
/** @brief Overload of unary operator *
|
||||
** Like raw pointers, applying the * operator returns a
|
||||
** reference to the pointed object.
|
||||
** @return Reference to the pointed object */
|
||||
T& operator *() const;
|
||||
|
||||
/** @brief Overload of operator ->
|
||||
** Like raw pointers, applying the -> operator returns the
|
||||
** pointed object.
|
||||
** @return Pointed object */
|
||||
T* operator ->() const;
|
||||
|
||||
/** @brief Cast operator to implicitely convert the pointer to its raw pointer type (T*)
|
||||
** @return Pointer to the actual object */
|
||||
operator T*() const;
|
||||
|
||||
/** @brief Assignment operator for a raw pointer parameter
|
||||
** @param value Pointer to assign
|
||||
** @return Reference to self */
|
||||
tThreadLocalPtr<T>& operator =(T* value);
|
||||
|
||||
/** @brief Assignment operator for a tThreadLocalPtr parameter
|
||||
** @param right tThreadLocalPtr to assign
|
||||
** @return Reference to self */
|
||||
tThreadLocalPtr<T>& operator =(const tThreadLocalPtr<T>& right);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
tThreadLocalPtr<T>::tThreadLocalPtr(T* value) :
|
||||
cThreadLocal(value)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& tThreadLocalPtr<T>::operator *() const {
|
||||
return *static_cast<T*>(Value());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* tThreadLocalPtr<T>::operator ->() const {
|
||||
return static_cast<T*>(Value());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
tThreadLocalPtr<T>::operator T*() const {
|
||||
return static_cast<T*>(Value());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
tThreadLocalPtr<T>& tThreadLocalPtr<T>::operator =(T* value) {
|
||||
Value(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
tThreadLocalPtr<T>& tThreadLocalPtr<T>::operator =(const tThreadLocalPtr<T>& right) {
|
||||
Value(right.Value());
|
||||
return *this;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
@class tThreadLocalPtr
|
||||
@ingroup System
|
||||
|
||||
tThreadLocalPtr is a type-safe wrapper for storing
|
||||
pointers to thread-local variables. A thread-local
|
||||
variable holds a different value for each different
|
||||
thread, unlike normal variable that are shared.
|
||||
|
||||
Its usage is completely transparent, so that it is similar
|
||||
to manipulating the raw pointer directly (like any smart pointer).
|
||||
|
||||
Usage example:
|
||||
@code
|
||||
MyClass object1;
|
||||
MyClass object2;
|
||||
tThreadLocalPtr<MyClass> objectPtr;
|
||||
|
||||
void thread1()
|
||||
{
|
||||
objectPtr = &object1; // doesn't impact thread2
|
||||
...
|
||||
}
|
||||
|
||||
void thread2()
|
||||
{
|
||||
objectPtr = &object2; // doesn't impact thread1
|
||||
...
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// Create and launch the two threads
|
||||
cThread t1(&thread1);
|
||||
cThread t2(&thread2);
|
||||
t1.launch();
|
||||
t2.launch();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
Reference in New Issue
Block a user