mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-07-13 06:22:51 +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
|
||||
*/
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 2.8.0, 2013-09-29T02:43:00. -->
|
||||
<!-- Written by QtCreator 2.8.0, 2013-09-30T02:03:41. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||
@@ -48,7 +48,7 @@
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{388e5431-b31b-42b3-b9ad-9002d279d75d}</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">10</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">19</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">11</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
|
||||
@@ -653,3 +653,10 @@
|
||||
../../Makefile.base
|
||||
../../Makefile
|
||||
../../src/examples/http_request/http_request.cpp
|
||||
../../include/eepp/system/cthreadlocal.hpp
|
||||
../../src/eepp/system/cthreadlocal.cpp
|
||||
../../src/eepp/system/platform/win/cthreadlocalimpl.hpp
|
||||
../../src/eepp/system/platform/win/cthreadlocalimpl.cpp
|
||||
../../src/eepp/system/platform/posix/cthreadlocalimpl.hpp
|
||||
../../src/eepp/system/platform/posix/cthreadlocalimpl.cpp
|
||||
../../include/eepp/system/tthreadlocalptr.hpp
|
||||
|
||||
@@ -53,6 +53,10 @@ void cHttp::Request::SetBody(const std::string& body) {
|
||||
mBody = body;
|
||||
}
|
||||
|
||||
const std::string &cHttp::Request::GetUri() const {
|
||||
return mUri;
|
||||
}
|
||||
|
||||
std::string cHttp::Request::Prepare() const {
|
||||
std::ostringstream out;
|
||||
|
||||
@@ -219,15 +223,36 @@ void cHttp::Response::Parse(const std::string& data) {
|
||||
}
|
||||
|
||||
cHttp::cHttp() :
|
||||
mConnection( NULL ),
|
||||
mHost(),
|
||||
mPort(0)
|
||||
{
|
||||
}
|
||||
|
||||
cHttp::cHttp(const std::string& host, unsigned short port) {
|
||||
cHttp::cHttp(const std::string& host, unsigned short port) :
|
||||
mConnection( NULL )
|
||||
{
|
||||
SetHost(host, port);
|
||||
}
|
||||
|
||||
cHttp::~cHttp() {
|
||||
std::list<cAsyncRequest*>::iterator itt;
|
||||
|
||||
// First we wait to finish any request pending
|
||||
for ( itt = mThreads.begin(); itt != mThreads.end(); itt++ ) {
|
||||
(*itt)->Wait();
|
||||
}
|
||||
|
||||
for ( itt = mThreads.begin(); itt != mThreads.end(); itt++ ) {
|
||||
eeDelete( *itt );
|
||||
}
|
||||
|
||||
// Then we destroy the last open connection
|
||||
cTcpSocket * tcp = mConnection;
|
||||
|
||||
eeSAFE_DELETE( tcp );
|
||||
}
|
||||
|
||||
void cHttp::SetHost(const std::string& host, unsigned short port) {
|
||||
// Check the protocol
|
||||
if (toLower(host.substr(0, 7)) == "http://") {
|
||||
@@ -253,6 +278,11 @@ void cHttp::SetHost(const std::string& host, unsigned short port) {
|
||||
}
|
||||
|
||||
cHttp::Response cHttp::SendRequest(const cHttp::Request& request, cTime timeout) {
|
||||
if ( NULL == mConnection ) {
|
||||
cTcpSocket * Conn = eeNew( cTcpSocket, () );
|
||||
mConnection = Conn;
|
||||
}
|
||||
|
||||
// First make sure that the request is valid -- add missing mandatory fields
|
||||
Request toSend(request);
|
||||
|
||||
@@ -286,19 +316,19 @@ cHttp::Response cHttp::SendRequest(const cHttp::Request& request, cTime timeout)
|
||||
Response received;
|
||||
|
||||
// Connect the socket to the host
|
||||
if (mConnection.Connect(mHost, mPort, timeout) == cSocket::Done) {
|
||||
if (mConnection->Connect(mHost, mPort, timeout) == cSocket::Done) {
|
||||
// Convert the request to string and send it through the connected socket
|
||||
std::string requestStr = toSend.Prepare();
|
||||
|
||||
if (!requestStr.empty()) {
|
||||
// Send it through the socket
|
||||
if (mConnection.Send(requestStr.c_str(), requestStr.size()) == cSocket::Done) {
|
||||
if (mConnection->Send(requestStr.c_str(), requestStr.size()) == cSocket::Done) {
|
||||
// Wait for the server's response
|
||||
std::string receivedStr;
|
||||
std::size_t size = 0;
|
||||
char buffer[1024];
|
||||
|
||||
while (mConnection.Receive(buffer, sizeof(buffer), size) == cSocket::Done) {
|
||||
while (mConnection->Receive(buffer, sizeof(buffer), size) == cSocket::Done) {
|
||||
receivedStr.append(buffer, buffer + size);
|
||||
}
|
||||
|
||||
@@ -308,10 +338,80 @@ cHttp::Response cHttp::SendRequest(const cHttp::Request& request, cTime timeout)
|
||||
}
|
||||
|
||||
// Close the connection
|
||||
mConnection.Disconnect();
|
||||
mConnection->Disconnect();
|
||||
}
|
||||
|
||||
return received;
|
||||
}
|
||||
|
||||
cHttp::cAsyncRequest::cAsyncRequest(cHttp *http, AsyncResponseCallback cb, cHttp::Request request, cTime timeout) :
|
||||
mHttp( http ),
|
||||
mCb( cb ),
|
||||
mRequest( request ),
|
||||
mTimeout( timeout ),
|
||||
mRunning( true )
|
||||
{
|
||||
}
|
||||
|
||||
void cHttp::cAsyncRequest::Run() {
|
||||
cHttp::Response response = mHttp->SendRequest( mRequest, mTimeout );
|
||||
|
||||
mCb( *mHttp, mRequest, response );
|
||||
|
||||
// The Async Request destroys the socket used to create the request
|
||||
cTcpSocket * tcp = mHttp->mConnection;
|
||||
eeSAFE_DELETE( tcp );
|
||||
mHttp->mConnection = NULL;
|
||||
|
||||
mRunning = false;
|
||||
}
|
||||
|
||||
void cHttp::RemoveOldThreads() {
|
||||
std::list<cAsyncRequest*> remove;
|
||||
|
||||
std::list<cAsyncRequest*>::iterator it = mThreads.begin();
|
||||
|
||||
for ( ; it != mThreads.end(); it++ ) {
|
||||
cAsyncRequest * ar = (*it);
|
||||
|
||||
if ( !ar->mRunning ) {
|
||||
// We need to be sure, since the state is set in the thread, this will not block the thread anyway
|
||||
ar->Wait();
|
||||
|
||||
eeDelete( ar );
|
||||
|
||||
remove.push_back( ar );
|
||||
}
|
||||
}
|
||||
|
||||
for ( it = remove.begin(); it != remove.end(); it++ ) {
|
||||
mThreads.remove( (*it) );
|
||||
}
|
||||
}
|
||||
|
||||
void cHttp::SendAsyncRequest( AsyncResponseCallback cb, const cHttp::Request& request, cTime timeout ) {
|
||||
cAsyncRequest * thread = eeNew( cAsyncRequest, ( this, cb, request, timeout ) );
|
||||
|
||||
thread->Launch();
|
||||
|
||||
// Clean old threads
|
||||
cLock l( mThreadsMutex );
|
||||
|
||||
RemoveOldThreads();
|
||||
|
||||
mThreads.push_back( thread );
|
||||
}
|
||||
|
||||
const cIpAddress &cHttp::GetHost() const {
|
||||
return mHost;
|
||||
}
|
||||
|
||||
const std::string &cHttp::GetHostName() const {
|
||||
return mHostName;
|
||||
}
|
||||
|
||||
const unsigned short& cHttp::GetPort() const {
|
||||
return mPort;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
24
src/eepp/system/cthreadlocal.cpp
Normal file
24
src/eepp/system/cthreadlocal.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <eepp/system/cthreadlocal.hpp>
|
||||
#include <eepp/system/platform/platformimpl.hpp>
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
cThreadLocal::cThreadLocal(void* value) :
|
||||
mImpl( eeNew( Private::cThreadLocalImpl, () ) )
|
||||
{
|
||||
Value( value );
|
||||
}
|
||||
|
||||
cThreadLocal::~cThreadLocal() {
|
||||
eeSAFE_DELETE( mImpl );
|
||||
}
|
||||
|
||||
void cThreadLocal::Value(void* value) {
|
||||
mImpl->Value(value);
|
||||
}
|
||||
|
||||
void* cThreadLocal::Value() const {
|
||||
return mImpl->Value();
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -8,13 +8,15 @@
|
||||
#include <eepp/system/platform/posix/cmuteximpl.hpp>
|
||||
#include <eepp/system/platform/posix/cclockimpl.hpp>
|
||||
#include <eepp/system/platform/posix/cconditionimpl.hpp>
|
||||
#include <eepp/system/platform/posix/cthreadlocalimpl.hpp>
|
||||
#elif EE_PLATFORM == EE_PLATFORM_WIN
|
||||
#include <eepp/system/platform/win/cthreadimpl.hpp>
|
||||
#include <eepp/system/platform/win/cmuteximpl.hpp>
|
||||
#include <eepp/system/platform/win/cclockimpl.hpp>
|
||||
#include <eepp/system/platform/win/cconditionimpl.hpp>
|
||||
#include <eepp/system/platform/win/cthreadlocalimpl.hpp>
|
||||
#else
|
||||
#error Threads, mutexes, conditions and timers not implemented for this platform.
|
||||
#error Threads, mutexes, conditions, timers and thread local storage not implemented for this platform.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
25
src/eepp/system/platform/posix/cthreadlocalimpl.cpp
Normal file
25
src/eepp/system/platform/posix/cthreadlocalimpl.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <eepp/system/platform/posix/cthreadlocalimpl.hpp>
|
||||
|
||||
#if defined( EE_PLATFORM_POSIX )
|
||||
|
||||
namespace EE { namespace System { namespace Private {
|
||||
|
||||
cThreadLocalImpl::cThreadLocalImpl() {
|
||||
pthread_key_create(&mKey, NULL);
|
||||
}
|
||||
|
||||
cThreadLocalImpl::~cThreadLocalImpl() {
|
||||
pthread_key_delete(mKey);
|
||||
}
|
||||
|
||||
void cThreadLocalImpl::Value(void* value) {
|
||||
pthread_setspecific(mKey, value);
|
||||
}
|
||||
|
||||
void* cThreadLocalImpl::Value() const {
|
||||
return pthread_getspecific(mKey);
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
31
src/eepp/system/platform/posix/cthreadlocalimpl.hpp
Normal file
31
src/eepp/system/platform/posix/cthreadlocalimpl.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef EE_SYSTEMCTHREADLOCALIMPLPOSIX_HPP
|
||||
#define EE_SYSTEMCTHREADLOCALIMPLPOSIX_HPP
|
||||
|
||||
#include <eepp/base.hpp>
|
||||
#include <eepp/base/noncopyable.hpp>
|
||||
|
||||
#if defined( EE_PLATFORM_POSIX )
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
namespace EE { namespace System { namespace Private {
|
||||
|
||||
class cThreadLocalImpl : NonCopyable {
|
||||
public:
|
||||
cThreadLocalImpl();
|
||||
|
||||
~cThreadLocalImpl();
|
||||
|
||||
void Value(void* value);
|
||||
|
||||
void* Value() const;
|
||||
private :
|
||||
pthread_key_t mKey;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
25
src/eepp/system/platform/win/cthreadlocalimpl.cpp
Normal file
25
src/eepp/system/platform/win/cthreadlocalimpl.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <eepp/system/platform/win/cthreadlocalimpl.hpp>
|
||||
|
||||
#if EE_PLATFORM == EE_PLATFORM_WIN
|
||||
|
||||
namespace EE { namespace System { namespace Private {
|
||||
|
||||
cThreadLocalImpl::cThreadLocalImpl() {
|
||||
mIndex = TlsAlloc();
|
||||
}
|
||||
|
||||
cThreadLocalImpl::~cThreadLocalImpl() {
|
||||
TlsFree(mIndex);
|
||||
}
|
||||
|
||||
void cThreadLocalImpl::Value(void* value) {
|
||||
TlsSetValue(mIndex, value);
|
||||
}
|
||||
|
||||
void* cThreadLocalImpl::Value() const {
|
||||
return TlsGetValue(mIndex);
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
30
src/eepp/system/platform/win/cthreadlocalimpl.hpp
Normal file
30
src/eepp/system/platform/win/cthreadlocalimpl.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef EE_SYSTEMCTHREADLOCALIMPLWIN_HPP
|
||||
#define EE_SYSTEMCTHREADLOCALIMPLWIN_HPP
|
||||
|
||||
#include <eepp/base.hpp>
|
||||
#include <eepp/base/noncopyable.hpp>
|
||||
|
||||
#if EE_PLATFORM == EE_PLATFORM_WIN
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace EE { namespace System { namespace Private {
|
||||
|
||||
class cThreadLocalImpl : NonCopyable {
|
||||
public:
|
||||
cThreadLocalImpl();
|
||||
|
||||
~cThreadLocalImpl();
|
||||
|
||||
void Value(void* value);
|
||||
|
||||
void* Value() const;
|
||||
private :
|
||||
DWORD mIndex;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -42,7 +42,7 @@ EE_MAIN_FUNC int main (int argc, char * argv [])
|
||||
cEngine::DestroySingleton();
|
||||
|
||||
// If was compiled in debug mode it will print the memory manager report
|
||||
EE::MemoryManager::ShowResults();
|
||||
MemoryManager::ShowResults();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ EE_MAIN_FUNC int main (int argc, char * argv [])
|
||||
|
||||
cEngine::DestroySingleton();
|
||||
|
||||
EE::MemoryManager::ShowResults();
|
||||
MemoryManager::ShowResults();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ EE_MAIN_FUNC int main (int argc, char * argv [])
|
||||
cEngine::DestroySingleton();
|
||||
|
||||
// If was compiled in debug mode it will print the memory manager report
|
||||
EE::MemoryManager::ShowResults();
|
||||
MemoryManager::ShowResults();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1,28 +1,44 @@
|
||||
#include <eepp/ee.hpp>
|
||||
|
||||
/// Entry point of application
|
||||
EE_MAIN_FUNC int main (int argc, char * argv [])
|
||||
{
|
||||
// Create a new HTTP client
|
||||
cHttp http;
|
||||
void AsyncRequestCallback( const cHttp& http, cHttp::Request& request, cHttp::Response& response ) {
|
||||
std::cout << "Got response from request: " << http.GetHostName() << request.GetUri() << std::endl;
|
||||
|
||||
// We'll work on http://www.wikipedia.org
|
||||
http.SetHost("http://www.wikipedia.org");
|
||||
|
||||
// Prepare a request to get the '/' page
|
||||
cHttp::Request request("/");
|
||||
|
||||
// Send the request
|
||||
cHttp::Response response = http.SendRequest(request);
|
||||
|
||||
// Check the status code and display the result
|
||||
cHttp::Response::Status status = response.GetStatus();
|
||||
|
||||
if ( status == cHttp::Response::Ok ) {
|
||||
if ( response.GetStatus() == cHttp::Response::Ok ) {
|
||||
std::cout << response.GetBody() << std::endl;
|
||||
} else {
|
||||
std::cout << "Error " << status << std::endl;
|
||||
std::cout << "Error " << response.GetStatus() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
EE_MAIN_FUNC int main (int argc, char * argv []) {
|
||||
{
|
||||
// Create a new HTTP client
|
||||
cHttp http;
|
||||
|
||||
// We'll work on http://en.wikipedia.org
|
||||
http.SetHost("http://en.wikipedia.org");
|
||||
|
||||
// Prepare a request to get the '/' page
|
||||
cHttp::Request request("/wiki/Main_Page");
|
||||
|
||||
// Send the request
|
||||
cHttp::Response response = http.SendRequest(request);
|
||||
|
||||
// Check the status code and display the result
|
||||
cHttp::Response::Status status = response.GetStatus();
|
||||
|
||||
if ( status == cHttp::Response::Ok ) {
|
||||
std::cout << response.GetBody() << std::endl;
|
||||
} else {
|
||||
std::cout << "Error " << status << std::endl;
|
||||
}
|
||||
|
||||
cHttp::Request asyncRequest( "/wiki/" + Version::GetCodename() );
|
||||
|
||||
http.SendAsyncRequest( cb::Make3( AsyncRequestCallback ), asyncRequest, Seconds( 5 ) );
|
||||
}
|
||||
|
||||
MemoryManager::ShowResults();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -642,7 +642,7 @@ EE_MAIN_FUNC int main (int argc, char * argv [])
|
||||
|
||||
cEngine::DestroySingleton();
|
||||
|
||||
EE::MemoryManager::ShowResults();
|
||||
MemoryManager::ShowResults();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ EE_MAIN_FUNC int main (int argc, char * argv [])
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
// If was compiled in debug mode it will print the memory manager report
|
||||
EE::MemoryManager::ShowResults();
|
||||
MemoryManager::ShowResults();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ EE_MAIN_FUNC int main (int argc, char * argv [])
|
||||
cEngine::DestroySingleton();
|
||||
|
||||
// If was compiled in debug mode it will print the memory manager report
|
||||
EE::MemoryManager::ShowResults();
|
||||
MemoryManager::ShowResults();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ EE_MAIN_FUNC int main (int argc, char * argv [])
|
||||
cEngine::DestroySingleton();
|
||||
|
||||
// If was compiled in debug mode it will print the memory manager report
|
||||
EE::MemoryManager::ShowResults();
|
||||
MemoryManager::ShowResults();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1952,7 +1952,7 @@ EE_MAIN_FUNC int main (int argc, char * argv []) {
|
||||
|
||||
eeDelete( Test );
|
||||
|
||||
EE::MemoryManager::ShowResults();
|
||||
MemoryManager::ShowResults();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user