* Fixed the TODO added by Ingo in r21957: locking the application didn't even make any
sense. Instead, we now lock its app_server connection only. The deadlock as exposed by starting Icon-O-Matic twice is now gone, at last. * Fixed the TODO added by Ingo in r21953: moved the thread/handler renaming code in a dedicated method _SetName() which is now called from _InitData() and SetTitle(); the "w>" is no longer lost. * Unlike the BeBook states, BMessageQueue::RemoveMessage() is indeed not supposed to delete the message it removes. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21959 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
0a201be444
commit
b73648647d
@ -335,6 +335,7 @@ private:
|
||||
void _AdoptResize();
|
||||
void _SetFocus(BView* focusView,
|
||||
bool notifyIputServer = false);
|
||||
void _SetName(const char* title);
|
||||
|
||||
Shortcut* _FindShortcut(uint32 key, uint32 modifiers);
|
||||
BView* _FindView(BView* view, BPoint point) const;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <input_globals.h>
|
||||
#include <AppMisc.h>
|
||||
#include <ApplicationPrivate.h>
|
||||
#include <AppServerLink.h>
|
||||
#include <DirectMessageTarget.h>
|
||||
#include <InputServerTypes.h>
|
||||
#include <MenuPrivate.h>
|
||||
@ -268,7 +269,7 @@ BWindow::Shortcut::PrepareKey(uint32 key)
|
||||
|
||||
|
||||
BWindow::BWindow(BRect frame, const char* title, window_type type,
|
||||
uint32 flags, uint32 workspace)
|
||||
uint32 flags, uint32 workspace)
|
||||
: BLooper(title, B_DISPLAY_PRIORITY)
|
||||
{
|
||||
window_look look;
|
||||
@ -279,8 +280,8 @@ BWindow::BWindow(BRect frame, const char* title, window_type type,
|
||||
}
|
||||
|
||||
|
||||
BWindow::BWindow(BRect frame, const char* title, window_look look, window_feel feel,
|
||||
uint32 flags, uint32 workspace)
|
||||
BWindow::BWindow(BRect frame, const char* title, window_look look,
|
||||
window_feel feel, uint32 flags, uint32 workspace)
|
||||
: BLooper(title, B_DISPLAY_PRIORITY)
|
||||
{
|
||||
_InitData(frame, title, look, feel, flags, workspace);
|
||||
@ -852,10 +853,9 @@ BWindow::DispatchMessage(BMessage *msg, BHandler *target)
|
||||
height = nextHeight;
|
||||
|
||||
MessageQueue()->RemoveMessage(pendingMessage);
|
||||
// TODO: the BeBook says that MessageQueue::RemoveMessage() deletes the message!
|
||||
delete pendingMessage;
|
||||
// this deletes the first *additional* message
|
||||
// fCurrentMessage is safe
|
||||
// this deletes the first *additional* message
|
||||
// fCurrentMessage is safe
|
||||
} else {
|
||||
MessageQueue()->RemoveMessage(pendingMessage);
|
||||
}
|
||||
@ -1798,25 +1798,7 @@ BWindow::SetTitle(const char *title)
|
||||
free(fTitle);
|
||||
fTitle = strdup(title);
|
||||
|
||||
// we will change BWindow's thread name to "w>window title"
|
||||
|
||||
char threadName[B_OS_NAME_LENGTH];
|
||||
strcpy(threadName, "w>");
|
||||
#ifdef __HAIKU__
|
||||
strlcat(threadName, title, B_OS_NAME_LENGTH);
|
||||
#else
|
||||
int32 length = strlen(title);
|
||||
length = min_c(length, B_OS_NAME_LENGTH - 3);
|
||||
memcpy(threadName + 2, title, length);
|
||||
threadName[length + 2] = '\0';
|
||||
#endif
|
||||
|
||||
// change the handler's name
|
||||
SetName(threadName);
|
||||
|
||||
// if the message loop has been started...
|
||||
if (Thread() >= B_OK)
|
||||
rename_thread(Thread(), threadName);
|
||||
_SetName(title);
|
||||
|
||||
// we notify the app_server so we can actually see the change
|
||||
if (Lock()) {
|
||||
@ -2367,9 +2349,10 @@ BWindow::_InitData(BRect frame, const char* title, window_look look,
|
||||
|
||||
if (title == NULL)
|
||||
title = "";
|
||||
// TODO: Where's da "w>"?
|
||||
|
||||
fTitle = strdup(title);
|
||||
SetName(title);
|
||||
|
||||
_SetName(title);
|
||||
|
||||
fFeel = feel;
|
||||
fLook = look;
|
||||
@ -2441,65 +2424,57 @@ BWindow::_InitData(BRect frame, const char* title, window_look look,
|
||||
|
||||
STRACE(("BWindow::InitData(): contacting app_server...\n"));
|
||||
|
||||
// HERE we are in BApplication's thread, so for locking we use be_app variable
|
||||
// we'll lock the be_app to be sure we're the only one writing at BApplication's server port
|
||||
bool locked = false;
|
||||
if (!be_app->IsLocked()) {
|
||||
// TODO: This doesn't look good. If a window is created in the message handling
|
||||
// code of another window, then the lock of that other window is already being
|
||||
// held. So, if the application tries to lock that window from its message
|
||||
// handling code, we get a beautiful deadlock. Start Icon-O-Matic, quit it, and
|
||||
// start it a second time to see that in action.
|
||||
be_app->Lock();
|
||||
locked = true;
|
||||
}
|
||||
|
||||
// let app_server know that a window has been created.
|
||||
fLink = new BPrivate::PortLink(
|
||||
BApplication::Private::ServerLink()->SenderPort(), receivePort);
|
||||
|
||||
if (bitmapToken < 0) {
|
||||
fLink->StartMessage(AS_CREATE_WINDOW);
|
||||
} else {
|
||||
fLink->StartMessage(AS_CREATE_OFFSCREEN_WINDOW);
|
||||
fLink->Attach<int32>(bitmapToken);
|
||||
{
|
||||
BPrivate::AppServerLink lockLink;
|
||||
// we're talking to the server application using our own
|
||||
// communication channel (fLink) - we better make sure no one
|
||||
// interferes by locking that channel (which AppServerLink does
|
||||
// implicetly)
|
||||
|
||||
if (bitmapToken < 0) {
|
||||
fLink->StartMessage(AS_CREATE_WINDOW);
|
||||
} else {
|
||||
fLink->StartMessage(AS_CREATE_OFFSCREEN_WINDOW);
|
||||
fLink->Attach<int32>(bitmapToken);
|
||||
}
|
||||
|
||||
fLink->Attach<BRect>(fFrame);
|
||||
fLink->Attach<uint32>((uint32)fLook);
|
||||
fLink->Attach<uint32>((uint32)fFeel);
|
||||
fLink->Attach<uint32>(fFlags);
|
||||
fLink->Attach<uint32>(workspace);
|
||||
fLink->Attach<int32>(_get_object_token_(this));
|
||||
fLink->Attach<port_id>(receivePort);
|
||||
fLink->Attach<port_id>(fMsgPort);
|
||||
fLink->AttachString(title);
|
||||
|
||||
port_id sendPort;
|
||||
int32 code;
|
||||
if (fLink->FlushWithReply(code) == B_OK
|
||||
&& code == B_OK
|
||||
&& fLink->Read<port_id>(&sendPort) == B_OK) {
|
||||
// read the frame size and its limits that were really
|
||||
// enforced on the server side
|
||||
|
||||
fLink->Read<BRect>(&fFrame);
|
||||
fLink->Read<float>(&fMinWidth);
|
||||
fLink->Read<float>(&fMaxWidth);
|
||||
fLink->Read<float>(&fMinHeight);
|
||||
fLink->Read<float>(&fMaxHeight);
|
||||
|
||||
fMaxZoomWidth = fMaxWidth;
|
||||
fMaxZoomHeight = fMaxHeight;
|
||||
} else
|
||||
sendPort = -1;
|
||||
|
||||
// Redirect our link to the new window connection
|
||||
fLink->SetSenderPort(sendPort);
|
||||
}
|
||||
|
||||
fLink->Attach<BRect>(fFrame);
|
||||
fLink->Attach<uint32>((uint32)fLook);
|
||||
fLink->Attach<uint32>((uint32)fFeel);
|
||||
fLink->Attach<uint32>(fFlags);
|
||||
fLink->Attach<uint32>(workspace);
|
||||
fLink->Attach<int32>(_get_object_token_(this));
|
||||
fLink->Attach<port_id>(receivePort);
|
||||
fLink->Attach<port_id>(fMsgPort);
|
||||
fLink->AttachString(title);
|
||||
|
||||
port_id sendPort;
|
||||
int32 code;
|
||||
if (fLink->FlushWithReply(code) == B_OK
|
||||
&& code == B_OK
|
||||
&& fLink->Read<port_id>(&sendPort) == B_OK) {
|
||||
// read the frame size and its limits that were really
|
||||
// enforced on the server side
|
||||
|
||||
fLink->Read<BRect>(&fFrame);
|
||||
fLink->Read<float>(&fMinWidth);
|
||||
fLink->Read<float>(&fMaxWidth);
|
||||
fLink->Read<float>(&fMinHeight);
|
||||
fLink->Read<float>(&fMaxHeight);
|
||||
|
||||
fMaxZoomWidth = fMaxWidth;
|
||||
fMaxZoomHeight = fMaxHeight;
|
||||
} else
|
||||
sendPort = -1;
|
||||
|
||||
// Redirect our link to the new window connection
|
||||
fLink->SetSenderPort(sendPort);
|
||||
|
||||
if (locked)
|
||||
be_app->Unlock();
|
||||
|
||||
STRACE(("Server says that our send port is %ld\n", sendPort));
|
||||
STRACE(("Window locked?: %s\n", IsLocked() ? "True" : "False"));
|
||||
|
||||
@ -2507,6 +2482,35 @@ BWindow::_InitData(BRect frame, const char* title, window_look look,
|
||||
}
|
||||
|
||||
|
||||
//! Rename the handler and its thread
|
||||
void
|
||||
BWindow::_SetName(const char *title)
|
||||
{
|
||||
if (title == NULL)
|
||||
title = "";
|
||||
|
||||
// we will change BWindow's thread name to "w>window title"
|
||||
|
||||
char threadName[B_OS_NAME_LENGTH];
|
||||
strcpy(threadName, "w>");
|
||||
#ifdef __HAIKU__
|
||||
strlcat(threadName, title, B_OS_NAME_LENGTH);
|
||||
#else
|
||||
int32 length = strlen(title);
|
||||
length = min_c(length, B_OS_NAME_LENGTH - 3);
|
||||
memcpy(threadName + 2, title, length);
|
||||
threadName[length + 2] = '\0';
|
||||
#endif
|
||||
|
||||
// change the handler's name
|
||||
SetName(threadName);
|
||||
|
||||
// if the message loop has been started...
|
||||
if (Thread() >= B_OK)
|
||||
rename_thread(Thread(), threadName);
|
||||
}
|
||||
|
||||
|
||||
//! Reads all pending messages from the window port and put them into the queue.
|
||||
void
|
||||
BWindow::_DequeueAll()
|
||||
|
Loading…
Reference in New Issue
Block a user