[CMake] Interrupt problems in cmake-gui

Clinton Stimpson clinton at elemtech.com
Fri Dec 30 23:18:58 EST 2011


Yeah it does look like synchronization is needed to fix this.  The current interrupt functionality depends on message output or progress reporting to actually process the interrupt on the worker thread, which isn't good enough.

I'm not sure if you've considered this, but it seems simpler to add an interrupt callback in cmSystemTools, much like the callbacks work for stdout/stderr.  Then cmake-gui could register an interrupt callback and coordinate that with the button click.  The synchronization of a simple flag can then be handled within cmake-gui using QAtomicInt.

Clint

On Dec 30, 2011, at 6:10 PM, Robert Dailey wrote:

> I don't know much about Qt, but what I do know is the fix involves using a direct connection. In CMakeSetupDialog::doInterrupt(), I changed the invokeMethod() command to use Qt::DirectConnection.
> 
> However, this solution is not thread safe, hence why I asked about synchronization. I could implement a multiple-reader/single-writer lock, but I'd much rather use Boost.Thread, but this would require introducing the boost library into the cmake build.
> 
> The following methods in cmSystemTools need to be made thread-safe (using a combination of read locks & writer locks). Qt has a reader/writer lock but I can't use this in cmSystemTools, since it will require cmake.exe to depend on Qt, which doesn't make much sense.
> 
> GetErrorOccuredFlag()
> SetFatalErrorOccured()
> GetFatalErrorOccured()
> ResetErrorOccuredFlag()
> 
> I was thinking of turning cmSystemTools into a singleton (you would have a static instance() method and access members through that) and using inheritance to implement a thread-safe variant of this class. I could create thread-safe overrides the above methods and utilize polymorphism to access the thread safe version in cmake-gui, whereas cmake.exe would not use it, since by itself it does not need it.
> 
> I'd like to introduce boost into CMake for this.
> 
> If you can find a better implementation that'd be great, I haven't been working with the CMake code base as long as you guys have, so you probably know an easier fix. The main issue is that the blocking functions (such as while, foreach) do not return control to Qt until after they are done executing, and the only way to reliably interrupt them is by setting the fatal error flag. It requires no additional interrupt logic. These are the findings of my investigation and debugging.
> 
> Thanks in advance for your input.
> 
> ---------
> Robert Dailey
> 
> 
> On Fri, Dec 30, 2011 at 12:53 PM, clinton at elemtech.com <clinton at elemtech.com> wrote:
> There isn't a lock.
> 
> Synchronization is done by threads having event loops and calling Qt slots in a queued fashion (like posting messages to the other event queue).
> 
> I imagine you just need to add another place where the interrupt is checked and gracefully return (which should take you back to the event loop).
> 
> Clint
> 
> 
> ----- Reply message -----
> From: "Robert Dailey" <rcdailey at gmail.com>
> Date: Fri, Dec 30, 2011 10:07 am
> Subject: [CMake] Interrupt problems in cmake-gui
> To: "CMake ML" <cmake at cmake.org>
> 
> I found the problem in code and currently have a fix. However, the code change requires some thread synchronization. Does anyone know if there is a reader/writer lock object in the CMake source code?
> 
> ---------
> Robert Dailey
> 
> 
> On Fri, Dec 30, 2011 at 9:58 AM, Robert Dailey <rcdailey at gmail.com> wrote:
> I have a foreach/while loop that checks if files exist. The files it is checking are on a Windows network share. So, each check takes a while. Sometimes after I click "Configure" in cmake-gui.exe, I want to click "Stop" during this check. However, the stop does not seem to interrupt the loop. I know this because let's say the whole loop takes 20 seconds to complete. If I let the loop run without clicking stop, it takes 20 seconds. If I click stop at about 10 seconds, then 10 seconds later it stops. In other words, clicking stop does not take affect until 20 seconds have passed anyway. So it obviously isn't stopping it. My loops basically look like this:
> 
> while()
>    foreach()
>       if( EXISTS )
>       endif()
>    endforeach()
> endwhile()
> 
> If I am checking 20 files, each check takes about 1 second to equal a total time of 20 seconds. So, at most, after clicking stop, there should be a 1 second wait time.
> 
> Can anyone verify that while/foreach loops can or cannot be interrupted by cmake-gui?
> 
> ---------
> Robert Dailey
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20111230/48767c6d/attachment.htm>


More information about the CMake mailing list