From f744935b65c0debd114d3aa8b805609c7e27e58c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 4 Aug 2016 22:12:00 +0200 Subject: [PATCH] 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. --- src/servers/app/AppServer.cpp | 8 ++--- src/servers/app/Desktop.cpp | 16 ++++++--- src/servers/app/MessageLooper.cpp | 10 +++--- src/servers/app/MessageLooper.h | 56 +++++++++++++++++-------------- src/servers/app/ServerApp.cpp | 23 ++++++++----- 5 files changed, 64 insertions(+), 49 deletions(-) diff --git a/src/servers/app/AppServer.cpp b/src/servers/app/AppServer.cpp index 9090086e72..d060445b02 100644 --- a/src/servers/app/AppServer.cpp +++ b/src/servers/app/AppServer.cpp @@ -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; diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 34157c1189..ed1a026349 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -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(); } diff --git a/src/servers/app/MessageLooper.cpp b/src/servers/app/MessageLooper.cpp index 2828b8ef4d..56ce033668 100644 --- a/src/servers/app/MessageLooper.cpp +++ b/src/servers/app/MessageLooper.cpp @@ -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; } diff --git a/src/servers/app/MessageLooper.h b/src/servers/app/MessageLooper.h index d9c027175c..2b6bd7dcd8 100644 --- a/src/servers/app/MessageLooper.h +++ b/src/servers/app/MessageLooper.h @@ -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 */ diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index af929c928e..d3258e5985 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -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)