From 6023ff8af09c93a677fd8d6dcc61b005bcdd4c52 Mon Sep 17 00:00:00 2001 From: jack Date: Fri, 4 Jul 2025 15:59:56 +0200 Subject: [PATCH] Fix thread safety issue causing peer count to show 0 - Add thread safety lock for activePeers Set access - Force UI update when peer list changes with objectWillChange - Add debug logging to track peer additions/removals - This fixes the 'alone :/' display when peers are actually connected --- bitchat/Services/BluetoothMeshService.swift | 18 +++++++++++++++--- bitchat/ViewModels/ChatViewModel.swift | 7 +++---- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/bitchat/Services/BluetoothMeshService.swift b/bitchat/Services/BluetoothMeshService.swift index 9c60406a..5084ad5c 100644 --- a/bitchat/Services/BluetoothMeshService.swift +++ b/bitchat/Services/BluetoothMeshService.swift @@ -33,6 +33,7 @@ class BluetoothMeshService: NSObject { private var peerNicknames: [String: String] = [:] private let peerNicknamesLock = NSLock() private var activePeers: Set = [] // Track all active peers + private let activePeersLock = NSLock() // Thread safety for activePeers private var peerRSSI: [String: NSNumber] = [:] // Track RSSI values for peers private var peripheralRSSI: [String: NSNumber] = [:] // Track RSSI by peripheral ID during discovery private var loggedCryptoErrors = Set() // Track which peers we've logged crypto errors for @@ -337,7 +338,9 @@ class BluetoothMeshService: NSObject { // Clear all tracking connectedPeripherals.removeAll() subscribedCentrals.removeAll() + activePeersLock.lock() activePeers.removeAll() + activePeersLock.unlock() announcedPeers.removeAll() // Clear announcement tracking @@ -757,7 +760,11 @@ class BluetoothMeshService: NSObject { private func getAllConnectedPeerIDs() -> [String] { // Return all valid active peers - let validPeers = activePeers.filter { peerID in + activePeersLock.lock() + let peersCopy = activePeers + activePeersLock.unlock() + + let validPeers = peersCopy.filter { peerID in // Ensure peerID is valid return !peerID.isEmpty && peerID != "unknown" && @@ -765,6 +772,7 @@ class BluetoothMeshService: NSObject { peerID.count <= 8 // Filter out temp IDs } + print("[DEBUG] Active peers: \(peersCopy), Valid peers: \(validPeers)") return Array(validPeers).sorted() } @@ -1328,6 +1336,7 @@ class BluetoothMeshService: NSObject { // Add to active peers immediately on key exchange activePeers.insert(senderID) + print("[DEBUG] Added peer \(senderID) to active peers via key exchange") let connectedPeerIDs = self.getAllConnectedPeerIDs() DispatchQueue.main.async { self.delegate?.didUpdatePeerList(connectedPeerIDs) @@ -1373,8 +1382,11 @@ class BluetoothMeshService: NSObject { // Add to active peers if not already there if senderID != "unknown" { - if !activePeers.contains(senderID) { - activePeers.insert(senderID) + activePeersLock.lock() + let wasInserted = activePeers.insert(senderID).inserted + activePeersLock.unlock() + if wasInserted { + print("[DEBUG] Added peer \(senderID) to active peers via announce") } // Show join message only for first announce diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index 9b4667e2..a4ce761d 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -588,13 +588,12 @@ extension ChatViewModel: BitchatDelegate { } func didUpdatePeerList(_ peers: [String]) { + print("[DEBUG] Updating peer list: \(peers.count) peers: \(peers)") connectedPeers = peers isConnected = !peers.isEmpty - // If we just disconnected from all peers, ensure UI updates - if peers.isEmpty && isConnected { - isConnected = false - } + // Force UI update + objectWillChange.send() // If we're in a private chat with someone who disconnected, exit the chat if let currentChatPeer = selectedPrivateChatPeer,