forked from qt-creator/qt-creator
CDB extension: Introduce StateNotificationBlocker.
Use RAI instead of manual bookkeeping when temporarily blocking the state notifications of the extension context. Change-Id: I991a3f0ddc578058f6bce173b4fc68ce567627ab Reviewed-by: David Schulz <david.schulz@digia.com>
This commit is contained in:
@@ -53,6 +53,29 @@ Parameters::Parameters() : maxStringLength(10000), maxStackDepth(1000)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! \class StateNotificationBlocker
|
||||||
|
|
||||||
|
Blocks state (stopped) notification of ExtensionContext while instantiated
|
||||||
|
|
||||||
|
\ingroup qtcreatorcdbext
|
||||||
|
*/
|
||||||
|
|
||||||
|
class StateNotificationBlocker {
|
||||||
|
StateNotificationBlocker(const StateNotificationBlocker &);
|
||||||
|
StateNotificationBlocker &operator=(const StateNotificationBlocker &);
|
||||||
|
|
||||||
|
public:
|
||||||
|
StateNotificationBlocker(ExtensionContext *ec)
|
||||||
|
: m_oldValue(ec->stateNotification())
|
||||||
|
, m_extensionContext(ec)
|
||||||
|
{ m_extensionContext->setStateNotification(false); }
|
||||||
|
~StateNotificationBlocker() { m_extensionContext->setStateNotification(m_oldValue); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const bool m_oldValue;
|
||||||
|
ExtensionContext *m_extensionContext;
|
||||||
|
};
|
||||||
|
|
||||||
/*! \class ExtensionContext
|
/*! \class ExtensionContext
|
||||||
|
|
||||||
Global singleton with context.
|
Global singleton with context.
|
||||||
@@ -350,18 +373,15 @@ bool ExtensionContext::call(const std::string &functionCall,
|
|||||||
}
|
}
|
||||||
// Wait until finished
|
// Wait until finished
|
||||||
startRecordingOutput();
|
startRecordingOutput();
|
||||||
m_stateNotification = false;
|
StateNotificationBlocker blocker(this);
|
||||||
m_control->WaitForEvent(0, INFINITE);
|
m_control->WaitForEvent(0, INFINITE);
|
||||||
*output = stopRecordingOutput();
|
*output = stopRecordingOutput();
|
||||||
m_stateNotification = true;
|
|
||||||
// Crude attempt at recovering from a crash: Issue 'gN' (go with exception not handled).
|
// Crude attempt at recovering from a crash: Issue 'gN' (go with exception not handled).
|
||||||
const bool crashed = output->find(L"This exception may be expected and handled.") != std::string::npos;
|
const bool crashed = output->find(L"This exception may be expected and handled.") != std::string::npos;
|
||||||
if (crashed) {
|
if (crashed) {
|
||||||
m_stopReason.clear();
|
m_stopReason.clear();
|
||||||
m_stateNotification = false;
|
|
||||||
hr = m_control->Execute(DEBUG_OUTCTL_ALL_CLIENTS, "~. gN", DEBUG_EXECUTE_ECHO);
|
hr = m_control->Execute(DEBUG_OUTCTL_ALL_CLIENTS, "~. gN", DEBUG_EXECUTE_ECHO);
|
||||||
m_control->WaitForEvent(0, INFINITE);
|
m_control->WaitForEvent(0, INFINITE);
|
||||||
m_stateNotification = true;
|
|
||||||
*errorMessage = "A crash occurred while calling: " + functionCall;
|
*errorMessage = "A crash occurred while calling: " + functionCall;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,9 @@ public:
|
|||||||
const Parameters ¶meters() const { return m_parameters; }
|
const Parameters ¶meters() const { return m_parameters; }
|
||||||
Parameters ¶meters() { return m_parameters; }
|
Parameters ¶meters() { return m_parameters; }
|
||||||
|
|
||||||
|
bool stateNotification() const { return m_stateNotification; }
|
||||||
|
void setStateNotification(bool s) { m_stateNotification = s; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isInitialized() const;
|
bool isInitialized() const;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user