Skip to content
Snippets Groups Projects
Commit bf454f3c authored by Sergey Linev's avatar Sergey Linev Committed by Philippe Canal
Browse files

http: allow to send web-socket data in extra threads

web socket engine should support this (default off) and
web socket handler have to allow this
parent d716a0ec
No related branches found
No related tags found
No related merge requests found
......@@ -39,6 +39,9 @@ protected:
THttpWSHandler(const char *name, const char *title);
/// Method called when multi-threaded send operation is completed
virtual void CompleteMTSend(UInt_t) {}
public:
virtual ~THttpWSHandler();
......@@ -49,6 +52,9 @@ public:
/// Used by the webcanvas
virtual TString GetDefaultPageContent() { return ""; }
/// Allow send operations in separate threads (when supported by websocket engine)
virtual Bool_t AllowMT() const { return kFALSE; }
/// Return kTRUE if websocket with given ID exists
Bool_t HasWS(UInt_t wsid) const { return FindEngine(wsid) != 0; }
......@@ -59,11 +65,11 @@ public:
void CloseWS(UInt_t wsid);
void SendWS(UInt_t wsid, const void *buf, int len);
Int_t SendWS(UInt_t wsid, const void *buf, int len);
void SendHeaderWS(UInt_t wsid, const char *hdr, const void *buf, int len);
Int_t SendHeaderWS(UInt_t wsid, const char *hdr, const void *buf, int len);
void SendCharStarWS(UInt_t wsid, const char *str);
Int_t SendCharStarWS(UInt_t wsid, const char *str);
virtual Bool_t ProcessWS(THttpCallArg *arg) = 0;
......
......@@ -16,11 +16,21 @@
#include "THttpCallArg.h"
class THttpWSHandler;
class THttpWSEngine {
private:
friend class THttpWSHandler;
bool fMTSend{false}; ///< true when multithreaded send operation is active
protected:
THttpWSEngine() = default;
/// Indicate if engine support send operation from different threads
virtual Bool_t SupportMT() const { return kFALSE; }
public:
virtual ~THttpWSEngine() {}
......
......@@ -14,6 +14,8 @@
#include "THttpWSEngine.h"
#include "THttpCallArg.h"
#include <thread>
/////////////////////////////////////////////////////////////////////////
///
/// THttpWSHandler
......@@ -184,33 +186,108 @@ void THttpWSHandler::CloseWS(UInt_t wsid)
////////////////////////////////////////////////////////////////////////////////
/// Send binary data via given websocket id
/// Returns -1 - in case of error,
/// 0 - when operation was executed immediately,
/// 1 - when send operation will be performed in different thread,
void THttpWSHandler::SendWS(UInt_t wsid, const void *buf, int len)
Int_t THttpWSHandler::SendWS(UInt_t wsid, const void *buf, int len)
{
THttpWSEngine *engine = FindEngine(wsid);
if (!engine) return -1;
if (engine)
if (engine->fMTSend) {
Error("SendWS", "Call next send operation before previous is completed");
return -1;
}
if (!AllowMT() || !engine->SupportMT()) {
engine->Send(buf, len);
return 0;
}
engine->fMTSend = true;
std::string argbuf((const char *)buf, len);
std::thread thrd([this, argbuf, engine] {
engine->Send(argbuf.data(), argbuf.length());
engine->fMTSend = false;
CompleteMTSend(engine->GetId());
});
thrd.detach(); // let continue thread execution without thread handle
return 1;
}
////////////////////////////////////////////////////////////////////////////////
/// Send binary data with text header via given websocket id
/// Returns -1 - in case of error,
/// 0 - when operation was executed immediately,
/// 1 - when send operation will be performed in different thread,
void THttpWSHandler::SendHeaderWS(UInt_t wsid, const char *hdr, const void *buf, int len)
Int_t THttpWSHandler::SendHeaderWS(UInt_t wsid, const char *hdr, const void *buf, int len)
{
THttpWSEngine *engine = FindEngine(wsid);
if (!engine) return -1;
if (engine)
if (engine->fMTSend) {
Error("SendHeaderWS", "Call next send operation before previous is completed");
return -1;
}
if (!AllowMT() || !engine->SupportMT()) {
engine->SendHeader(hdr, buf, len);
return 0;
}
engine->fMTSend = true;
std::string arghdr(hdr), argbuf((const char *) buf, len);
std::thread thrd([this, arghdr, argbuf, engine] {
engine->SendHeader(arghdr.c_str(), argbuf.data(), argbuf.length());
engine->fMTSend = false;
CompleteMTSend(engine->GetId());
});
thrd.detach(); // let continue thread execution without thread handle
return 1;
}
////////////////////////////////////////////////////////////////////////////////
/// Send string via given websocket id
/// Returns -1 - in case of error,
/// 0 - when operation was executed immediately,
/// 1 - when send operation will be performed in different thread,
void THttpWSHandler::SendCharStarWS(UInt_t wsid, const char *str)
Int_t THttpWSHandler::SendCharStarWS(UInt_t wsid, const char *str)
{
THttpWSEngine *engine = FindEngine(wsid);
if (!engine) return -1;
if (engine)
if (engine->fMTSend) {
Error("SendCharStarWS", "Call next send operation before previous is completed");
return -1;
}
if (!AllowMT() || !engine->SupportMT()) {
engine->SendCharStar(str);
return 0;
}
engine->fMTSend = true;
std::string arg(str);
std::thread thrd([this, arg, engine] {
engine->SendCharStar(arg.c_str());
engine->fMTSend = false;
CompleteMTSend(engine->GetId());
});
thrd.detach(); // let continue thread execution without thread handle
return 1;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment