mgriebling/SwiftMath

Thread-safe exception

Closed this issue · 2 comments

Description of the Exception

When running the below concurrently in a multi-thread situation, the below functions sometimes hit thread-safe exception.

  • getInterElementSpaces()
  • MTMathAtomFactory.delimValueToName
  • MTMathAtomFactory.accentValueToName
  • MTMathAtomFactory.textToLatexSymbolName

Thread 2: EXC_BAD_ACCESS (code=1, address=0xfffffffffffffff0)

Test code run repeatedly

    private let executionQueue = DispatchQueue(label: "com.swiftmath.concurrencytests", attributes: .concurrent)
    private let executionGroup = DispatchGroup()
    
    let totalCases = 20
    var testCount = 0
    
    func testSwiftMathConcurrentScript() throws {
        for caseNumber in 0 ..< totalCases {
            helperConcurrency(caseNumber, in: executionGroup, on: executionQueue) {
                let result1 = getInterElementSpaces()
                let result2 = MTMathAtomFactory.delimValueToName
                let result3 = MTMathAtomFactory.accentValueToName
                let result4 = MTMathAtomFactory.textToLatexSymbolName
                XCTAssertNotNil(result1)
                XCTAssertNotNil(result2)
                XCTAssertNotNil(result3)
                XCTAssertNotNil(result4)
            }
        }
        executionGroup.notify(queue: .main) { [weak self] in
            // print("All test cases completed: \(self?.testCount ?? 0)")
        }
        executionGroup.wait()
    }
    func helperConcurrency(_ count: Int, in group: DispatchGroup, on queue: DispatchQueue, _ testClosure: @escaping () -> (Void)) {
        let workitem = DispatchWorkItem {
            testClosure()
        }
        workitem.notify(queue: .main) { [weak self] in
            self?.testCount += 1
        }
        queue.async(group: group, execute: workitem)
    }

Further investigations

At the moment the below static function is not invoked by any code, however, if in-use, will also cause thread-safety exception.

    public static func add(latexSymbol name: String, value: MTMathAtom) {
        supportedLatexSymbols[name] = value
        Self.textToLatexSymbolName[value.nucleus] = name
    }

issued a push request.

Incorporated. Thanks for the fix.