Skip to content

Commit

Permalink
Use a separate thread to install native signal handler to greatly red…
Browse files Browse the repository at this point in the history
…uce delay
  • Loading branch information
bidetofevil committed Mar 14, 2024
1 parent 6f7d42e commit 56e6249
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import io.embrace.android.embracesdk.session.properties.EmbraceSessionProperties
import io.embrace.android.embracesdk.storage.NATIVE_CRASH_FILE_FOLDER
import io.embrace.android.embracesdk.storage.StorageService
import io.embrace.android.embracesdk.worker.BackgroundWorker
import io.embrace.android.embracesdk.worker.TaskPriority
import java.io.BufferedReader
import java.io.File
import java.io.FileInputStream
Expand All @@ -59,8 +58,8 @@ internal class EmbraceNdkService(
private val logger: InternalEmbraceLogger,
private val repository: EmbraceNdkServiceRepository,
private val delegate: NdkServiceDelegate.NdkDelegate,
private val cleanCacheWorker: BackgroundWorker,
private val ndkStartupWorker: BackgroundWorker,
private val backgroundWorker: BackgroundWorker,
highPriorityWorker: BackgroundWorker,
/**
* The device architecture.
*/
Expand Down Expand Up @@ -89,7 +88,11 @@ internal class EmbraceNdkService(
null
}
if (configService.autoDataCaptureBehavior.isNdkEnabled()) {
ndkStartupWorker.submit(priority = TaskPriority.CRITICAL) {
// Workaround to load native symbols synchronously so the main thread won't be blocked by the background
// thread doing this when the native ANR monitoring tries to load this
// Remove this once the native ANR initialization is done on the background thread too.
sharedObjectLoader.loadEmbraceNative()
highPriorityWorker.submit {
Systrace.traceSynchronous("init-ndk-service") {
processStateService.addListener(this)
if (appFramework == AppFramework.UNITY) {
Expand Down Expand Up @@ -120,14 +123,18 @@ internal class EmbraceNdkService(
override fun onSessionPropertiesUpdate(properties: Map<String, String>) {
logger.logDeveloper("EmbraceNDKService", "NDK update: (session properties): $properties")
if (isInstalled) {
updateDeviceMetaData()
backgroundWorker.submit {
updateDeviceMetaData()
}
}
}

override fun onUserInfoUpdate() {
logger.logDeveloper("EmbraceNDKService", "NDK update (user)")
if (isInstalled) {
updateDeviceMetaData()
backgroundWorker.submit {
updateDeviceMetaData()
}
}
}

Expand Down Expand Up @@ -459,7 +466,7 @@ internal class EmbraceNdkService(
}

private fun cleanOldCrashFiles() {
cleanCacheWorker.submit {
backgroundWorker.submit {
logger.logDeveloper("EmbraceNDKService", "Processing clean of old crash files.")
val sortedFiles = repository.sortNativeCrashes(true)
val deleteCount = sortedFiles.size - MAX_NATIVE_CRASH_FILES_ALLOWED
Expand Down Expand Up @@ -584,19 +591,16 @@ internal class EmbraceNdkService(
}

/**
* Compute NDK metadata on a background thread.
* Compute NDK metadata
*/
private fun updateDeviceMetaData() {
ndkStartupWorker.submit {
logger.logDeveloper("EmbraceNDKService", "Processing NDK metadata update on bg thread.")
var newDeviceMetaData = getMetaData(true)
logger.logDeveloper("EmbraceNDKService", "NDK update (metadata): $newDeviceMetaData")
if (newDeviceMetaData.length >= EMB_DEVICE_META_DATA_SIZE) {
logger.logDebug("Removing session properties from metadata to avoid exceeding size limitation for NDK metadata.")
newDeviceMetaData = getMetaData(false)
}
delegate._updateMetaData(newDeviceMetaData)
var newDeviceMetaData = getMetaData(true)
logger.logDeveloper("EmbraceNDKService", "NDK update (metadata): $newDeviceMetaData")
if (newDeviceMetaData.length >= EMB_DEVICE_META_DATA_SIZE) {
logger.logDebug("Removing session properties from metadata to avoid exceeding size limitation for NDK metadata.")
newDeviceMetaData = getMetaData(false)
}
delegate._updateMetaData(newDeviceMetaData)
}

private fun getMetaData(includeSessionProperties: Boolean): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ internal class NativeModuleImpl(
embraceNdkServiceRepository,
NdkDelegateImpl(),
workerThreadModule.backgroundWorker(WorkerName.BACKGROUND_REGISTRATION),
workerThreadModule.backgroundWorker(WorkerName.BACKGROUND_REGISTRATION),
workerThreadModule.backgroundWorker(WorkerName.SERVICE_INIT),
essentialServiceModule.deviceArchitecture,
coreModule.jsonSerializer
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.embrace.android.embracesdk.arch.DataCaptureOrchestrator
import io.embrace.android.embracesdk.arch.SessionType
import io.embrace.android.embracesdk.comms.delivery.DeliveryService
import io.embrace.android.embracesdk.config.ConfigService
import io.embrace.android.embracesdk.internal.Systrace
import io.embrace.android.embracesdk.internal.clock.Clock
import io.embrace.android.embracesdk.internal.utils.Provider
import io.embrace.android.embracesdk.logging.InternalEmbraceLogger
Expand Down Expand Up @@ -44,7 +45,7 @@ internal class SessionOrchestratorImpl(

init {
processStateService.addListener(this)
createInitialSession()
Systrace.traceSynchronous("start-first-session") { createInitialSession() }
}

private fun createInitialSession() {
Expand Down Expand Up @@ -240,6 +241,7 @@ internal class SessionOrchestratorImpl(
}
}
}

ProcessState.BACKGROUND -> scheduleBackgroundActivitySave(endProcessState, newState)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,9 @@ internal enum class WorkerName(internal val threadName: String) {
* Monitor thread that checks the main thread for ANRs.
*/
ANR_MONITOR("anr-monitor"),

/**
* Initialize services asynchronously
*/
SERVICE_INIT("service-init"),
}

0 comments on commit 56e6249

Please sign in to comment.