Menu

Closing a docker cause a never ending process hang

Help
2015-01-14
2015-01-31
  • TorstenEschner

    TorstenEschner - 2015-01-14

    I've an application based on the DockTabbedMDI sample. The application add new Dockers on the right side, here the new Dockers represent channels for different actions.
    My Dockers are implemented on the same way like the example with docker/container/view and the view as modeless dialog.

    The channels could be closed, so I tried to close a docker via a button from the docker view themself. The button initiate a PostMessage to the mainframe, and the mainframe try to close the docker in the message handler with the close method of the docker class.

    Now my problem: Sometimes the process hang inside the CWnd destroy method inside the docker close method and will never return (The OnDestroy of the view was called and executed at this time). Sometimes it works without any problem.

    Adding a sleep of until one second at the beginning of executing the close message handler of the PostMessage before calling the close method of the docker reduce the occurence of the problem, but the problem still exist.

    Undock the docker via MMI and closing the docker via the windows exit button in the caption of the undocked docker works everytime without problem.

    So I tried to undock, to hide, to undock and hide the docker via the docker methods before closing the docker, but the problem still exist sometimes.

    So I tried to post the undocked docker the WM_SYSCOMMAND SC_CLOSE message from the handler in the mainframe to simulate clicking the caption bar exit button, the problem still exist sometimes.

    The docker which should be closed isn't the last docker, setting an other docker as active shown page before closing the docker doesn't change the behaviour.

    Now my Question: Do you have any other idea about the problem and/or how dockers can be closed from actions inside the docker view?

     
  • David

    David - 2015-01-19

    Hi,

    Currently CDocker::Close handles the closing of simple dockers, but doesn't handle the closing of dockers with dock containers properly.

    Try overriding CDocker::Close in your modeless dialog's docker with the following code:

    void CMyDocker::Close()
    {
        // Destroy the docker
        if (dynamic_cast<CDockContainer*>(GetView()))
        {
            CDockContainer* pContainer = (static_cast<CDockContainer*>(GetView()))->GetActiveContainer();
            CDocker* pDock = GetDockFromView(pContainer);
            UndockContainer(pContainer, GetCursorPos(), FALSE);
            pDock->Destroy();
        }
        else
        {
            Hide();
            Destroy();
        }
    }
    

    I'd like you to let me know how you get on. If this fails to resolve the problem, I might get you to send me an e-mail with a project that demonstrates the problem.

    Best regards,
    David

     

    Last edit: David 2015-01-19
    • TorstenEschner

      TorstenEschner - 2015-01-30

      Hello David,

      thanks for the solution proposal, but it doesn't help my Project.

      I've spent a lot of time to find out why, and i didn't found the problem, but a solution. The Problem was, that the application hangs with different call stacks in a very windows internal function NTWaitSingleObject.

      In the origin architecture of my application each docker has an own working thread to do the work, and the threads are closed in the right way before the docker will be closed if I use the Debugger, but if I do the same with the release version, the application hangs as described.

      So I removed all the docker working threads to one unique, now task queued, worker thread and it seems, that this was a solution, the application doesn't hang.

      It is not really clear why and also not the real solution for my project because the actions should be done in parallel, but I also think, it isn't a problem of the framework.

      Thank your for your help.

       
  • David

    David - 2015-01-31

    Hi,

    I wasn't aware you were running dockers in different threads. The dockers reposition each other and also send messages and notifications to each other, so separate threads for dockers is probably not a good idea. In addition, the dock ancestor has the task of destroying all descendant dockers when the application closes. I suspect this is causing a thread deadlock in your application.

    If you feel that multiple threads are appropriate you could put the docker's view window in a different thread. This would be a GUI thread, running its own message loop, and should be ended with a PostQuitMessage when the view window is destroyed.

    The DirectX sample demonstrates how a view window can be run in a different thread.

    Best regards,
    David

     

Log in to post a comment.