fune/widget/windows/RemoteBackbuffer.h
Chris Martin 0d05486ea9 Bug 1617523 - Ensure remote backbuffer only reused if initialized properly r=jrmuizel
This crash was caused because there was a case where the Provider would
store the SharedImage even if it failed to initialize it or send it to the
Client.

When the Client next requested a borrow, the Provider would see it was
already storing a SharedImage and would tell the Client to just
reuse the one it already had.

Since the Client never actually received it, it would end up dereferencing
a null pointer.

The fix for this is to wait until the SharedImage is fully initialized and
shared with the Client before storing it. That way, we know that if we have
it then so does the Client.

Differential Revision: https://phabricator.services.mozilla.com/D64659

--HG--
extra : moz-landing-system : lando
2020-02-28 01:34:26 +00:00

87 lines
No EOL
2.3 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef widget_windows_RemoteBackbuffer_h
#define widget_windows_RemoteBackbuffer_h
#include <thread>
#include <windows.h>
#include "mozilla/Maybe.h"
namespace mozilla {
namespace widget {
namespace remote_backbuffer {
struct SharedData;
struct BorrowResponseData;
struct PresentResponseData;
class SharedImage;
class PresentableSharedImage;
class Provider {
public:
Provider();
~Provider();
bool Initialize(HWND aWindowHandle, DWORD aTargetProcessId,
nsTransparencyMode aTransparencyMode);
Maybe<RemoteBackbufferHandles> CreateRemoteHandles();
void UpdateTransparencyMode(nsTransparencyMode aTransparencyMode);
Provider(const Provider&) = delete;
Provider(Provider&&) = delete;
Provider& operator=(const Provider&) = delete;
Provider& operator=(Provider&&) = delete;
private:
void ThreadMain();
void HandleBorrowRequest(BorrowResponseData* aResponseData,
bool aAllowSameBuffer);
void HandlePresentRequest(PresentResponseData* aResponseData);
HWND mWindowHandle;
DWORD mTargetProcessId;
HANDLE mFileMapping;
HANDLE mRequestReadyEvent;
HANDLE mResponseReadyEvent;
SharedData* mSharedDataPtr;
bool mStopServiceThread;
std::thread mServiceThread;
std::unique_ptr<PresentableSharedImage> mBackbuffer;
mozilla::Atomic<nsTransparencyMode, MemoryOrdering::Relaxed>
mTransparencyMode;
};
class Client {
public:
Client();
~Client();
bool Initialize(const RemoteBackbufferHandles& aRemoteHandles);
already_AddRefed<gfx::DrawTarget> BorrowDrawTarget();
bool PresentDrawTarget();
Client(const Client&) = delete;
Client(Client&&) = delete;
Client& operator=(const Client&) = delete;
Client& operator=(Client&&) = delete;
private:
HANDLE mFileMapping;
HANDLE mRequestReadyEvent;
HANDLE mResponseReadyEvent;
SharedData* mSharedDataPtr;
std::unique_ptr<SharedImage> mBackbuffer;
};
} // namespace remote_backbuffer
} // namespace widget
} // namespace mozilla
#endif // widget_windows_RemoteBackbuffer_h