cmake-gui: Improve interrupt granularity to fix bug 12649.

Instead of enabling interrupt only when a progress or message callback is called, add a new callback specifically for
interrupt.  This new callback is called from GetFatalErrorOccured() so cmake-gui can immediately report interrupt status
instead of calling queuing a call to cmSystemTools::SetFatalErrorOccured() and waiting for the progress or message
callback to be called to process that queued call.
This commit is contained in:
Clinton Stimpson 2012-01-02 11:07:43 -07:00
parent 40aedcbbae
commit 131eed6607
6 changed files with 43 additions and 7 deletions

View File

@ -10,11 +10,11 @@
# See the License for more information.
#=============================================================================
PROJECT(QtDialog)
SET(QT_MIN_VERSION "4.3.0")
SET(QT_MIN_VERSION "4.4.0")
FIND_PACKAGE(Qt4 REQUIRED)
IF(NOT QT4_FOUND)
MESSAGE(SEND_ERROR "Failed to find Qt 4.3 or greater.")
MESSAGE(SEND_ERROR "Failed to find Qt 4.4 or greater.")
ELSE(NOT QT4_FOUND)
INCLUDE(${QT_USE_FILE})

View File

@ -554,8 +554,7 @@ void CMakeSetupDialog::doHelp()
void CMakeSetupDialog::doInterrupt()
{
this->enterState(Interrupting);
QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
"interrupt", Qt::QueuedConnection);
this->CMakeThread->cmakeInstance()->interrupt();
}
void CMakeSetupDialog::doSourceBrowse()

View File

@ -63,6 +63,8 @@ QCMake::QCMake(QObject* p)
#endif
this->CMakeInstance->SetProgressCallback(QCMake::progressCallback, this);
cmSystemTools::SetInterruptCallback(QCMake::interruptCallback, this);
std::vector<std::string> generators;
this->CMakeInstance->GetRegisteredGenerators(generators);
std::vector<std::string>::iterator iter;
@ -170,6 +172,7 @@ void QCMake::configure()
this->CMakeInstance->SetWarnUnused(this->WarnUnusedMode);
this->CMakeInstance->PreLoadCMakeFiles();
InterruptFlag = 0;
cmSystemTools::ResetErrorOccuredFlag();
int err = this->CMakeInstance->Configure();
@ -188,7 +191,9 @@ void QCMake::generate()
UINT lastErrorMode = SetErrorMode(0);
#endif
InterruptFlag = 0;
cmSystemTools::ResetErrorOccuredFlag();
int err = this->CMakeInstance->Generate();
#ifdef Q_OS_WIN
@ -337,7 +342,13 @@ QCMakePropertyList QCMake::properties() const
void QCMake::interrupt()
{
cmSystemTools::SetFatalErrorOccured();
this->InterruptFlag.ref();
}
bool QCMake::interruptCallback(void* cd)
{
QCMake* self = reinterpret_cast<QCMake*>(cd);
return self->InterruptFlag;
}
void QCMake::progressCallback(const char* msg, float percent, void* cd)

View File

@ -23,6 +23,7 @@
#include <QList>
#include <QStringList>
#include <QMetaType>
#include <QAtomicInt>
class cmake;
@ -78,7 +79,7 @@ public slots:
void generate();
/// set the property values
void setProperties(const QCMakePropertyList&);
/// interrupt the configure or generate process
/// interrupt the configure or generate process (if connecting, make a direct connection)
void interrupt();
/// delete the cache in binary directory
void deleteCache();
@ -133,6 +134,7 @@ signals:
protected:
cmake* CMakeInstance;
static bool interruptCallback(void*);
static void progressCallback(const char* msg, float percent, void* cd);
static void errorCallback(const char* msg, const char* title,
bool&, void* cd);
@ -145,6 +147,7 @@ protected:
QString Generator;
QStringList AvailableGenerators;
QString CMakeExecutable;
QAtomicInt InterruptFlag;
};
#endif // __QCMake_h

View File

@ -131,6 +131,8 @@ void (*cmSystemTools::s_ErrorCallback)(const char*, const char*,
void (*cmSystemTools::s_StdoutCallback)(const char*, int len, void*);
void* cmSystemTools::s_ErrorCallbackClientData = 0;
void* cmSystemTools::s_StdoutCallbackClientData = 0;
bool (*cmSystemTools::s_InterruptCallback)(void*);
void* cmSystemTools::s_InterruptCallbackClientData = 0;
// replace replace with with as many times as it shows up in source.
// write the result into source.
@ -220,6 +222,20 @@ void cmSystemTools::Error(const char* m1, const char* m2,
cmSystemTools::Message(message.c_str(),"Error");
}
void cmSystemTools::SetInterruptCallback(InterruptCallback f, void* clientData)
{
s_InterruptCallback = f;
s_InterruptCallbackClientData = clientData;
}
bool cmSystemTools::GetInterruptFlag()
{
if(s_InterruptCallback)
{
return (*s_InterruptCallback)(s_InterruptCallbackClientData);
}
return false;
}
void cmSystemTools::SetErrorCallback(ErrorCallback f, void* clientData)
{

View File

@ -78,6 +78,11 @@ public:
///! Send a string to stderr. Stdout callbacks will not be invoced.
static void Stderr(const char* s, int length);
typedef bool (*InterruptCallback)(void*);
static void SetInterruptCallback(InterruptCallback f, void* clientData=0);
static bool GetInterruptFlag();
///! Return true if there was an error at any point.
static bool GetErrorOccuredFlag()
{
@ -96,7 +101,7 @@ public:
///! Return true if there was an error at any point.
static bool GetFatalErrorOccured()
{
return cmSystemTools::s_FatalErrorOccured;
return cmSystemTools::s_FatalErrorOccured || GetInterruptFlag();
}
///! Set the error occured flag and fatal error back to false
@ -467,8 +472,10 @@ private:
static bool s_DisableRunCommandOutput;
static ErrorCallback s_ErrorCallback;
static StdoutCallback s_StdoutCallback;
static InterruptCallback s_InterruptCallback;
static void* s_ErrorCallbackClientData;
static void* s_StdoutCallbackClientData;
static void* s_InterruptCallbackClientData;
static std::string s_Windows9xComspecSubstitute;
};