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.") }
func (t *tcpClient) flush() error { for { blen := t.outbuf.Len() if blen > writeBufSize { blen = writeBufSize } if blen == 0 { break } chunk := make([]byte, blen) if _, err := t.outbuf.Read(chunk); err != nil { return err } if err := t.enqueue(chunk); err != nil { return err } } err_t := C.tcp_output(t.client.pcb) if err_t != C.ERR_OK { return fmt.Errorf("tcp_output: %d", int(err_t)) } return nil }
// tcpOutput wraps tcp_output. func (t *tcpClient) tcpOutput() error { t.mu.Lock() err_t := C.tcp_output(t.client.pcb) t.mu.Unlock() if err_t != C.ERR_OK { return fmt.Errorf("C.tcp_output: %d", int(err_t)) } return nil }