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 _SetupServerAllocator();
status_t _InitGUIContext(); status_t _InitGUIContext();
status_t _ConnectToServer(); status_t _ConnectToServer();
void _ReconnectToServer();
bool _QuitAllWindows(bool force); bool _QuitAllWindows(bool force);
bool _WindowQuitLoop(bool quitFilePanels, bool force); bool _WindowQuitLoop(bool quitFilePanels, bool force);
void _ArgvReceived(BMessage* message); 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); bool is_app_showing_modal_window(team_id team);
void invalidate_server_port();
port_id get_app_server_port(); port_id get_app_server_port();
status_t create_desktop_connection(ServerLink* link, const char* name, status_t create_desktop_connection(ServerLink* link, const char* name,
int32 capacity); 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 port_id
get_app_server_port() get_app_server_port()
{ {
static port_id sServerPort = -1;
if (sServerPort < 0) { if (sServerPort < 0) {
// No need for synchronization - in the worst case, we'll call // No need for synchronization - in the worst case, we'll call
// find_port() twice. // find_port() twice.

View File

@ -26,6 +26,7 @@
#include <File.h> #include <File.h>
#include <Locker.h> #include <Locker.h>
#include <MessageRunner.h> #include <MessageRunner.h>
#include <ObjectList.h>
#include <Path.h> #include <Path.h>
#include <PropertyInfo.h> #include <PropertyInfo.h>
#include <RegistrarDefs.h> #include <RegistrarDefs.h>
@ -36,9 +37,11 @@
#include <AppMisc.h> #include <AppMisc.h>
#include <AppServerLink.h> #include <AppServerLink.h>
#include <AutoLocker.h> #include <AutoLocker.h>
#include <BitmapPrivate.h>
#include <DraggerPrivate.h> #include <DraggerPrivate.h>
#include <LooperList.h> #include <LooperList.h>
#include <MenuWindow.h> #include <MenuWindow.h>
#include <PicturePrivate.h>
#include <PortLink.h> #include <PortLink.h>
#include <RosterPrivate.h> #include <RosterPrivate.h>
#include <ServerMemoryAllocator.h> #include <ServerMemoryAllocator.h>
@ -597,6 +600,12 @@ BApplication::MessageReceived(BMessage *message)
be_roster->ActivateApp(Team()); be_roster->ActivateApp(Team());
break; break;
case kMsgAppServerRestarted:
{
_ReconnectToServer();
break;
}
default: default:
BLooper::MessageReceived(message); BLooper::MessageReceived(message);
break; 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 #if 0
void void
BApplication::send_drag(BMessage *message, int32 vs_token, BPoint offset, 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<int32>(bitmap->Token());
fLink.Attach<uint8>(allocationFlags); fLink.Attach<uint8>(allocationFlags);
fLink.Attach<area_id>( fLink.Attach<area_id>(bitmap->Area());
fMemoryAllocator.Area(bitmap->AllocationCookie())); fLink.Attach<int32>(bitmap->AreaOffset());
fLink.Attach<int32>(
fMemoryAllocator.AreaOffset(bitmap->AllocationCookie()));
if ((allocationFlags & kFramebuffer) != 0) if ((allocationFlags & kFramebuffer) != 0)
fLink.Attach<int32>(bitmap->BytesPerRow()); fLink.Attach<int32>(bitmap->BytesPerRow());
@ -806,6 +804,49 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
break; 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 // Picture ops
case AS_CREATE_PICTURE: case AS_CREATE_PICTURE: