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