zhangmeng
2019-08-30 f8dadae1c1254ec79dcaff16257d9c54c2ee2e43
提交 | 用户 | age
9a89af 1 package deliver
Z 2
3 import (
4     "errors"
5     "fmt"
fb46ee 6     "io"
4f3bd6 7     "reflect"
512af9 8     "time"
4f3bd6 9     "unsafe"
9a89af 10
b8c958 11     "basic.com/valib/shm.git"
9a89af 12 )
Z 13
14 // SHM share memory
15 type SHM struct {
93ff14 16     rw  *shm.ReadWriteCloser
Z 17     typ td
4f3bd6 18
f8dada 19     recvData        []byte
Z 20     recvSliceHeader *reflect.SliceHeader
9a89af 21 }
Z 22
23 // Send impl interface Diliver
24 func (s *SHM) Send(data []byte) error {
c2bbe3 25     if s == nil || s.rw == nil {
9a89af 26         return errors.New("please init shm producer first")
Z 27     }
28
fb46ee 29     n, err := s.rw.Write(data)
Z 30     if n < 1 {
31         fmt.Println("recv data less than 1 length")
9a89af 32     }
Z 33
fb46ee 34     return err
9a89af 35 }
Z 36
37 // Recv impl interface Diliver
38 func (s *SHM) Recv() ([]byte, error) {
39
c2bbe3 40     if s == nil || s.rw == nil {
9a89af 41         return nil, errors.New("please open shm consumer first")
Z 42     }
43
4f3bd6 44     // orig
Z 45
20a4c4 46     // data := make([]byte, maxRecvSize)
Z 47     // n, err := s.rw.Read(data)
48     // if err == nil || err == io.EOF {
020e17 49     //     data := data[:n:n]
20a4c4 50     //     return data, nil
Z 51     // }
52
4f3bd6 53     // cur
Z 54
55     // data, err := s.rw.DirectRead()
56     // if err == nil || err == io.EOF {
57     //     return data, nil
58     // }
59
60     // new
61
62     if s.recvData == nil {
63         s.recvData = make([]byte, maxRecvSize)
f8dada 64         s.recvSliceHeader = (*reflect.SliceHeader)(unsafe.Pointer(&s.recvData))
9a89af 65     }
f8dada 66     // sliceHeader.Cap = maxRecvSize
Z 67     s.recvSliceHeader.Len = maxRecvSize
4f3bd6 68
Z 69     n, err := s.rw.Read(s.recvData)
70     if err == nil || err == io.EOF {
f8dada 71         s.recvSliceHeader.Len = n
4f3bd6 72         return s.recvData, nil
Z 73     }
74
fb46ee 75     return nil, err
9a89af 76 }
Z 77
020e17 78 // Recv2 impl interface
058b21 79 func (s *SHM) Recv2(data []byte) (int, error) {
020e17 80     if s == nil || s.rw == nil {
058b21 81         return 0, errors.New("please open shm consumer first")
020e17 82     }
Z 83
84     n, err := s.rw.Read(data)
85     if err == nil || err == io.EOF {
86         data = data[:n:n]
058b21 87         return n, nil
020e17 88     }
Z 89
058b21 90     return 0, err
020e17 91 }
Z 92
9a89af 93 // Close impl interface Deliver
Z 94 func (s *SHM) Close() {
c2bbe3 95     if s == nil {
Z 96         return
97     }
9a89af 98     if s.rw != nil {
Z 99         s.rw.Close()
100     }
101     if s.typ == agent {
102         shm.Unlink(s.rw.Name())
103     }
104 }
105
c2bbe3 106 func shmServer(m Mode, url string, args ...interface{}) (*SHM, error) {
9a89af 107     if m != Shm {
c2bbe3 108         return nil, errors.New("please use deliver.Shm mode")
9a89af 109     }
Z 110
111     var param []int
112     for _, v := range args {
113         switch v.(type) {
114         case int:
115             param = append(param, v.(int))
116         default:
117
c2bbe3 118             return nil, errors.New("shmServer created recv error parameters")
9a89af 119         }
Z 120     }
fb46ee 121
512af9 122     blocks, size := 2, maxRecvSize
Z 123     if len(param) == 2 {
124         blocks, size = param[0], param[1]
125         // return nil, errors.New("shmServer created recv too much parameters")
126     }
127
128     time.Sleep(time.Millisecond)
25d8c3 129     shm.Unlink(url)
Z 130
512af9 131     rw, err := shm.CreateSimplex(url, 0644, blocks, size)
c2bbe3 132     if err == nil {
e3c917 133         fmt.Println(rw.Name())
9a89af 134         return &SHM{
20a4c4 135             rw:  rw,
Z 136             typ: agent,
c2bbe3 137         }, nil
9a89af 138     }
Z 139
c2bbe3 140     return nil, err
9a89af 141 }
Z 142
c2bbe3 143 func shmClient(m Mode, url string, args ...interface{}) (*SHM, error) {
9a89af 144     if m != Shm {
c2bbe3 145         return nil, errors.New("please use deliver.Shm mode")
9a89af 146     }
Z 147
c2bbe3 148     rw, err := shm.OpenSimplex(url)
Z 149     if err == nil {
9a89af 150         return &SHM{
20a4c4 151             rw:  rw,
Z 152             typ: coactee,
c2bbe3 153         }, nil
9a89af 154     }
c2bbe3 155     return nil, err
9a89af 156 }