pass_chan_slice.go raw
1 package main
2
3 import "io"
4
5 // B.0.4 test: chan element type with []byte slice field.
6 // Before Codec invocation, raw memcpy across the spawn boundary sent
7 // only the slice header (ptr/len/cap), causing the receiver to
8 // dereference a parent-only address - SIGSEGV.
9 //
10 // With Codec, EncodeTo writes the byte payload as length-prefixed
11 // data; DecodeFrom allocates a fresh slice in the receiver's heap.
12
13 type Blob struct {
14 Size int32
15 Data []byte
16 }
17
18 func (b *Blob) EncodeTo(w io.Writer) (encErr error) {
19 var sz [4]byte
20 sz[0] = byte(b.Size)
21 sz[1] = byte(b.Size >> 8)
22 sz[2] = byte(b.Size >> 16)
23 sz[3] = byte(b.Size >> 24)
24 _, encErr = w.Write(sz[:])
25 if encErr != nil {
26 return encErr
27 }
28 _, encErr = w.Write(b.Data)
29 return encErr
30 }
31
32 func (b *Blob) DecodeFrom(r io.Reader) (decErr error) {
33 var sz [4]byte
34 _, decErr = io.ReadFull(r, sz[:])
35 if decErr != nil {
36 return decErr
37 }
38 b.Size = int32(sz[0]) | int32(sz[1])<<8 | int32(sz[2])<<16 | int32(sz[3])<<24
39 b.Data = make([]byte, b.Size)
40 _, decErr = io.ReadFull(r, b.Data)
41 return decErr
42 }
43
44 func echo(in chan Blob, out chan Blob) {
45 b := <-in
46 bad := int32(-1)
47 for i := int32(0); i < b.Size; i++ {
48 if b.Data[i] != byte(i) {
49 bad = i
50 break
51 }
52 }
53 if bad != -1 {
54 out <- Blob{Size: bad, Data: nil}
55 return
56 }
57 out <- Blob{Size: b.Size, Data: b.Data}
58 }
59
60 func main() {
61 const N = int32(100000) // 100 KB - exceeds kernel pipe buffer to exercise partial syscalls
62 in := make(chan Blob)
63 out := make(chan Blob)
64 spawn(echo, in, out)
65
66 data := make([]byte, N)
67 for i := int32(0); i < N; i++ {
68 data[i] = byte(i)
69 }
70 in <- Blob{Size: N, Data: data}
71
72 got := <-out
73 if got.Size != N {
74 println("FAIL:slice", "size", got.Size, "want", N)
75 return
76 }
77 for i := int32(0); i < N; i++ {
78 if got.Data[i] != byte(i) {
79 println("FAIL:slice", "byte mismatch at", i)
80 return
81 }
82 }
83 println("PASS:slice-codec")
84 }
85