Skip to content

Commit 99b2844

Browse files
committed
net:http-server: improve data/cancel handler lifetime handling
1 parent 737fd7c commit 99b2844

File tree

3 files changed

+41
-20
lines changed

3 files changed

+41
-20
lines changed

code/components/net-http-server/include/HttpServer.h

+27-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "TcpServer.h"
1111

1212
#include <forward_list>
13+
#include <shared_mutex>
1314

1415
namespace net
1516
{
@@ -37,33 +38,53 @@ class HttpRequest : public fwRefCountable
3738

3839
HeaderMap m_headerList;
3940

40-
std::function<void(const std::vector<uint8_t>&)> m_dataHandler;
41+
std::shared_ptr<std::function<void(const std::vector<uint8_t>&)>> m_dataHandler;
4142

42-
std::function<void()> m_cancelHandler;
43+
std::shared_mutex m_dataHandlerMutex;
44+
45+
std::shared_ptr<std::function<void()>> m_cancelHandler;
46+
47+
std::shared_mutex m_cancelHandlerMutex;
4348

4449
public:
4550
HttpRequest(int httpVersionMajor, int httpVersionMinor, const std::string& requestMethod, const std::string& path, const HeaderMap& headerList, const std::string& remoteAddress);
4651

4752
virtual ~HttpRequest() override;
4853

49-
inline const std::function<void(const std::vector<uint8_t>& data)>& GetDataHandler() const
54+
inline std::shared_ptr<std::function<void(const std::vector<uint8_t>& data)>> GetDataHandler()
5055
{
56+
std::shared_lock<std::shared_mutex> lock(m_dataHandlerMutex);
5157
return m_dataHandler;
5258
}
5359

60+
inline void SetDataHandler()
61+
{
62+
std::unique_lock<std::shared_mutex> lock(m_dataHandlerMutex);
63+
m_dataHandler = {};
64+
}
65+
5466
inline void SetDataHandler(const std::function<void(const std::vector<uint8_t>& data)>& handler)
5567
{
56-
m_dataHandler = handler;
68+
std::unique_lock<std::shared_mutex> lock(m_dataHandlerMutex);
69+
m_dataHandler = std::make_shared<std::remove_const_t<std::remove_reference_t<decltype(handler)>>>(handler);
5770
}
5871

59-
inline const std::function<void()>& GetCancelHandler() const
72+
inline std::shared_ptr<std::function<void()>> GetCancelHandler()
6073
{
74+
std::shared_lock<std::shared_mutex> lock(m_cancelHandlerMutex);
6175
return m_cancelHandler;
6276
}
6377

78+
inline void SetCancelHandler()
79+
{
80+
std::unique_lock<std::shared_mutex> lock(m_cancelHandlerMutex);
81+
m_cancelHandler = {};
82+
}
83+
6484
inline void SetCancelHandler(const std::function<void()>& handler)
6585
{
66-
m_cancelHandler = handler;
86+
std::unique_lock<std::shared_mutex> lock(m_cancelHandlerMutex);
87+
m_cancelHandler = std::make_shared<std::remove_const_t<std::remove_reference_t<decltype(handler)>>>(handler);
6788
}
6889

6990
inline std::pair<int, int> GetHttpVersion() const

code/components/net-http-server/src/Http1Server.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -396,13 +396,13 @@ void HttpServerImpl::OnConnection(fwRefContainer<TcpServerStream> stream)
396396
readQueue.erase(readQueue.begin(), readQueue.begin() + contentLength);
397397

398398
// call the data handler
399-
auto& dataHandler = localConnectionData->request->GetDataHandler();
399+
auto dataHandler = localConnectionData->request->GetDataHandler();
400400

401401
if (dataHandler)
402402
{
403-
dataHandler(requestData);
403+
localConnectionData->request->SetDataHandler();
404404

405-
localConnectionData->request->SetDataHandler(std::function<void(const std::vector<uint8_t>&)>());
405+
(*dataHandler)(requestData);
406406
}
407407

408408
// clean up the req/res
@@ -460,15 +460,15 @@ void HttpServerImpl::OnConnection(fwRefContainer<TcpServerStream> stream)
460460
readQueue.erase(readQueue.begin(), readQueue.begin() + readQueue.size() - result);
461461

462462
// call the data handler
463-
auto& dataHandler = localConnectionData->request->GetDataHandler();
463+
auto dataHandler = localConnectionData->request->GetDataHandler();
464464

465465
if (dataHandler)
466466
{
467-
requestData.resize(localConnectionData->lastLength);
467+
localConnectionData->request->SetDataHandler();
468468

469-
dataHandler(requestData);
469+
requestData.resize(localConnectionData->lastLength);
470470

471-
localConnectionData->request->SetDataHandler(std::function<void(const std::vector<uint8_t>&)>());
471+
(*dataHandler)(requestData);
472472
}
473473

474474
// clean up the req/res
@@ -508,9 +508,9 @@ void HttpServerImpl::OnConnection(fwRefContainer<TcpServerStream> stream)
508508

509509
if (cancelHandler)
510510
{
511-
cancelHandler();
511+
(*cancelHandler)();
512512

513-
connectionData->request->SetCancelHandler(std::function<void()>());
513+
connectionData->request->SetCancelHandler();
514514
}
515515

516516
connectionData->request = nullptr;

code/components/net-http-server/src/Http2Server.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,13 @@ class Http2Response : public HttpResponse
126126
{
127127
if (m_request.GetRef() && !m_ended)
128128
{
129-
auto& cancelHandler = m_request->GetCancelHandler();
129+
auto cancelHandler = m_request->GetCancelHandler();
130130

131131
if (cancelHandler)
132132
{
133-
cancelHandler();
133+
(*cancelHandler)();
134134

135-
m_request->SetCancelHandler(std::function<void()>());
135+
m_request->SetCancelHandler();
136136
}
137137
}
138138

@@ -318,11 +318,11 @@ void Http2ServerImpl::OnConnection(fwRefContainer<TcpServerStream> stream)
318318
if (req->httpReq.GetRef())
319319
{
320320
auto handler = req->httpReq->GetDataHandler();
321-
req->httpReq->SetDataHandler({});
321+
req->httpReq->SetDataHandler();
322322

323323
if (handler)
324324
{
325-
handler(req->body);
325+
(*handler)(req->body);
326326
}
327327
}
328328
}

0 commit comments

Comments
 (0)