func (t *tcpClient) enqueue(chunk []byte) error { cchunk := C.CString(string(chunk)) defer C.free(unsafe.Pointer(cchunk)) sleepTime := time.Millisecond * 5 for j := 0; j < maxEnqueueAttempts; j++ { err_t := C.tcp_write(t.client.pcb, unsafe.Pointer(cchunk), C.uint16_t(len(chunk)), 1) if err_t == C.ERR_OK { return nil } if err_t == C.ERR_MEM { // Could not enqueue anymore, let's flush and try again. err_t := C.tcp_output(t.client.pcb) if err_t == C.ERR_OK { // Last part was flushed, now continue and try again... time.Sleep(sleepTime) if sleepTime < maxWaitingTime { sleepTime = sleepTime * 2 } continue } return fmt.Errorf("tcp_output: %d", int(err_t)) } } return fmt.Errorf("Could not flush data. Giving up.") }
// tcpWrite wraps tcp_write. func (t *tcpClient) tcpWrite(chunk []byte) error { clen := len(chunk) cchunk := C.CString(string(chunk)) defer C.free(unsafe.Pointer(cchunk)) t.mu.Lock() err_t := C.tcp_write(t.client.pcb, unsafe.Pointer(cchunk), C.uint16_t(clen), C.TCP_WRITE_FLAG_COPY) t.mu.Unlock() switch err_t { case C.ERR_OK: t.accWritten(uint64(clen)) return nil case C.ERR_MEM: return errBufferIsFull } return fmt.Errorf("C.tcp_write: %d", int(err_t)) }