Bug 1822368 - Avoid creating RemoteSurfaceAllocator until JNI is ready. r=geckoview-reviewers,owlish

Following a GPU process crash, it is possible that we will attempt to
allocate a new Surface prior to JNI being initialized in the new GPU
process. This is resulting in UnsatisfiedLinkError exceptions when
attempting to call a native function.

To fix this, we avoid creating the new GPU process'
RemoteSurfaceAllocator until we reach the JNI_READY state, returning
null in RemoteSurfaceAllocator.getInstance() prior to then. We must
additionally ensure that GpuProcessConnection.getSurfaceAllocator()
repeatedly attempts to create the allocator until it succeeds, rather
than caching the null value returned on the first attempt.

Differential Revision: https://phabricator.services.mozilla.com/D217711
This commit is contained in:
Jamie Nicol 2024-07-26 08:30:38 +00:00
parent e49cdd5218
commit 8991573e43
2 changed files with 20 additions and 13 deletions

View File

@ -6,6 +6,7 @@
package org.mozilla.gecko.gfx;
import java.util.concurrent.atomic.AtomicInteger;
import org.mozilla.gecko.GeckoThread;
public final class RemoteSurfaceAllocator extends ISurfaceAllocator.Stub {
private static final String LOGTAG = "RemoteSurfaceAllocator";
@ -24,7 +25,7 @@ public final class RemoteSurfaceAllocator extends ISurfaceAllocator.Stub {
* 0 for the parent process instance.
*/
public static synchronized RemoteSurfaceAllocator getInstance(final int allocatorId) {
if (mInstance == null) {
if (mInstance == null && GeckoThread.isStateAtLeast(GeckoThread.State.JNI_READY)) {
mInstance = new RemoteSurfaceAllocator(allocatorId);
}
return mInstance;

View File

@ -198,6 +198,10 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
return mPid;
}
protected IChildProcess getChild() {
return mChild;
}
private GeckoResult<IChildProcess> completeFailedBind(
@NonNull final ServiceAllocator.BindException e) {
XPCOMEventTarget.assertOnLauncherThread();
@ -263,7 +267,6 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
final IChildProcess child = IChildProcess.Stub.asInterface(service);
try {
mPid = child.getPid();
onBinderConnected(child);
} catch (final DeadObjectException e) {
unbindService();
@ -288,10 +291,6 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
}
}
// Subclasses of ChildConnection can override this method to make any IChildProcess calls
// specific to their process type immediately after connection.
protected void onBinderConnected(@NonNull final IChildProcess child) throws RemoteException {}
@Override
protected void onReleaseResources() {
XPCOMEventTarget.assertOnLauncherThread();
@ -328,7 +327,7 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
// Unique ID used to identify each GPU process instance. Will always be non-zero,
// and unlike the process' pid cannot be the same value for successive instances.
private int mUniqueGpuProcessId;
private final int mUniqueGpuProcessId;
// Static counter used to initialize each instance's mUniqueGpuProcessId
private static int sUniqueGpuProcessIdCounter = 0;
@ -343,17 +342,24 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
mUniqueGpuProcessId = sUniqueGpuProcessIdCounter++;
}
@Override
protected void onBinderConnected(@NonNull final IChildProcess child) throws RemoteException {
mCompositorSurfaceManager = new CompositorSurfaceManager(child.getCompositorSurfaceManager());
mSurfaceAllocator = child.getSurfaceAllocator(mUniqueGpuProcessId);
}
public CompositorSurfaceManager getCompositorSurfaceManager() {
if (mCompositorSurfaceManager == null && getChild() != null) {
try {
mCompositorSurfaceManager =
new CompositorSurfaceManager(getChild().getCompositorSurfaceManager());
} catch (final RemoteException ignored) {
}
}
return mCompositorSurfaceManager;
}
public ISurfaceAllocator getSurfaceAllocator() {
if (mSurfaceAllocator == null && getChild() != null) {
try {
mSurfaceAllocator = getChild().getSurfaceAllocator(mUniqueGpuProcessId);
} catch (final RemoteException ignored) {
}
}
return mSurfaceAllocator;
}
}