Qlistview - review question QT 4.8 / VC2010



  • Hi All,

    I had a race condition in one of my projects hunting down to a update race condition in the
    qlistview(.cpp). After I change my Windows environment from VC2008 to VC2010 and QT 4.8.

    My problem is solved but I wondering about this code snip set below

    @
    int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wrap) const
    {
    QVector<int> positions;
    if (wrap)
    positions = segmentPositions;
    else if (!flowPositions.isEmpty()) {
    positions.reserve(scrollValueMap.size());
    foreach (int itemShown, scrollValueMap)
    positions.append(flowPositions.at(itemShown));
    }
    @

    The flowPositions vector is checked to be not empty .. but later in the foreach-iterator
    step over the scrollValueMap? Is this correct ??
    (In my race scrollValueMap had more entries than flowPositions)

    regards
    Chris



  • Hi All... oh its getting more worse.

    Today I play around and catch something related to the question I ask before.
    It might be related to the VC2010SP1 cause on my Linux port it never happen.

    again line 9 of the posting before.

    itemShown = 1
    d->size = 4
    in Q_ASSERT_X( i >= 0 && i < d->size ..

    QtCored4.dll!qFatal(const char * msg, ...) Line 2481 + 0xf bytes C++
    QtCored4.dll!qt_assert_x(const char * where, const char * what, const char * file, int line) Line 2007 + 0x1a bytes C++
    QtGuid4.dll!QVector<int>::at(int i) Line 351 + 0x44 bytes C++
    QtGuid4.dll!QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wrap) Line 2528 + 0xf bytes C++
    QtGuid4.dll!QListModeViewBase::updateVerticalScrollBar(const QSize & step) Line 2098 + 0x31 bytes C++
    QtGuid4.dll!QListView::updateGeometries() Line 1487 C++
    QtGuid4.dll!QAbstractItemView::doItemsLayout() Line 1165 C++ QtGuid4.dll!QListView::doItemsLayout() Line 1469 C++
    QtGuid4.dll!QAbstractItemView::timerEvent(QTimerEvent * event) Line 2443 C++

    Condition not match obviously

    @
    52335640 push ebp
    52335641 mov ebp,esp
    52335643 sub esp,8
    52335646 mov dword ptr [ebp-4],ecx
    52335649 cmp dword ptr [i],0 i=1
    5233564D jl QVector<int>::at+2Ah (5233566Ah)
    5233564F mov eax,dword ptr [this]
    52335652 mov ecx,dword ptr [eax]
    52335654 mov edx,dword ptr [i]
    52335657 cmp edx,dword ptr [ecx+8]
    5233565A jge QVector<int>::at+2Ah (5233566Ah)
    5233565C call qt_noop (522A5333h)
    52335661 mov dword ptr [ebp-8],0
    52335668 jmp QVector<int>::at+4Eh (5233568Eh)
    5233566A push 15Fh
    5233566F push offset string "c:\iwmake\build_vs2010_opensourc"... (52CE82A0h)
    52335674 push offset string "index out of range" (52CE4AB8h)
    52335679 push offset string "QVector<T>::at" (52CE8288h)
    5233567E call dword ptr [__imp_qt_assert_x (5302206Ch)]
    52335684 add esp,10h
    52335687 mov dword ptr [ebp-8],0
    @

    ASK ME QUESTIONS!

    Chris



  • Night is over and I worked out the reason.

    Trigger the problem: ( worked with VC2008, QT4.7 , and NOT with VC2010, QT4.8 )
    @
    private slot:
    function_print( a, b) // update a qviewlist
    public:
    forwardfunction(a,b) { function_print(a,b); }
    @

    the public function direct calls the slot ! QASSERT_X() !

    Rewrite it to use a signal ( work with VC2010, QT4.8 )
    @
    signal:
    myforwardsig(a,b)

    public:
    forwardfunction(a,b) {myforwardsig(a,b);}
    @

    code:
    @
    connect(this,SIGNAL(myforwardsig(a,b)),this,SLOT(function_print(a,b)));
    @

    hope that helps other people step in the same pitfall

    Chris



  • I cannot follow, in your old code, were you using non signal member function as a signal by intention?
    I believe your old code may complains signal/slot not found blah blah error in debug message.
    Would you please tell me more detail?



  • Hi,

    no the code not complain any missing signal/slot the private slot is in use for inter thread communication.

    In the 4.7 version I called the slot-function in via public method [update] ( IN THE MAIN-THREAD ) [/update].

    But a bit more details up front to light up the scenario.
    In my case a second thread is using this signal/slot too to deliver messages to the main-thread's qlistview, synchronized with a mutex. But there was a need to write messages from main-thread to the same qlistview as well synchronized. Therefore I write a public-method around and call the slot function. This works fine with 4.7. BUT I always pass by the Event-handler in this way and cause of the VC2010 or QT4.8 (what I not know at this time) I run into race condition in the screen update.

    With the signal method the message queued in and the Event-handler of the main-thread take care of
    the serialization.

    Chris



  • You must not call GUI related code in the main thread from another thread.

    If you use signals/slots, the connection is made as QueuedConnection, so it works then.



  • Hi Volker,

    the public method was called within the main-thread , the other worker-thread used signal to deliver its content.
    Written in black and white: GUI Classes are not thread safe ;-)

    How is Berlin doing? I expect you had been at this great Party "am Tor" ..
    I had 11 degrees inside the flat this morning .. and my fingers turns a bit blue while I type this lines.

    Chris



  • Using threads, it's easy to run into trouble and calling a slot with the wrong thread affinity (depending on your thread implementation). Make sure to study "Threads, Events and QObjects":/wiki/Threads_Events_QObjects in the wiki.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.