mirror of
https://github.com/openlibrecommunity/olcng.git
synced 2026-07-03 14:05:17 +02:00
fix(service): prevent concurrent operations with synchronization locks
This commit is contained in:
@@ -30,6 +30,8 @@ object V2RayServiceManager {
|
||||
private val coreController: CoreController = V2RayNativeManager.newCoreController(CoreCallback())
|
||||
private val mMsgReceive = ReceiveMessageHandler()
|
||||
private var currentConfig: ProfileItem? = null
|
||||
private val operationLock = Any()
|
||||
@Volatile private var isOperationInProgress = false
|
||||
|
||||
var serviceControl: SoftReference<ServiceControl>? = null
|
||||
set(value) {
|
||||
@@ -57,13 +59,27 @@ object V2RayServiceManager {
|
||||
* @param guid The GUID of the server configuration to use (optional).
|
||||
*/
|
||||
fun startVService(context: Context, guid: String? = null) {
|
||||
Log.i(AppConfig.TAG, "StartCore-Manager: startVService from ${context::class.java.simpleName}")
|
||||
|
||||
if (guid != null) {
|
||||
MmkvManager.setSelectServer(guid)
|
||||
synchronized(operationLock) {
|
||||
if (isOperationInProgress) {
|
||||
Log.w(AppConfig.TAG, "StartCore-Manager: Operation already in progress")
|
||||
return
|
||||
}
|
||||
isOperationInProgress = true
|
||||
}
|
||||
|
||||
startContextService(context)
|
||||
try {
|
||||
Log.i(AppConfig.TAG, "StartCore-Manager: startVService from ${context::class.java.simpleName}")
|
||||
|
||||
if (guid != null) {
|
||||
MmkvManager.setSelectServer(guid)
|
||||
}
|
||||
|
||||
startContextService(context)
|
||||
} finally {
|
||||
synchronized(operationLock) {
|
||||
isOperationInProgress = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,8 +87,21 @@ object V2RayServiceManager {
|
||||
* @param context The context from which the service is stopped.
|
||||
*/
|
||||
fun stopVService(context: Context) {
|
||||
//context.toast(R.string.toast_services_stop)
|
||||
MessageUtil.sendMsg2Service(context, AppConfig.MSG_STATE_STOP, "")
|
||||
synchronized(operationLock) {
|
||||
if (isOperationInProgress) {
|
||||
Log.w(AppConfig.TAG, "StartCore-Manager: Operation already in progress")
|
||||
return
|
||||
}
|
||||
isOperationInProgress = true
|
||||
}
|
||||
|
||||
try {
|
||||
MessageUtil.sendMsg2Service(context, AppConfig.MSG_STATE_STOP, "")
|
||||
} finally {
|
||||
synchronized(operationLock) {
|
||||
isOperationInProgress = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -385,11 +414,17 @@ object V2RayServiceManager {
|
||||
|
||||
AppConfig.MSG_STATE_STOP -> {
|
||||
Log.i(AppConfig.TAG, "StartCore-Manager: Stop service")
|
||||
synchronized(operationLock) {
|
||||
isOperationInProgress = false
|
||||
}
|
||||
serviceControl.stopService()
|
||||
}
|
||||
|
||||
AppConfig.MSG_STATE_RESTART -> {
|
||||
Log.i(AppConfig.TAG, "StartCore-Manager: Restart service")
|
||||
synchronized(operationLock) {
|
||||
isOperationInProgress = false
|
||||
}
|
||||
serviceControl.stopService()
|
||||
Thread.sleep(500L)
|
||||
startVService(serviceControl.getService())
|
||||
|
||||
@@ -52,6 +52,7 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect
|
||||
val mainViewModel: MainViewModel by viewModels()
|
||||
private lateinit var groupPagerAdapter: GroupPagerAdapter
|
||||
private var tabMediator: TabLayoutMediator? = null
|
||||
@Volatile private var isFabOperationInProgress = false
|
||||
|
||||
private val requestVpnPermission = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.resultCode == RESULT_OK) {
|
||||
@@ -201,12 +202,24 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect
|
||||
}
|
||||
|
||||
private fun handleFabAction() {
|
||||
if (isFabOperationInProgress) {
|
||||
return
|
||||
}
|
||||
isFabOperationInProgress = true
|
||||
|
||||
applyRunningState(isLoading = true, isRunning = false)
|
||||
|
||||
if (mainViewModel.isRunning.value == true) {
|
||||
V2RayServiceManager.stopVService(this)
|
||||
} else {
|
||||
startV2RayWithPermission()
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
if (mainViewModel.isRunning.value == true) {
|
||||
V2RayServiceManager.stopVService(this@MainActivity)
|
||||
} else {
|
||||
startV2RayWithPermission()
|
||||
}
|
||||
} finally {
|
||||
delay(1000)
|
||||
isFabOperationInProgress = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,29 +233,42 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect
|
||||
}
|
||||
|
||||
private fun handleLiteAction() {
|
||||
if (mainViewModel.isRunning.value == true) {
|
||||
V2RayServiceManager.stopVService(this)
|
||||
if (isFabOperationInProgress) {
|
||||
return
|
||||
}
|
||||
|
||||
showStatus("Обновление профилей...")
|
||||
showLoading()
|
||||
isLiteTesting = true
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val result = mainViewModel.updateConfigViaSubAll()
|
||||
delay(500L)
|
||||
launch(Dispatchers.Main) {
|
||||
if (result.configCount > 0) {
|
||||
mainViewModel.reloadServerList()
|
||||
showStatus("Обновлено ${result.configCount} профилей. Запуск теста...")
|
||||
} else {
|
||||
showStatus("Запуск теста...")
|
||||
isFabOperationInProgress = true
|
||||
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
if (mainViewModel.isRunning.value == true) {
|
||||
V2RayServiceManager.stopVService(this@MainActivity)
|
||||
delay(1000)
|
||||
}
|
||||
hideLoading()
|
||||
|
||||
delay(500L)
|
||||
showStatus("Выполняется замер задержки. Ожидаем завершения...")
|
||||
mainViewModel.testAllRealPing()
|
||||
|
||||
showStatus("Обновление профилей...")
|
||||
showLoading()
|
||||
isLiteTesting = true
|
||||
|
||||
launch(Dispatchers.IO) {
|
||||
val result = mainViewModel.updateConfigViaSubAll()
|
||||
delay(500L)
|
||||
launch(Dispatchers.Main) {
|
||||
if (result.configCount > 0) {
|
||||
mainViewModel.reloadServerList()
|
||||
showStatus("Обновлено ${result.configCount} профилей. Запуск теста...")
|
||||
} else {
|
||||
showStatus("Запуск теста...")
|
||||
}
|
||||
hideLoading()
|
||||
|
||||
delay(500L)
|
||||
showStatus("Выполняется замер задержки. Ожидаем завершения...")
|
||||
mainViewModel.testAllRealPing()
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
delay(1000)
|
||||
isFabOperationInProgress = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -269,12 +295,22 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect
|
||||
}
|
||||
|
||||
fun restartV2Ray() {
|
||||
if (mainViewModel.isRunning.value == true) {
|
||||
V2RayServiceManager.stopVService(this)
|
||||
if (isFabOperationInProgress) {
|
||||
return
|
||||
}
|
||||
isFabOperationInProgress = true
|
||||
|
||||
lifecycleScope.launch {
|
||||
delay(500)
|
||||
startV2Ray()
|
||||
try {
|
||||
if (mainViewModel.isRunning.value == true) {
|
||||
V2RayServiceManager.stopVService(this@MainActivity)
|
||||
}
|
||||
delay(1000)
|
||||
startV2Ray()
|
||||
} finally {
|
||||
delay(500)
|
||||
isFabOperationInProgress = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user