Merge branch 'stable'

This commit is contained in:
Evgeny Poberezkin 2023-10-09 18:04:11 +01:00
commit dffbd32c76
4 changed files with 39 additions and 5 deletions

View File

@ -19,7 +19,11 @@ let bgSuspendTimeout: Int = 5 // seconds
let terminationTimeout: Int = 3 // seconds let terminationTimeout: Int = 3 // seconds
private func _suspendChat(timeout: Int) { private func _suspendChat(timeout: Int) {
if ChatModel.ok { // this is a redundant check to prevent logical errors, like the one fixed in this PR
let state = appStateGroupDefault.get()
if !state.canSuspend {
logger.error("_suspendChat called, current state: \(state.rawValue, privacy: .public)")
} else if ChatModel.ok {
appStateGroupDefault.set(.suspending) appStateGroupDefault.set(.suspending)
apiSuspendChat(timeoutMicroseconds: timeout * 1000000) apiSuspendChat(timeoutMicroseconds: timeout * 1000000)
let endTask = beginBGTask(chatSuspended) let endTask = beginBGTask(chatSuspended)
@ -31,9 +35,7 @@ private func _suspendChat(timeout: Int) {
func suspendChat() { func suspendChat() {
suspendLockQueue.sync { suspendLockQueue.sync {
if appStateGroupDefault.get() != .stopped { _suspendChat(timeout: appSuspendTimeout)
_suspendChat(timeout: appSuspendTimeout)
}
} }
} }
@ -45,15 +47,25 @@ func suspendBgRefresh() {
} }
} }
private var terminating = false
func terminateChat() { func terminateChat() {
logger.debug("terminateChat")
suspendLockQueue.sync { suspendLockQueue.sync {
switch appStateGroupDefault.get() { switch appStateGroupDefault.get() {
case .suspending: case .suspending:
// suspend instantly if already suspending // suspend instantly if already suspending
_chatSuspended() _chatSuspended()
// when apiSuspendChat is called with timeout 0, it won't send any events on suspension
if ChatModel.ok { apiSuspendChat(timeoutMicroseconds: 0) } if ChatModel.ok { apiSuspendChat(timeoutMicroseconds: 0) }
case .stopped: () chatCloseStore()
case .suspended:
chatCloseStore()
case .stopped:
chatCloseStore()
default: default:
terminating = true
// the store will be closed in _chatSuspended when event is received
_suspendChat(timeout: terminationTimeout) _suspendChat(timeout: terminationTimeout)
} }
} }
@ -73,10 +85,14 @@ private func _chatSuspended() {
if ChatModel.shared.chatRunning == true { if ChatModel.shared.chatRunning == true {
ChatReceiver.shared.stop() ChatReceiver.shared.stop()
} }
if terminating {
chatCloseStore()
}
} }
func activateChat(appState: AppState = .active) { func activateChat(appState: AppState = .active) {
logger.debug("DEBUGGING: activateChat") logger.debug("DEBUGGING: activateChat")
terminating = false
suspendLockQueue.sync { suspendLockQueue.sync {
appStateGroupDefault.set(appState) appStateGroupDefault.set(appState)
if ChatModel.ok { apiActivateChat() } if ChatModel.ok { apiActivateChat() }
@ -85,6 +101,7 @@ func activateChat(appState: AppState = .active) {
} }
func initChatAndMigrate(refreshInvitations: Bool = true) { func initChatAndMigrate(refreshInvitations: Bool = true) {
terminating = false
let m = ChatModel.shared let m = ChatModel.shared
if (!m.chatInitialized) { if (!m.chatInitialized) {
do { do {
@ -97,6 +114,7 @@ func initChatAndMigrate(refreshInvitations: Bool = true) {
} }
func startChatAndActivate() { func startChatAndActivate() {
terminating = false
logger.debug("DEBUGGING: startChatAndActivate") logger.debug("DEBUGGING: startChatAndActivate")
if ChatModel.shared.chatRunning == true { if ChatModel.shared.chatRunning == true {
ChatReceiver.shared.start() ChatReceiver.shared.start()

View File

@ -50,6 +50,13 @@ public func chatMigrateInit(_ useKey: String? = nil, confirmMigrations: Migratio
return result return result
} }
public func chatCloseStore() {
let err = fromCString(chat_close_store(getChatCtrl()))
if err != "" {
logger.error("chatCloseStore error: \(err)")
}
}
public func resetChatCtrl() { public func resetChatCtrl() {
chatController = nil chatController = nil
migrationResult = nil migrationResult = nil

View File

@ -80,6 +80,14 @@ public enum AppState: String {
default: return false default: return false
} }
} }
public var canSuspend: Bool {
switch self {
case .active: true
case .bgRefresh: true
default: false
}
}
} }
public enum DBContainer: String { public enum DBContainer: String {

View File

@ -17,6 +17,7 @@ typedef void* chat_ctrl;
// the last parameter is used to return the pointer to chat controller // the last parameter is used to return the pointer to chat controller
extern char *chat_migrate_init(char *path, char *key, char *confirm, chat_ctrl *ctrl); extern char *chat_migrate_init(char *path, char *key, char *confirm, chat_ctrl *ctrl);
extern char *chat_close_store(chat_ctrl ctl);
extern char *chat_send_cmd(chat_ctrl ctl, char *cmd); extern char *chat_send_cmd(chat_ctrl ctl, char *cmd);
extern char *chat_recv_msg(chat_ctrl ctl); extern char *chat_recv_msg(chat_ctrl ctl);
extern char *chat_recv_msg_wait(chat_ctrl ctl, int wait); extern char *chat_recv_msg_wait(chat_ctrl ctl, int wait);