Skip to content

Commit

Permalink
[embedlite] Make it possible to shut down the engine grecefully.
Browse files Browse the repository at this point in the history
With this in place applications like sailfish-browser should be able to
request the engine to shut down and wait for the prcess to finish before
terminating the mainloop.
  • Loading branch information
tworaz committed Sep 29, 2015
1 parent 2c5e703 commit 93431df
Show file tree
Hide file tree
Showing 15 changed files with 135 additions and 45 deletions.
65 changes: 40 additions & 25 deletions embedding/embedlite/EmbedLiteApp.cpp
Expand Up @@ -314,16 +314,15 @@ EmbedLiteApp::Stop()
NS_ASSERTION(mState == STARTING || mState == INITIALIZED, "Wrong timing");

if (mState == INITIALIZED) {
if (mViews.empty()) {
if (mViews.empty() && mWindows.empty()) {
mUILoop->PostTask(FROM_HERE,
NewRunnableFunction(&EmbedLiteApp::PreDestroy, this));
} else {
std::map<uint32_t, EmbedLiteView*>::iterator it;
for (it = mViews.begin(); it != mViews.end(); it++) {
EmbedLiteView* view = it->second;
delete view;
it->second = nullptr;
// NOTE: we still keep dangling keys here. They are supposed to be erased in ViewDestroyed().
for (auto viewPair : mViews) {
viewPair.second->Destroy();
}
for (auto winPair: mWindows) {
winPair.second->Destroy();
}
}
}
Expand Down Expand Up @@ -441,7 +440,7 @@ EmbedLiteApp::CreateView(EmbedLiteWindow* aWindow, uint32_t aParent, bool aIsPri

PEmbedLiteViewParent* viewParent = static_cast<PEmbedLiteViewParent*>(
mAppParent->SendPEmbedLiteViewConstructor(aWindow->GetUniqueID(), sViewCreateID,
aParent, aIsPrivateWindow));
aParent, aIsPrivateWindow));
EmbedLiteView* view = new EmbedLiteView(this, aWindow, viewParent, sViewCreateID);
mViews[sViewCreateID] = view;
return view;
Expand Down Expand Up @@ -517,25 +516,45 @@ EmbedLiteApp::ViewDestroyed(uint32_t id)
LOGT("id:%i", id);
std::map<uint32_t, EmbedLiteView*>::iterator it = mViews.find(id);
if (it != mViews.end()) {
EmbedLiteView* view = it->second;
mViews.erase(it);
delete view;
}
if (mState == DESTROYING && mViews.empty()) {
mUILoop->PostTask(FROM_HERE,
NewRunnableFunction(&EmbedLiteApp::PreDestroy, this));
if (mViews.empty()) {
if (mListener) {
mListener->LastViewDestroyed();
}
if (mState == DESTROYING) {
mUILoop->PostTask(FROM_HERE,
NewRunnableFunction(&EmbedLiteApp::PreDestroy, this));
}
}
}

void
EmbedLiteApp::WindowDestroyed(uint32_t id)
{
LOGT("id:%i", id);
std::map<uint32_t, EmbedLiteWindow*>::iterator it = mWindows.find(id);
if (it != mWindows.end()) {
EmbedLiteWindow* win = it->second;
mWindows.erase(it);
delete win;
}
if (mWindows.empty()) {
if (mListener) {
mListener->LastWindowDestroyed();
}
}
}

void EmbedLiteApp::DestroyView(EmbedLiteView* aView)
{
LOGT();
NS_ASSERTION(mState == INITIALIZED, "Wrong timing");
std::map<uint32_t, EmbedLiteView*>::iterator it;
for (it = mViews.begin(); it != mViews.end(); it++) {
if (it->second == aView) {
EmbedLiteView* view = it->second;
delete view;
it->second = nullptr;
mViews.erase(it);
for (auto elm : mViews) {
if (aView == elm.second) {
elm.second->Destroy();
return;
}
}
Expand All @@ -546,13 +565,9 @@ void EmbedLiteApp::DestroyWindow(EmbedLiteWindow* aWindow)
{
LOGT();
NS_ASSERTION(mState == INITIALIZED, "Wrong timing");
std::map<uint32_t, EmbedLiteWindow*>::iterator it;
for (it = mWindows.begin(); it != mWindows.end(); it++) {
if (it->second == aWindow) {
EmbedLiteWindow* window = it->second;
delete window;
it->second = nullptr;
mWindows.erase(it);
for (auto elm : mWindows) {
if (aWindow == elm.second) {
elm.second->Destroy();
return;
}
}
Expand Down
8 changes: 5 additions & 3 deletions embedding/embedlite/EmbedLiteApp.h
Expand Up @@ -51,6 +51,8 @@ class EmbedLiteAppListener
const char* uri,
const uint32_t& contextFlags,
EmbedLiteView* aParentView) { return 0; }
virtual void LastViewDestroyed() {};
virtual void LastWindowDestroyed() {};
};

class EmbedLiteApp
Expand Down Expand Up @@ -175,13 +177,13 @@ class EmbedLiteApp
friend class EmbedLiteAppThreadParent;
friend class EmbedLiteCompositorParent;
friend class EmbedLitePuppetWidget;
friend class EmbedLiteViewBaseChild;
friend class EmbedLiteViewBaseParent;
friend class EmbedLiteViewThreadParent;
friend class EmbedLiteView;
friend class EmbedLiteWindow;

EmbedLiteView* GetViewByID(uint32_t id);
EmbedLiteWindow* GetWindowByID(uint32_t id);
void ViewDestroyed(uint32_t id);
void WindowDestroyed(uint32_t id);
void ChildReadyToDestroy();
uint32_t CreateWindowRequested(const uint32_t& chromeFlags, const char* uri, const uint32_t& contextFlags, const uint32_t& parentId);
EmbedLiteAppListener* GetListener();
Expand Down
19 changes: 13 additions & 6 deletions embedding/embedlite/EmbedLiteView.cpp
Expand Up @@ -40,18 +40,25 @@ EmbedLiteView::EmbedLiteView(EmbedLiteApp* aApp, EmbedLiteWindow* aWindow, PEmb
EmbedLiteView::~EmbedLiteView()
{
LOGT("impl:%p", mViewImpl);
if (mViewParent) {
unused << mViewParent->SendDestroy();
} else {
LOGNI();
}
if (mViewImpl) {
mViewImpl->ViewAPIDestroyed();
}
mViewImpl = NULL;
}

void
EmbedLiteView::Destroy()
{
MOZ_ASSERT(mViewParent);
unused << mViewParent->SendDestroy();
}

void
EmbedLiteView::Destroyed()
{
if (mListener) {
mListener->ViewDestroyed();
}
EmbedLiteApp::GetInstance()->ViewDestroyed(mUniqueID);
}

void
Expand Down
15 changes: 12 additions & 3 deletions embedding/embedlite/EmbedLiteView.h
Expand Up @@ -115,12 +115,21 @@ class EmbedLiteView

virtual uint32_t GetUniqueID();

private:
friend class EmbedLiteViewThreadParent;
protected:
friend class EmbedLiteApp; // Needs to destroy the view.

// EmbedLiteViews are supposed to be destroyed through EmbedLiteApp::DestroyView.
virtual ~EmbedLiteView();
// Request the view to be destroyed. Once this async process is done
// EmbedLiteViewListener::ViewDestroyed will be called. This interface
// should only be used by EmbedLiteApp. EmbedLite users should destroy
// EmbedLiteViews by calling EmbedLiteApp::DestroyView.
void Destroy();

private:
friend class EmbedLiteViewBaseParent;
friend class EmbedLiteViewThreadParent;

void Destroyed();

EmbedLiteViewIface* GetImpl();

Expand Down
12 changes: 10 additions & 2 deletions embedding/embedlite/EmbedLiteWindow.cpp
Expand Up @@ -32,14 +32,22 @@ EmbedLiteWindow::EmbedLiteWindow(EmbedLiteApp* app, PEmbedLiteWindowParent* pare
EmbedLiteWindow::~EmbedLiteWindow()
{
MOZ_COUNT_DTOR(EmbedLiteWindow);
unused << mWindowParent->SendDestroy();
mWindowParent->SetEmbedAPIWindow(nullptr);
}

void EmbedLiteWindow::Destroy()
{
unused << mWindowParent->SendDestroy();
}

void EmbedLiteWindow::Destroyed()
{
if (mListener) {
mListener->WindowDestroyed();
}
EmbedLiteApp::GetInstance()->WindowDestroyed(mUniqueID);
}


void EmbedLiteWindow::SetListener(EmbedLiteWindowListener* aListener)
{
mListener = aListener;
Expand Down
14 changes: 12 additions & 2 deletions embedding/embedlite/EmbedLiteWindow.h
Expand Up @@ -75,11 +75,21 @@ class EmbedLiteWindow {
virtual void ResumeRendering();
virtual void* GetPlatformImage(int* width, int* height);

protected:
friend class EmbedLiteApp;

virtual ~EmbedLiteWindow();
// Request the window to be destroyed. Once this async process is done
// EmbedLiteWindowListener::WindowDestroyed will be called. This interface
// should only be used by EmbedLiteApp. EmbedLite users should destroy
// EmbedLiteWindowss by calling EmbedLiteApp::DestroyWindow.
void Destroy();

private:
friend class EmbedLiteApp; // Needs to destroy the window.
friend class EmbedLiteWindowBaseParent;

// EmbedLiteWindowss are supposed to be destroyed through EmbedLiteApp::DestroyWindow.
virtual ~EmbedLiteWindow();
void Destroyed();

EmbedLiteApp* mApp;
EmbedLiteWindowListener* mListener;
Expand Down
1 change: 1 addition & 0 deletions embedding/embedlite/PEmbedLiteView.ipdl
Expand Up @@ -70,6 +70,7 @@ child:

parent:
Initialized();
Destroyed();
__delete__();

OnLocationChanged(nsCString aLocation, bool aCanGoBack, bool aCanGoForward);
Expand Down
1 change: 1 addition & 0 deletions embedding/embedlite/PEmbedLiteWindow.ipdl
Expand Up @@ -20,6 +20,7 @@ child:

parent:
Initialized();
Destroyed();
__delete__();
};

Expand Down
2 changes: 0 additions & 2 deletions embedding/embedlite/embedshared/EmbedLitePuppetWidget.cpp
Expand Up @@ -101,8 +101,6 @@ EmbedLitePuppetWidget::EmbedLitePuppetWidget(EmbedLiteWindowBaseChild* window)
: EmbedLitePuppetWidget(window, nullptr)
{
if (sUseExternalGLContext && sRequestGLContextEarly) {
// GetPlatform() should create compositor loop if it doesn't exist, yet.
gfxPlatform::GetPlatform();
CompositorParent::CompositorLoop()->PostTask(FROM_HERE,
NewRunnableFunction(&CreateGLContextEarly, window->GetUniqueID()));
}
Expand Down
1 change: 1 addition & 0 deletions embedding/embedlite/embedshared/EmbedLiteViewBaseChild.cpp
Expand Up @@ -146,6 +146,7 @@ bool EmbedLiteViewBaseChild::RecvDestroy()
mChrome = nullptr;
mDOMWindow = nullptr;
mWebNavigation = nullptr;
unused << SendDestroyed();
PEmbedLiteViewChild::Send__delete__(this);
return true;
}
Expand Down
14 changes: 12 additions & 2 deletions embedding/embedlite/embedshared/EmbedLiteViewBaseParent.cpp
Expand Up @@ -5,7 +5,6 @@

#include "EmbedLog.h"

#include "EmbedLiteApp.h"
#include "EmbedLiteView.h"
#include "EmbedLiteViewBaseParent.h"
#include "EmbedLiteWindowBaseParent.h"
Expand Down Expand Up @@ -47,7 +46,6 @@ EmbedLiteViewBaseParent::~EmbedLiteViewBaseParent()
LOGT("mView:%p, mCompositor:%p", mView, mCompositor.get());
mController = nullptr;
mWindow.RemoveObserver(this);
EmbedLiteApp::GetInstance()->ViewDestroyed(mId);
}

void
Expand Down Expand Up @@ -93,6 +91,18 @@ EmbedLiteViewBaseParent::RecvInitialized()
return true;
}

bool
EmbedLiteViewBaseParent::RecvDestroyed()
{
if (mViewAPIDestroyed) {
return true;
}

NS_ENSURE_TRUE(mView, false);
mView->Destroyed();
return true;
}

bool
EmbedLiteViewBaseParent::RecvOnLocationChanged(const nsCString& aLocation,
const bool& aCanGoBack,
Expand Down
3 changes: 3 additions & 0 deletions embedding/embedlite/embedshared/EmbedLiteViewBaseParent.h
Expand Up @@ -38,6 +38,9 @@ class EmbedLiteViewBaseParent : public PEmbedLiteViewParent,
virtual bool
RecvInitialized() override;

virtual bool
RecvDestroyed() override;

virtual bool
RecvOnLocationChanged(const nsCString& aLocation, const bool& aCanGoBack, const bool& aCanGoForward) override;

Expand Down
17 changes: 17 additions & 0 deletions embedding/embedlite/embedshared/EmbedLiteWindowBaseChild.cpp
Expand Up @@ -12,12 +12,19 @@
#include "ScreenOrientation.h"
#include "nsIScreen.h"
#include "nsIScreenManager.h"
#include "gfxPlatform.h"

using namespace mozilla::dom;

namespace mozilla {

namespace layers {
void ShutdownTileCache();
}
namespace embedlite {

static int sWindowCount = 0;

EmbedLiteWindowBaseChild::EmbedLiteWindowBaseChild(const uint32_t& aId)
: mId(aId)
, mWidget(nullptr)
Expand All @@ -28,6 +35,10 @@ EmbedLiteWindowBaseChild::EmbedLiteWindowBaseChild(const uint32_t& aId)

mCreateWidgetTask = NewRunnableMethod(this, &EmbedLiteWindowBaseChild::CreateWidget);
MessageLoop::current()->PostTask(FROM_HERE, mCreateWidgetTask);
sWindowCount++;

// Make sure gfx platform is initialized and ready to go.
gfxPlatform::GetPlatform();
}

EmbedLiteWindowBaseChild::~EmbedLiteWindowBaseChild()
Expand All @@ -38,6 +49,11 @@ EmbedLiteWindowBaseChild::~EmbedLiteWindowBaseChild()
mCreateWidgetTask->Cancel();
mCreateWidgetTask = nullptr;
}

sWindowCount--;
if (sWindowCount == 0) {
mozilla::layers::ShutdownTileCache();
}
}

EmbedLitePuppetWidget* EmbedLiteWindowBaseChild::GetWidget() const
Expand All @@ -54,6 +70,7 @@ bool EmbedLiteWindowBaseChild::RecvDestroy()
{
LOGT("destroy");
mWidget = nullptr;
unused << SendDestroyed();
PEmbedLiteWindowChild::Send__delete__(this);
return true;
}
Expand Down
7 changes: 7 additions & 0 deletions embedding/embedlite/embedshared/EmbedLiteWindowBaseParent.cpp
Expand Up @@ -128,6 +128,13 @@ bool EmbedLiteWindowBaseParent::RecvInitialized()
return true;
}

bool EmbedLiteWindowBaseParent::RecvDestroyed()
{
MOZ_ASSERT(mWindow);
mWindow->Destroyed();
return true;
}

void EmbedLiteWindowBaseParent::SetCompositor(EmbedLiteCompositorParent* aCompositor)
{
LOGT("compositor:%p, observers:%d", aCompositor, mObservers.Length());
Expand Down
Expand Up @@ -49,6 +49,7 @@ class EmbedLiteWindowBaseParent : public PEmbedLiteWindowParent
virtual void ActorDestroy(ActorDestroyReason aWhy) override;

virtual bool RecvInitialized() override;
virtual bool RecvDestroyed() override;

void SetEmbedAPIWindow(EmbedLiteWindow* window);
void SetCompositor(EmbedLiteCompositorParent* aCompositor);
Expand Down

0 comments on commit 93431df

Please sign in to comment.