Leia exatamente n bytes de InputStream no Swift 4

Eu tenho um servidor que me envia mensagens pelo TCP, onde os 4 primeiros bytes determinam o comprimento do restante da mensagem. Então eu preciso

1) leia 4 bytes em um UInt32 (funciona) e armazene-o embytes_expected

2) lerbytes_expected bytes emmensagem

No momento, meu código fica assim:

private let inputStreamAccessQueue  = DispatchQueue(label: "SynchronizedInputStreamAccess")
func inputStreamHandler(_ event: Stream.Event) {
    switch event {
        case Stream.Event.hasBytesAvailable:
            self.handleInput()

        ...
    }
}
func handleInput() {
    // **QUESTION: Do I use this barrier wrong?**
    self.inputStreamAccessQueue.sync(flags: .barrier) {            
        guard let istr = self.inputStream else {
            log.error(self.buildLogMessage("InputStream is nil"))
            return
        }

        guard istr.hasBytesAvailable else {
            log.error(self.buildLogMessage("handleInput() called when inputstream has no bytes available"))
            return
        }

        let lengthbuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: 4)
        defer { lengthbuffer.deallocate(capacity: 4) }
        let lenbytes_read = istr.read(lengthbuffer, maxLength: 4)

        guard lenbytes_read == 4 else {
            self.errorHandler(NetworkingError.InputError("Input Stream received \(lenbytes_read) (!=4) bytes"))
            return
        }

        let bytes_expected = Int(UnsafeRawPointer(lengthbuffer).load(as: UInt32.self).bigEndian)
        log.info(self.buildLogMessage("expect \(bytes_expected) bytes"))

        print("::DEBUG", call, "bytes_expected", bytes_expected)

        var message = ""
        var bytes_missing = bytes_expected
        while bytes_missing > 0 {
            //print("::DEBUG", call, "bytes_missing", bytes_missing)
            let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bytes_missing)
            let bytes_read = istr.read(buffer, maxLength: bytes_missing)

            print("::DEBUG", call, "bytes_read", bytes_read)

            guard bytes_read > 0 else {
                print("bytes_read not > 0: \(bytes_read)")
                return
            }

            guard bytes_read <= bytes_missing else {
                print("Read more bytes than expected. missing=\(bytes_missing), read=\(bytes_read)")
                return
            }

            guard let partial_message = String(bytesNoCopy: buffer, length: bytes_read, encoding: .utf8, freeWhenDone: true) else {
                log.error("ERROR WHEN READING")
                return
            }

            message = message + partial_message
            bytes_missing -= bytes_read
        }

        self.handleMessage(message)
    }
}

Meu problema é que o istr.read (buffer, maxLength: bytes_missing) às vezes não lê todas as mensagens de uma só vez, então faço um loop até ler tudo o que quero. Mas ainda vejo meu aplicativo travando (raramente) porque handleInput () é chamado novamente enquanto outra chamada para esse método ainda está em execução. Nesse caso, bytes_expected contém valores aleatórios e o aplicativo trava devido à alocação ilegal de memória.

Eu pensei que poderia evitar isso usando a barreira. Mas parece que isso não funciona ... Estou usando a barreira errada?

questionAnswers(2)

yourAnswerToTheQuestion