hrev54257 adds 1 changeset to branch 'master'
old head: 51dd385e3ea8651afd345d724193365cc47dacf2
new head: f95ec23e9582b09d2067c39903ea8cbbe7bf1e94
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=f95ec23e9582+%5E51dd385e3ea8
----------------------------------------------------------------------------
f95ec23e9582: HaikuDepot: Fix Crash on Quit During Load
If the system is currently loading-up and populating
data and the user quits then it was crashing because
of a call to a deleted ProcessCoordinator object.
This change implements the reference as BReference
ensuring that the ProcessCoordinator object is only
deleted after it is not used anywhere.
Resolves #16109
Change-Id: If535c151819da37d502283af3745e4148da69026
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2797
Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>
[ Andrew Lindesay <apl@xxxxxxxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev54257
Commit: f95ec23e9582b09d2067c39903ea8cbbe7bf1e94
URL: https://git.haiku-os.org/haiku/commit/?id=f95ec23e9582
Author: Andrew Lindesay <apl@xxxxxxxxxxxxxx>
Date: Sun May 24 11:20:39 2020 UTC
Committer: waddlesplash <waddlesplash@xxxxxxxxx>
Commit-Date: Sun May 24 15:51:40 2020 UTC
Ticket: https://dev.haiku-os.org/ticket/16109
----------------------------------------------------------------------------
4 files changed, 21 insertions(+), 19 deletions(-)
src/apps/haikudepot/server/AbstractProcess.cpp | 10 +++++-----
src/apps/haikudepot/server/AbstractProcess.h | 5 +++--
src/apps/haikudepot/ui/MainWindow.cpp | 20 ++++++++++----------
src/apps/haikudepot/ui/MainWindow.h | 5 +++--
----------------------------------------------------------------------------
diff --git a/src/apps/haikudepot/server/AbstractProcess.cpp
b/src/apps/haikudepot/server/AbstractProcess.cpp
index bc74cedf73..2316f509b1 100644
--- a/src/apps/haikudepot/server/AbstractProcess.cpp
+++ b/src/apps/haikudepot/server/AbstractProcess.cpp
@@ -36,7 +36,7 @@ void
AbstractProcess::SetListener(AbstractProcessListener* listener)
{
AutoLocker<BLocker> locker(&fLock);
- fListener = listener;
+ fListener = BReference<AbstractProcessListener>(listener);
}
@@ -64,7 +64,7 @@ AbstractProcess::Run()
if (runResult != B_OK)
printf("[%s] an error has arisen; %s\n", Name(),
strerror(runResult));
- AbstractProcessListener* listener;
+ BReference<AbstractProcessListener> listener;
{
AutoLocker<BLocker> locker(&fLock);
@@ -76,7 +76,7 @@ AbstractProcess::Run()
// this process may be part of a larger bulk-load process and
// if so, the process orchestration needs to know when this
// process has completed.
- if (listener != NULL)
+ if (listener.Get() != NULL)
listener->ProcessExited();
return runResult;
@@ -110,7 +110,7 @@ status_t
AbstractProcess::Stop()
{
status_t result = B_CANCELED;
- AbstractProcessListener* listener = NULL;
+ BReference<AbstractProcessListener> listener = NULL;
{
AutoLocker<BLocker> locker(&fLock);
@@ -126,7 +126,7 @@ AbstractProcess::Stop()
}
}
- if (listener != NULL)
+ if (listener.Get() != NULL)
listener->ProcessExited();
return result;
diff --git a/src/apps/haikudepot/server/AbstractProcess.h
b/src/apps/haikudepot/server/AbstractProcess.h
index 001ff8724e..72e04da96e 100644
--- a/src/apps/haikudepot/server/AbstractProcess.h
+++ b/src/apps/haikudepot/server/AbstractProcess.h
@@ -8,6 +8,7 @@
#define ABSTRACT_PROCESS_H
#include <String.h>
+#include <Referenceable.h>
#include <Url.h>
#include "StandardMetaData.h"
@@ -26,7 +27,7 @@ typedef enum process_state {
failure.
*/
-class AbstractProcessListener {
+class AbstractProcessListener : public BReferenceable {
public:
virtual void ProcessExited() = 0;
};
@@ -55,7 +56,7 @@ protected:
private:
BLocker fLock;
- AbstractProcessListener*
+ BReference<AbstractProcessListener>
fListener;
bool fWasStopped;
process_state fProcessState;
diff --git a/src/apps/haikudepot/ui/MainWindow.cpp
b/src/apps/haikudepot/ui/MainWindow.cpp
index c247616679..3bfd4f5eb5 100644
--- a/src/apps/haikudepot/ui/MainWindow.cpp
+++ b/src/apps/haikudepot/ui/MainWindow.cpp
@@ -496,7 +496,7 @@ MainWindow::MessageReceived(BMessage* message)
}
_AddRemovePackageFromLists(ref);
if ((changes & PKG_CHANGED_STATE) != 0
- && fCoordinator == NULL) {
+ && fCoordinator.Get() == NULL) {
fWorkStatusView->PackageStatusChanged(ref);
}
}
@@ -1334,14 +1334,14 @@ MainWindow::_AddProcessCoordinator(ProcessCoordinator*
item)
{
AutoLocker<BLocker> lock(&fCoordinatorLock);
- if (fCoordinator == NULL) {
+ if (fCoordinator.Get() == NULL) {
if (acquire_sem(fCoordinatorRunningSem) != B_OK)
debugger("unable to acquire the process coordinator
sem");
if (Logger::IsInfoEnabled()) {
printf("adding and starting a process coordinator
[%s]\n",
item->Name().String());
}
- fCoordinator = item;
+ fCoordinator = BReference<ProcessCoordinator>(item);
fCoordinator->Start();
}
else {
@@ -1364,7 +1364,7 @@ MainWindow::_SpinUntilProcessCoordinatorComplete()
debugger("unable to release the process coordinator
sem");
{
AutoLocker<BLocker> lock(&fCoordinatorLock);
- if (fCoordinator == NULL)
+ if (fCoordinator.Get() == NULL)
return;
}
}
@@ -1381,16 +1381,15 @@ MainWindow::_StopProcessCoordinators()
AutoLocker<BLocker> lock(&fCoordinatorLock);
while (!fCoordinatorQueue.empty()) {
- ProcessCoordinator *processCoordinator =
fCoordinatorQueue.front();
+ BReference<ProcessCoordinator> processCoordinator =
fCoordinatorQueue.front();
if (Logger::IsInfoEnabled()) {
printf("will drop queued process coordinator
[%s]\n",
processCoordinator->Name().String());
}
fCoordinatorQueue.pop();
- delete processCoordinator;
}
- if (fCoordinator != NULL) {
+ if (fCoordinator.Get() != NULL) {
fCoordinator->Stop();
}
}
@@ -1416,7 +1415,7 @@ MainWindow::CoordinatorChanged(ProcessCoordinatorState&
coordinatorState)
{
AutoLocker<BLocker> lock(&fCoordinatorLock);
- if (fCoordinator == coordinatorState.Coordinator()) {
+ if (fCoordinator.Get() == coordinatorState.Coordinator()) {
if (!coordinatorState.IsRunning()) {
if (release_sem(fCoordinatorRunningSem) != B_OK)
debugger("unable to release the process
coordinator sem");
@@ -1434,8 +1433,9 @@ MainWindow::CoordinatorChanged(ProcessCoordinatorState&
coordinatorState)
messenger.SendMessage(message);
}
- delete fCoordinator;
- fCoordinator = NULL;
+ fCoordinator = BReference<ProcessCoordinator>(NULL);
+ // will delete the old process coordinator if
it is not used
+ // elsewhere.
// now schedule the next one.
if (!fCoordinatorQueue.empty()) {
diff --git a/src/apps/haikudepot/ui/MainWindow.h
b/src/apps/haikudepot/ui/MainWindow.h
index 32a3717d9c..5ead8e5960 100644
--- a/src/apps/haikudepot/ui/MainWindow.h
+++ b/src/apps/haikudepot/ui/MainWindow.h
@@ -155,9 +155,10 @@ private:
Model fModel;
ModelListenerRef fModelListener;
- std::queue<ProcessCoordinator*>
+ std::queue<BReference<ProcessCoordinator>>
fCoordinatorQueue;
- ProcessCoordinator* fCoordinator;
+ BReference<ProcessCoordinator>
+ fCoordinator;
BLocker fCoordinatorLock;
sem_id fCoordinatorRunningSem;