Reconnect BApplication and trigger reconnect of all BWindows in an application.

* handle bitmap reconnect request in the app server
This commit is contained in:
czeidler 2012-01-22 15:06:34 +13:00
parent 00670f08ef
commit 6c40fc5dfc
5 changed files with 94 additions and 6 deletions

View File

@ -122,6 +122,7 @@ private:
status_t _SetupServerAllocator();
status_t _InitGUIContext();
status_t _ConnectToServer();
void _ReconnectToServer();
bool _QuitAllWindows(bool force);
bool _WindowQuitLoop(bool quitFilePanels, bool force);
void _ArgvReceived(BMessage* message);

View File

@ -29,6 +29,7 @@ thread_id main_thread_for(team_id team);
bool is_app_showing_modal_window(team_id team);
void invalidate_server_port();
port_id get_app_server_port();
status_t create_desktop_connection(ServerLink* link, const char* name,
int32 capacity);

View File

@ -165,11 +165,19 @@ is_app_showing_modal_window(team_id team)
}
static port_id sServerPort = -1;
void
invalidate_server_port()
{
sServerPort = -1;
}
port_id
get_app_server_port()
{
static port_id sServerPort = -1;
if (sServerPort < 0) {
// No need for synchronization - in the worst case, we'll call
// find_port() twice.

View File

@ -26,6 +26,7 @@
#include <File.h>
#include <Locker.h>
#include <MessageRunner.h>
#include <ObjectList.h>
#include <Path.h>
#include <PropertyInfo.h>
#include <RegistrarDefs.h>
@ -36,9 +37,11 @@
#include <AppMisc.h>
#include <AppServerLink.h>
#include <AutoLocker.h>
#include <BitmapPrivate.h>
#include <DraggerPrivate.h>
#include <LooperList.h>
#include <MenuWindow.h>
#include <PicturePrivate.h>
#include <PortLink.h>
#include <RosterPrivate.h>
#include <ServerMemoryAllocator.h>
@ -597,6 +600,12 @@ BApplication::MessageReceived(BMessage *message)
be_roster->ActivateApp(Team());
break;
case kMsgAppServerRestarted:
{
_ReconnectToServer();
break;
}
default:
BLooper::MessageReceived(message);
break;
@ -1284,6 +1293,34 @@ BApplication::_ConnectToServer()
}
void
BApplication::_ReconnectToServer()
{
delete_port(fServerLink->SenderPort());
delete_port(fServerLink->ReceiverPort());
invalidate_server_port();
if (_ConnectToServer() != B_OK)
debugger("Can't reconnect to app server!");
AutoLocker<BLooperList> listLock(gLooperList);
if (!listLock.IsLocked())
return;
uint32 count = gLooperList.CountLoopers();
for (uint32 i = 0; i < count ; i++) {
BWindow* window = dynamic_cast<BWindow*>(gLooperList.LooperAt(i));
if (window == NULL)
continue;
BMessenger windowMessenger(window);
windowMessenger.SendMessage(kMsgAppServerRestarted);
}
reconnect_bitmaps_to_app_server();
reconnect_pictures_to_app_server();
}
#if 0
void
BApplication::send_drag(BMessage *message, int32 vs_token, BPoint offset,

View File

@ -720,10 +720,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
fLink.Attach<int32>(bitmap->Token());
fLink.Attach<uint8>(allocationFlags);
fLink.Attach<area_id>(
fMemoryAllocator.Area(bitmap->AllocationCookie()));
fLink.Attach<int32>(
fMemoryAllocator.AreaOffset(bitmap->AllocationCookie()));
fLink.Attach<area_id>(bitmap->Area());
fLink.Attach<int32>(bitmap->AreaOffset());
if ((allocationFlags & kFramebuffer) != 0)
fLink.Attach<int32>(bitmap->BytesPerRow());
@ -806,6 +804,49 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
break;
}
case AS_RECONNECT_BITMAP:
{
// First, let's attempt to allocate the bitmap
ServerBitmap* bitmap = NULL;
BRect frame;
color_space colorSpace;
uint32 flags;
int32 bytesPerRow;
int32 screenID;
area_id clientArea;
int32 areaOffset;
link.Read<BRect>(&frame);
link.Read<color_space>(&colorSpace);
link.Read<uint32>(&flags);
link.Read<int32>(&bytesPerRow);
link.Read<int32>(&screenID);
link.Read<int32>(&clientArea);
if (link.Read<int32>(&areaOffset) == B_OK) {
// TODO: choose the right HWInterface with regards to the
// screenID
bitmap = gBitmapManager->CloneFromClient(clientArea, areaOffset,
frame, colorSpace, flags, bytesPerRow);
}
if (bitmap != NULL && _AddBitmap(bitmap)) {
fLink.StartMessage(B_OK);
fLink.Attach<int32>(bitmap->Token());
fLink.Attach<area_id>(bitmap->Area());
} else {
if (bitmap != NULL)
bitmap->ReleaseReference();
fLink.StartMessage(B_NO_MEMORY);
}
fLink.Flush();
break;
}
// Picture ops
case AS_CREATE_PICTURE: