app_server: Fixed broken ServerApp allocation.

* Did not use std::nothrow, but exceptions were not catched.
* MessageLooper::Run() now returns a status code.
* There are a lot more cases of a new without nothrow that need to
  be investigated.
This commit is contained in:
Axel Dörfler 2016-08-04 22:12:00 +02:00
parent 7503f9a84f
commit f744935b65
5 changed files with 64 additions and 49 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2015, Haiku, Inc.
* Copyright 2001-2016, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
@ -176,10 +176,8 @@ AppServer::_CreateDesktop(uid_t userID, const char* targetScreen)
desktop = new Desktop(userID, targetScreen);
status_t status = desktop->Init();
if (status == B_OK) {
if (!desktop->Run())
status = B_ERROR;
}
if (status == B_OK)
status = desktop->Run();
if (status == B_OK && !fDesktops.AddItem(desktop))
status = B_NO_MEMORY;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2015, Haiku.
* Copyright 2001-2016, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -2539,10 +2539,16 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
if (link.ReadString(&appSignature) != B_OK)
break;
ServerApp* app = new ServerApp(this, clientReplyPort,
ServerApp* app = new (std::nothrow) ServerApp(this, clientReplyPort,
clientLooperPort, clientTeamID, htoken, appSignature);
if (app->InitCheck() == B_OK
&& app->Run()) {
status_t status = B_OK;
if (app == NULL)
status = B_NO_MEMORY;
if (status == B_OK)
status = app->InitCheck();
if (status == B_OK)
status = app->Run();
if (status == B_OK) {
// add the new ServerApp to the known list of ServerApps
fApplicationsLock.Lock();
fApplications.AddItem(app);
@ -2553,7 +2559,7 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// if everything went well, ServerApp::Run() will notify
// the client - but since it didn't, we do it here
BPrivate::LinkSender reply(clientReplyPort);
reply.StartMessage(B_ERROR);
reply.StartMessage(status);
reply.Flush();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005-2007, Haiku.
* Copyright 2005-2016, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -30,7 +30,7 @@ MessageLooper::~MessageLooper()
}
bool
status_t
MessageLooper::Run()
{
BAutolock locker(this);
@ -44,17 +44,17 @@ MessageLooper::Run()
fThread = spawn_thread(_message_thread, name, B_DISPLAY_PRIORITY, this);
if (fThread < B_OK) {
fQuitting = true;
return false;
return fThread;
}
if (resume_thread(fThread) != B_OK) {
fQuitting = true;
kill_thread(fThread);
fThread = -1;
return false;
return B_BAD_THREAD_ID;
}
return true;
return B_OK;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005, Haiku.
* Copyright 2005-2016, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -15,41 +15,45 @@
class MessageLooper : public BLocker {
public:
MessageLooper(const char* name);
virtual ~MessageLooper();
public:
MessageLooper(const char* name);
virtual ~MessageLooper();
virtual bool Run();
virtual void Quit();
virtual status_t Run();
virtual void Quit();
status_t PostMessage(int32 code,
bigtime_t timeout = B_INFINITE_TIMEOUT);
status_t PostMessage(int32 code,
bigtime_t timeout = B_INFINITE_TIMEOUT);
thread_id Thread() const { return fThread; }
bool IsQuitting() const { return fQuitting; }
sem_id DeathSemaphore() const { return fDeathSemaphore; }
thread_id Thread() const { return fThread; }
bool IsQuitting() const { return fQuitting; }
sem_id DeathSemaphore() const
{ return fDeathSemaphore; }
virtual port_id MessagePort() const = 0;
virtual port_id MessagePort() const = 0;
static status_t WaitForQuit(sem_id semaphore,
bigtime_t timeout = B_INFINITE_TIMEOUT);
static status_t WaitForQuit(sem_id semaphore,
bigtime_t timeout = B_INFINITE_TIMEOUT);
private:
virtual void _PrepareQuit();
virtual void _GetLooperName(char* name, size_t length);
virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link);
virtual void _MessageLooper();
private:
virtual void _PrepareQuit();
virtual void _GetLooperName(char* name, size_t length);
virtual void _DispatchMessage(int32 code,
BPrivate::LinkReceiver& link);
virtual void _MessageLooper();
protected:
static int32 _message_thread(void *_looper);
protected:
static int32 _message_thread(void*_looper);
protected:
thread_id fThread;
BPrivate::PortLink fLink;
bool fQuitting;
sem_id fDeathSemaphore;
protected:
thread_id fThread;
BPrivate::PortLink fLink;
bool fQuitting;
sem_id fDeathSemaphore;
};
static const int32 kMsgQuitLooper = 'quit';
#endif /* MESSAGE_LOOPER_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2015, Haiku.
* Copyright 2001-2016, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -105,7 +105,7 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort,
fViewCursor(NULL),
fCursorHideLevel(0),
fIsActive(false),
fMemoryAllocator(new ClientMemoryAllocator(this))
fMemoryAllocator(new (std::nothrow) ClientMemoryAllocator(this))
{
if (fSignature == "")
fSignature = "application/no-signature";
@ -194,7 +194,8 @@ ServerApp::~ServerApp()
fWindowListLock.Lock();
}
fMemoryAllocator->Detach();
if (fMemoryAllocator != NULL)
fMemoryAllocator->Detach();
fMapLocker.Lock();
while (!fBitmapMap.empty())
@ -204,7 +205,8 @@ ServerApp::~ServerApp()
fPictureMap.begin()->second->SetOwner(NULL);
fDesktop->GetCursorManager().DeleteCursors(fClientTeam);
fMemoryAllocator->ReleaseReference();
if (fMemoryAllocator != NULL)
fMemoryAllocator->ReleaseReference();
STRACE(("ServerApp %s::~ServerApp(): Exiting\n", Signature()));
}
@ -224,6 +226,9 @@ ServerApp::InitCheck()
if (fWindowListLock.Sem() < B_OK)
return fWindowListLock.Sem();
if (fMemoryAllocator == NULL)
return B_NO_MEMORY;
return B_OK;
}
@ -3318,10 +3323,12 @@ ServerApp::_CreateWindow(int32 code, BPrivate::LinkReceiver& link,
if (window != NULL) {
status = window->Init(frame, (window_look)look, (window_feel)feel,
flags, workspaces);
if (status == B_OK && !window->Run()) {
syslog(LOG_ERR, "ServerApp::_CreateWindow() - failed to run the "
"window thread\n");
status = B_ERROR;
if (status == B_OK) {
status = window->Run();
if (status != B_OK) {
syslog(LOG_ERR, "ServerApp::_CreateWindow() - failed to run "
"the window thread\n");
}
}
if (status != B_OK)