handling GUI resource locks between event handler and boost::thread

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Lars Uffmann

    handling GUI resource locks between event handler and boost::thread

    I have this wxWidgets OnButtonClick event handler, that apparently holds
    a lock on all widgets in my form, but this event handler is supposed to
    end a thread in the background - while that thread is supposed to update
    widget content. So if I want to wait for the thread to end in the event
    handler, I have 2 threads waiting on each other - with the one in the
    background waiting to access the widget content.

    My current workaround is to introduce a boost::mutex, have the
    background thread acquire a lock on it upon start, release upon end, and
    the OnButtonClick event handler will check (or try to acquire and
    instantly release) the lock on that mutex to make sure the previous
    background thread has ended before starting a new one.

    The according code looks like this:

    boost::mutex mutexChecka;
    typedef boost::mutex::s coped_lock lockaChecka;

    void demonstrateFram eLock()
    {
    cout << "child thread: acquiring lock" << endl;
    lockaChecka lc (mutexChecka);
    cout << "child thread: got lock" << endl;

    sleep (1);
    cout << "child thread: taking a nap (2 seconds)" << endl;
    sleep (2);
    cout << "child thread: woke up!" << endl;

    cout << "child thread: mainWindow->txt1->GetValue = " <<
    mainWindow->txt1->GetValue() << endl;

    cout << "child thread: unlocking" << endl;
    lc.unlock();
    cout << "child thread: unlocked" << endl;

    cout << "child thread: thread finished" << endl;
    }

    void debuggingGUImai nFrame::OnToggl e( wxCommandEvent& event )
    {
    cout << "main thread: acquiring lock" << endl;
    lockaChecka lc (mutexChecka);
    cout << "main thread: got lock, unlocking" << endl;
    lc.unlock();
    cout << "main thread: unlocked" << endl;
    if (myThread) {
    cout << "main thread: deleting old thread" << endl;
    delete myThread;
    myThread = 0;
    }

    myThread = new boost::thread(& demonstrateFram eLock);
    cout << "main thread: sleeping 5 seconds" << endl;
    sleep (5);
    cout << "main thread: done sleeping" << endl;
    // myThread.join() ; // old code, never got this to work due to the lock
    on form controls
    cout << "main thread: thread finished" << endl;
    }

    This gets the job done, but it really doesn't seem very pretty to me -
    so being a newbie with thread programming, I would appreciate any
    comments on how to improve this code (which is, of course, incomplete
    and just the sample that remained after long hours of debugging).

    Thank you in advance!

    Lars
  • bytebro

    #2
    Re: handling GUI resource locks between event handler and

    On 11 Mar, 16:01, Lars Uffmann <a...@nurfuersp am.dewrote:
    I have this wxWidgets OnButtonClick event handler, that apparently holds
    a lock on all widgets in my form, but this event handler is supposed to
    <snip>
    boost::mutex mutexChecka;
    typedef boost::mutex::s coped_lock lockaChecka;
    wxWidgets have a support forum at http://wxforum.shadonet.com/ and
    boost have user support mailing lists at http://www.boost.org/more/mailing_lists.htm#users

    HTH.

    Comment

    • Lars Uffmann

      #3
      Re: handling GUI resource locks between event handler and boost::thread

      bytebro wrote:
      wxWidgets have a support forum at http://wxforum.shadonet.com/ and
      boost have user support mailing lists at http://www.boost.org/more/mailing_lists.htm#users
      HTH.
      No, not at all. You told me two things that I do already know, and btw.
      there is no newsgroup where boost is more on-topic than this one,
      because the boost mailing list - while having a newsgroup portal -
      doesn't allow posting via the latter.

      I guess I'll add a disclaimer in my signature saying which resource
      sites I know and which I do not :) Otherwise yes, your information would
      have been partially helpful - but a direct answer was what I was looking
      for.

      Thanks anyways,

      Lars

      Comment

      • Lars Uffmann

        #4
        SOLUTION: handling GUI resource locks between event handler and boost::thread

        Hey Paavo,

        I'll have to chew a bit on your example, doesn't seem so obvious to me -
        I haven't yet learned even nearly all aspects of C++.
        Put it in my "re-read" folder :)

        Meanwhile, I managed to solve my locking problem with the help of input
        from this thread, in the way stated below.

        Best Regards & thanks to everyone involved,

        Lars

        solution relevant code excerpt (missing includes and wxWidgets
        initialization) :
        /* *** */

        debuggingGUImai nFrame *mainWindow; // wxWidgets main window,
        // controls cmd1 (wxButton) and txt1 (wxTextCtrl)

        int glbSERVICING = 0; // "keepalive flag" for the background thread

        // mutex to ensure alternate access to window controls and glbSERVICING
        boost::mutex mutexChecka;

        typedef boost::mutex::s coped_lock lockaChecka;

        void demonstrateFram eLock()
        {
        sleep (1);
        cout << "child thread: acquiring lock" << endl;
        lockaChecka lc (mutexChecka);
        cout << "child thread: got lock, child thread: ready for servicing"
        << endl;
        mainWindow->cmd1->Enable();

        int i = 0;
        while (glbSERVICING) {
        lc.unlock(); // unlock r/w access to keepalive flag
        cout << "child thread: unlocked" << endl;
        ++i;
        sleep (2);
        cout << "child thread: servicing... (i = " << i << ")" << endl;
        lc.lock(); // prepare read access to keepalive flag
        cout << "child thread: got lock" << endl;
        }

        cout << "child thread: mainWindow->txt1->GetValue = " <<
        mainWindow->txt1->GetValue() << endl;
        mainWindow->cmd1->Enable();

        lc.unlock();
        cout << "child thread: unlocked, thread finished" << endl;
        }

        void debuggingGUImai nFrame::OnToggl e( wxCommandEvent& event )
        {
        cmd1->Disable();

        cout << "main thread: acquiring lock" << endl;
        lockaChecka lc (mutexChecka);
        cout << "main thread: got lock" << endl;

        if (glbSERVICING) {
        glbSERVICING = 0;
        mainWindow->cmd1->SetLabel (wxT ("Enable Service"));
        }
        else {
        glbSERVICING = 1;
        mainWindow->cmd1->SetLabel (wxT ("Disable Service"));
        boost::thread *helperThread;
        helperThread = new boost::thread(& demonstrateFram eLock);
        delete helperThread;
        helperThread = 0;
        }

        cout << "main thread: unlocking" << endl;
        lc.unlock();

        cout << "main thread: thread finished" << endl;
        }
        /* *** */

        Comment

        Working...