[haiku-appserver] deadlock

  • From: Adi Oanca <adioanca@xxxxxxxxxxxxxx>
  • To: AppServer <haiku-appserver@xxxxxxxxxxxxx>
  • Date: Wed, 06 Apr 2005 11:49:01 +0300

Hi guys,

        While playing yesterday I found a "pretty nice" situation.
        You can reproduce it by adding a single line:
MoveBy(10,10);
        in Stephan's "Windows" app.

----------------
// main.cpp

#include <stdio.h>

#include "Application.h"
#include "TextControl.h"
#include "View.h"
#include "Window.h"

class HelloView : public BView {
  public:
                                        HelloView(BRect frame, const char* name,
                                                          uint32 resizeFlags, 
uint32 flags)
                                                : BView(frame, name, 
resizeFlags, flags)
                                        { }

        virtual void    Draw(BRect updateRect)
                                        {
//                              printf("HelloView::Draw()\n");
//                              updateRect.PrintToStream();

//                                              
SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
//                                              FillRect(updateRect);
                                                BRect r(Bounds());
//                              r.PrintToStream();

                                                const char* message = "Hello 
World!";
                                                float width = 
StringWidth(message);
                                                BPoint p(r.left + r.Width() / 
2.0 - width / 2.0,
                                                                 r.top + 
r.Height() / 2.0);

                                                SetHighColor(255, 0, 0, 128);
                                                DrawString(message, p);
                                        }
};


// show_window
void
show_window(BRect frame, const char* name)
{
        BWindow* window = new BWindow(frame, name,
                                                                  
B_TITLED_WINDOW,
                                                                  
B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE);

        BView* view = new HelloView(window->Bounds(), "test", B_FOLLOW_ALL,
                                                                B_WILL_DRAW/* | 
B_FULL_UPDATE_ON_RESIZE*/);

        view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
        window->AddChild(view);
/*      BRect b(view->Bounds());
        b.InsetBy(10.0, 20.0);
        BTextControl* control = new BTextControl(b, "tc", "Text", "Enter Text 
Here", NULL);
        view->AddChild(control);*/

        window->Show();
----------
++++    window->MoveBy(10,10);
---------
}

// main
int
main(int argc, char** argv)
{
        BApplication* app = new 
BApplication("application/x.vnd-Haiku.windows_test");

        BRect frame(50.0, 50.0, 200.0, 150.0);
        show_window(frame, "Window #1");

        frame.Set(80.0, 100.0, 250.0, 200.0);
        show_window(frame, "Window #2");

        app->Run();

        delete app;
        return 0;
}
----------------------------

        Looks to me StringWidth() is not implemented well. I tested this on R5 
and it works.
        The reason: when you create a BApplication object its looper is locked 
until you call ::Run(). StringWidth() uses 
BApplication's server connection and for that it must acquire BApplication's 
lock. Because StringWidth() is called from 
BWindow's thread we get a deadlock.
        Don't know how this should be solved... I guess we should use BWindow 
for getting font data. Just a thought.


bye,
Adi.

Other related posts: