Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
webgui: try to cancel all updates and commands when connection closing
  • Loading branch information
linev committed Jul 27, 2017
commit be77577ff01a92c24d704f17e81d8a74934edb01
67 changes: 62 additions & 5 deletions gui/canvaspainter/v7/src/TCanvasPainter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ class TCanvasPainter : public THttpWSHandler,
std::string fArg; ///<! command arg
bool fRunning; ///<! true when command submitted
ROOT::Experimental::CanvasCallback_t fCallback; ///<! callback function associated with command
WebCommand() : fId(), fName(), fArg(), fRunning(false), fCallback() {}
UInt_t fConnId; ///<! connection id was used to send command
WebCommand() : fId(), fName(), fArg(), fRunning(false), fCallback(), fConnId(0) {}
};

struct WebUpdate {
Expand Down Expand Up @@ -238,6 +239,10 @@ class TCanvasPainter : public THttpWSHandler,

virtual Bool_t ProcessWS(THttpCallArg *arg);

void CancelCommands(bool cancel_all, UInt_t connid = 0);

void CancelUpdates();

public:
/// Create a TVirtualCanvasPainter for the given canvas.
/// The painter observes it; it needs to know should the TCanvas be deleted.
Expand All @@ -249,6 +254,12 @@ class TCanvasPainter : public THttpWSHandler,
gServer->Register("/web7gui", this);
}

virtual ~TCanvasPainter()
{
CancelCommands(true);
CancelUpdates();
}

virtual bool IsBatchMode() const { return fBatchMode; }

virtual void AddDisplayItem(ROOT::Experimental::TDisplayItem *item) final;
Expand Down Expand Up @@ -411,7 +422,8 @@ void TCanvasPainter::CanvasUpdated(uint64_t ver, bool async, ROOT::Experimental:
{
if (ver && fSnapshotDelivered && (ver <= fSnapshotDelivered)) {
// if given canvas version was already delivered to clients, can return immediately
if (callback) callback(true);
if (callback)
callback(true);
return;
}

Expand Down Expand Up @@ -514,6 +526,38 @@ void TCanvasPainter::PopFrontCommand(bool result)
fCmds.pop_front();
}

/////////////////////////////////////////////////////////////////////////////////////////////
/// Cancel commands for given connection ID
/// Invoke all callbacks

void TCanvasPainter::CancelCommands(bool cancel_all, UInt_t connid)
{
auto iter = fCmds.begin();
while (iter != fCmds.end()) {
auto next = iter;
next++;
if (cancel_all || (iter->fConnId == connid)) {
iter->fCallback(false);
fCmds.erase(iter);
}
}
}

/////////////////////////////////////////////////////////////////////////////////////////////
/// Cancel all pending Canvas::Update()

void TCanvasPainter::CancelUpdates()
{
fSnapshotDelivered = 0;
auto iter = fUpdatesLst.begin();
while (iter != fUpdatesLst.end()) {
auto curr = iter;
iter++;
curr->fCallback(false);
fUpdatesLst.erase(curr);
}
}

/////////////////////////////////////////////////////////////////////////////////////////////
/// Process reply of first command in the queue
/// For the moment commands use to create image files
Expand Down Expand Up @@ -599,14 +643,23 @@ Bool_t TCanvasPainter::ProcessWS(THttpCallArg *arg)

printf("Connection closed\n");

UInt_t connid = 0;

if (conn && conn->fHandle) {
connid = conn->fHandle->GetId();
conn->fHandle->ClearHandle();
delete conn->fHandle;
conn->fHandle = 0;
}

if (conn)
fWebConn.erase(iter);

// if there are no other connections - cancel all submitted commands
CancelCommands((fWebConn.size() == 0), connid);

CheckDataToSend(); // check if data should be send via other connections

return kTRUE;
}

Expand Down Expand Up @@ -704,6 +757,7 @@ void TCanvasPainter::CheckDataToSend()
buf.Append(cmd.fId);
buf.Append(":");
buf.Append(cmd.fName);
cmd.fConnId = conn.fHandle->GetId();
} else if (!conn.fGetMenu.empty()) {
ROOT::Experimental::Internal::TDrawable *drawable = FindDrawable(fCanvas, conn.fGetMenu);

Expand Down Expand Up @@ -739,19 +793,22 @@ void TCanvasPainter::CheckDataToSend()
}
}

// if there are updates submitted, but all connections disappeared - cancel all updates
if ((fWebConn.size() == 0) && fSnapshotDelivered)
return CancelUpdates();

if (fSnapshotDelivered != min_delivered) {
fSnapshotDelivered = min_delivered;

auto iter = fUpdatesLst.begin();
while (iter != fUpdatesLst.end()) {
auto curr = iter; iter++;
auto curr = iter;
iter++;
if (curr->fVersion <= fSnapshotDelivered) {
curr->fCallback(true);
fUpdatesLst.erase(curr);
}
}

// one could call-back canvas methods here
}
}

Expand Down