github.com/iceber/iouring-go@v0.0.0-20230403020409-002cfd2e2a90/examples/concurrent-cat/main.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 7 "github.com/iceber/iouring-go" 8 ) 9 10 var blockSize int64 = 32 * 1024 11 12 func main() { 13 if len(os.Args) <= 1 { 14 fmt.Printf("Usage: %s file1 file2 ...\n", os.Args[0]) 15 } 16 17 iour, err := iouring.New(10) 18 if err != nil { 19 panic(err) 20 } 21 defer iour.Close() 22 23 compCh := make(chan iouring.Result, 1) 24 25 go func() { 26 for _, filename := range os.Args[1:] { 27 file, err := os.Open(filename) 28 if err != nil { 29 panic(fmt.Sprintf("open %s error: %v", filename, err)) 30 } 31 if err := read(iour, file, compCh); err != nil { 32 panic(fmt.Sprintf("submit read %s request error: %v", filename, err)) 33 } 34 } 35 }() 36 37 files := len(os.Args) - 1 38 39 var prints int 40 for result := range compCh { 41 filename := result.GetRequestInfo().(string) 42 if err := result.Err(); err != nil { 43 fmt.Printf("read %s error: %v\n", filename, result.Err()) 44 } 45 46 fmt.Printf("%s: \n", filename) 47 for _, buffer := range result.GetRequestBuffers() { 48 fmt.Printf("%s", buffer) 49 } 50 fmt.Println() 51 52 prints++ 53 if prints == files { 54 break 55 } 56 } 57 58 fmt.Println("cat successful") 59 } 60 61 func read(iour *iouring.IOURing, file *os.File, ch chan iouring.Result) error { 62 stat, err := file.Stat() 63 if err != nil { 64 return err 65 } 66 size := stat.Size() 67 68 blocks := int(size / blockSize) 69 if size%blockSize != 0 { 70 blocks++ 71 } 72 73 buffers := make([][]byte, blocks) 74 for i := 0; i < blocks; i++ { 75 buffers[i] = make([]byte, blockSize) 76 } 77 if size%blockSize != 0 { 78 buffers[blocks-1] = buffers[blocks-1][:size%blockSize] 79 } 80 81 prepRequest := iouring.Readv(int(file.Fd()), buffers).WithInfo(file.Name()) 82 _, err = iour.SubmitRequest(prepRequest, ch) 83 return err 84 }