mirror of
https://gitee.com/an-tao/drogon.git
synced 2024-12-04 12:47:42 +08:00
commit
97667f358e
@ -13,18 +13,12 @@
|
||||
|
||||
#pragma once
|
||||
#include <drogon/config.h>
|
||||
#include <shared_mutex>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
|
||||
#if (CXX_STD > 14)
|
||||
typedef std::shared_mutex SharedMutex;
|
||||
#else
|
||||
typedef std::shared_timed_mutex SharedMutex;
|
||||
#endif
|
||||
|
||||
enum HttpStatusCode
|
||||
{
|
||||
//rfc2616-6.1.1
|
||||
@ -115,22 +109,4 @@ enum HttpMethod
|
||||
Invalid
|
||||
};
|
||||
|
||||
class SpinLock
|
||||
{
|
||||
public:
|
||||
SpinLock(std::atomic_flag &flag) : _flag(flag)
|
||||
{
|
||||
while (_flag.test_and_set(std::memory_order_acquire))
|
||||
{
|
||||
}
|
||||
}
|
||||
~SpinLock()
|
||||
{
|
||||
_flag.clear(std::memory_order_release);
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic_flag &_flag;
|
||||
};
|
||||
|
||||
} // namespace drogon
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "HttpRequestImpl.h"
|
||||
#include "HttpResponseImpl.h"
|
||||
#include "HttpAppFrameworkImpl.h"
|
||||
#include "SpinLock.h"
|
||||
|
||||
using namespace drogon;
|
||||
|
||||
@ -219,7 +220,7 @@ void HttpControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlBinderP
|
||||
{
|
||||
HttpResponsePtr responsePtr;
|
||||
{
|
||||
SpinLock guard(ctrlBinderPtr->_binderMtx);
|
||||
SimpleSpinLock guard(ctrlBinderPtr->_binderMtx);
|
||||
responsePtr = ctrlBinderPtr->_responsePtr;
|
||||
}
|
||||
|
||||
@ -282,7 +283,7 @@ void HttpControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlBinderP
|
||||
//cache the response;
|
||||
std::dynamic_pointer_cast<HttpResponseImpl>(resp)->makeHeaderString();
|
||||
{
|
||||
SpinLock guard(ctrlBinderPtr->_binderMtx);
|
||||
SimpleSpinLock guard(ctrlBinderPtr->_binderMtx);
|
||||
ctrlBinderPtr->_responsePtr = resp;
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ class HttpControllersRouter : public trantor::NonCopyable
|
||||
std::vector<std::shared_ptr<HttpFilterBase>> _filters;
|
||||
std::vector<size_t> _parameterPlaces;
|
||||
std::map<std::string, size_t> _queryParametersPlaces;
|
||||
//std::atomic<bool> _binderMtx = ATOMIC_VAR_INIT(false);
|
||||
std::atomic_flag _binderMtx = ATOMIC_FLAG_INIT;
|
||||
std::shared_ptr<HttpResponse> _responsePtr;
|
||||
};
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "HttpAppFrameworkImpl.h"
|
||||
#include "HttpResponseImpl.h"
|
||||
#include "SpinLock.h"
|
||||
#include <drogon/HttpViewBase.h>
|
||||
#include <drogon/HttpViewData.h>
|
||||
#include <drogon/HttpAppFramework.h>
|
||||
@ -350,14 +351,14 @@ std::shared_ptr<std::string> HttpResponseImpl::renderToString() const
|
||||
_httpStringDate = now.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC;
|
||||
auto newDate = getHttpFullDate(now);
|
||||
{
|
||||
SpinLock lock(*_httpStringMutex);
|
||||
SimpleSpinLock lock(*_httpStringMutex);
|
||||
_httpString = std::make_shared<std::string>(*_httpString);
|
||||
memcpy((void *)&(*_httpString)[_datePos], newDate, strlen(newDate));
|
||||
return _httpString;
|
||||
}
|
||||
}
|
||||
{
|
||||
SpinLock lock(*_httpStringMutex);
|
||||
SimpleSpinLock lock(*_httpStringMutex);
|
||||
return _httpString;
|
||||
}
|
||||
}
|
||||
@ -393,7 +394,7 @@ std::shared_ptr<std::string> HttpResponseImpl::renderToString() const
|
||||
httpString->append(*_bodyPtr);
|
||||
if (_expriedTime >= 0)
|
||||
{
|
||||
SpinLock lock(*_httpStringMutex);
|
||||
SimpleSpinLock lock(*_httpStringMutex);
|
||||
_datePos = datePos;
|
||||
_httpString = httpString;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ class HttpResponseImpl : public HttpResponse
|
||||
_leftBodyLength(0),
|
||||
_currentChunkLength(0),
|
||||
_bodyPtr(new std::string()),
|
||||
_httpStringMutex(new std::atomic_flag())
|
||||
_httpStringMutex(new std::atomic_flag)
|
||||
{
|
||||
_httpStringMutex->clear();
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "FiltersFunction.h"
|
||||
#include "HttpSimpleControllersRouter.h"
|
||||
#include "HttpAppFrameworkImpl.h"
|
||||
#include "SpinLock.h"
|
||||
|
||||
using namespace drogon;
|
||||
|
||||
@ -126,7 +127,7 @@ void HttpSimpleControllersRouter::doControllerHandler(SimpleControllerRouterItem
|
||||
HttpResponsePtr responsePtr;
|
||||
{
|
||||
//Maybe update the _responsePtr, so we use shared_lock to protect;
|
||||
SpinLock guard(item._mutex);
|
||||
SimpleSpinLock guard(item._mutex);
|
||||
responsePtr = item._responsePtr;
|
||||
}
|
||||
if (responsePtr && (responsePtr->expiredTime() == 0 || (trantor::Date::now() < responsePtr->creationDate().after(responsePtr->expiredTime()))))
|
||||
@ -154,7 +155,7 @@ void HttpSimpleControllersRouter::doControllerHandler(SimpleControllerRouterItem
|
||||
//cache the response;
|
||||
std::dynamic_pointer_cast<HttpResponseImpl>(resp)->makeHeaderString();
|
||||
{
|
||||
SpinLock guard(item._mutex);
|
||||
SimpleSpinLock guard(item._mutex);
|
||||
item._responsePtr = resp;
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ class HttpSimpleControllersRouter : public trantor::NonCopyable
|
||||
std::vector<int> _validMethodsFlags;
|
||||
std::shared_ptr<HttpSimpleControllerBase> _controller;
|
||||
std::shared_ptr<HttpResponse> _responsePtr;
|
||||
//std::atomic<bool> _mutex = ATOMIC_VAR_INIT(false);
|
||||
std::atomic_flag _mutex = ATOMIC_FLAG_INIT;
|
||||
};
|
||||
std::unordered_map<std::string, SimpleControllerRouterItem> _simpCtrlMap;
|
||||
|
86
lib/src/SpinLock.h
Normal file
86
lib/src/SpinLock.h
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* SpinLock.h
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <emmintrin.h>
|
||||
|
||||
#define LOCK_SPIN 2048
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
|
||||
class SpinLock
|
||||
{
|
||||
public:
|
||||
inline SpinLock(std::atomic<bool> &flag)
|
||||
: _flag(flag)
|
||||
{
|
||||
const static int cpu = std::thread::hardware_concurrency();
|
||||
int n, i;
|
||||
while (1)
|
||||
{
|
||||
if (!_flag.load() && !_flag.exchange(true, std::memory_order_acquire))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (cpu > 1)
|
||||
{
|
||||
for (n = 1; n < LOCK_SPIN; n <<= 1)
|
||||
{
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
//__asm__ __volatile__("rep; nop" ::: "memory"); //pause
|
||||
_mm_pause();
|
||||
}
|
||||
if (!_flag.load() && !_flag.exchange(true, std::memory_order_acquire))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
inline ~SpinLock()
|
||||
{
|
||||
_flag.store(false, std::memory_order_release);
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic<bool> &_flag;
|
||||
};
|
||||
|
||||
class SimpleSpinLock
|
||||
{
|
||||
public:
|
||||
inline SimpleSpinLock(std::atomic_flag &flag)
|
||||
: _flag(flag)
|
||||
{
|
||||
while (_flag.test_and_set(std::memory_order_acquire))
|
||||
{
|
||||
//__asm__ __volatile__("rep; nop" ::: "memory"); //pause
|
||||
_mm_pause();
|
||||
}
|
||||
}
|
||||
inline ~SimpleSpinLock()
|
||||
{
|
||||
_flag.clear(std::memory_order_release);
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic_flag &_flag;
|
||||
};
|
||||
|
||||
} // namespace drogon
|
@ -22,12 +22,20 @@
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
namespace orm
|
||||
{
|
||||
|
||||
#if (CXX_STD > 14)
|
||||
typedef std::shared_mutex SharedMutex;
|
||||
#else
|
||||
typedef std::shared_timed_mutex SharedMutex;
|
||||
#endif
|
||||
|
||||
enum ConnectStatus
|
||||
{
|
||||
ConnectStatus_None = 0,
|
||||
|
Loading…
Reference in New Issue
Block a user