554325746@qq.com
2019-08-22 074c0c376a7b6c91bad7c45e050270a4a6856b6d
shm.go
@@ -1,52 +1,91 @@
package deliver
import (
   "bytes"
   "errors"
   "fmt"
   "io"
   "time"
   "github.com/tmthrgd/shm-go"
)
// SHM share memory
type SHM struct {
   rw   *shm.ReadWriteCloser
   typ  td
   data []byte
   rw     *shm.ReadWriteCloser
   typ    td
}
// Send impl interface Diliver
func (s *SHM) Send(data []byte) error {
   if s.rw == nil {
   if s == nil || s.rw == nil {
      return errors.New("please init shm producer first")
   }
   n, err := s.rw.Write(data)
   if n < 1 {
      fmt.Println("recv data less than 1 length")
   ch := make(chan int)
   go func(){
      n, _ := s.rw.Write(data)
      ch <- n
   }()
   select{
   case <-ch:
      return nil
   case <- time.After(3 * time.Second):
      return errors.New("send time out")
   }
   return err
   return errors.New("send should't here")
   // n, err := s.rw.Write(data)
   // if n < 1 {
   //    fmt.Println("recv data less than 1 length")
   // }
   // return err
}
// Recv impl interface Diliver
func (s *SHM) Recv() ([]byte, error) {
   if s.rw == nil {
   if s == nil || s.rw == nil {
      return nil, errors.New("please open shm consumer first")
   }
   n, err := s.rw.Read(s.data)
   if err == nil || err == io.EOF {
      s.data = s.data[:n:n]
      return s.data, nil
   ch := make(chan []byte)
   go func(){
      buffer := new(bytes.Buffer)
      _, err := s.rw.WriteTo(buffer)
      if err == nil || err == io.EOF {
         ch <- buffer.Bytes()
      }
      ch <- nil
   }()
   select{
   case d := <-ch:
      return d, nil
   case <- time.After(3 * time.Second):
      return nil, errors.New("recv time out")
   }
   return nil, err
   return nil, errors.New("recv should't here")
   // data := make([]byte, maxRecvSize)
   // n, err := s.rw.Read(data)
   // if err == nil || err == io.EOF {
   //    data = data[:n:n]
   //    return data, nil
   // }
   // return nil, err
}
// Close impl interface Deliver
func (s *SHM) Close() {
   if s == nil {
      return
   }
   if s.rw != nil {
      s.rw.Close()
   }
@@ -55,56 +94,52 @@
   }
}
func shmServer(m Mode, url string, args ...interface{}) *SHM {
func shmServer(m Mode, url string, args ...interface{}) (*SHM, error) {
   if m != Shm {
      fmt.Println("this is not a shm mode: ", m)
      return nil
      return nil, errors.New("please use deliver.Shm mode")
   }
   var param []int
   for _, v := range args {
      fmt.Println(v)
      switch v.(type) {
      case int:
         param = append(param, v.(int))
      default:
         fmt.Println("shmProducer recv error parameters")
         return nil
         return nil, errors.New("shmServer created recv error parameters")
      }
   }
   if len(param) != 2 {
      fmt.Println("shmProducer recv too much parameter: ", len(param))
      return nil
   blocks, size := 2, maxRecvSize
   if len(param) == 2 {
      blocks, size = param[0], param[1]
      // return nil, errors.New("shmServer created recv too much parameters")
   }
   shm.Unlink(url)
   if rw, err := shm.CreateSimplex(url, 0644, param[0], param[1]); err == nil {
   rw, err := shm.CreateSimplex(url, 0644, blocks, size)
   if err == nil {
      fmt.Println(rw.Name())
      return &SHM{
         rw,
         agent,
         nil,
      }
      }, nil
   }
   fmt.Println("create simple shm error")
   return nil
   return nil, err
}
func shmClient(m Mode, url string, args ...interface{}) *SHM {
func shmClient(m Mode, url string, args ...interface{}) (*SHM, error) {
   if m != Shm {
      fmt.Println("this is not a shm mode: ", m)
      return nil
      return nil, errors.New("please use deliver.Shm mode")
   }
   if rw, err := shm.OpenSimplex(url); err == nil {
   rw, err := shm.OpenSimplex(url)
   if err == nil {
      return &SHM{
         rw,
         coactee,
         make([]byte, maxRecvSize),
      }
      }, nil
   }
   fmt.Println("shmConsumer open error")
   return nil
   return nil, err
}