New file |
| | |
| | | package shmqueue |
| | | |
| | | import ( |
| | | "reflect" |
| | | "unsafe" |
| | | ) |
| | | |
| | | // lock free queue struct |
| | | type ShmDataInfo struct { |
| | | Capacity uint32 |
| | | Cache []byte |
| | | } |
| | | |
| | | // shmData2Info convert []byte to *ShmDataInfo |
| | | func shmData2Info(b []byte) *ShmDataInfo { |
| | | return (*ShmDataInfo)(unsafe.Pointer( |
| | | (*reflect.SliceHeader)(unsafe.Pointer(&b)).Data, |
| | | )) |
| | | } |
| | | |
| | | // ConvertToSlice convert to []byte |
| | | func ptr2Slice(s unsafe.Pointer, size int) []byte { |
| | | var x reflect.SliceHeader |
| | | x.Len = size |
| | | x.Cap = size |
| | | x.Data = uintptr(s) |
| | | return *(*[]byte)(unsafe.Pointer(&x)) |
| | | } |
| | | |
| | | func WriteShmData(data []byte, shmId int) error { |
| | | shmdata,err := Attach(shmId) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | sdi := shmData2Info(shmdata) |
| | | if len(data) <= len(shmdata) { |
| | | sdi.Capacity = uint32(len(data)) |
| | | } else { |
| | | sdi.Capacity = uint32(len(shmdata)) |
| | | } |
| | | |
| | | tmpData := ptr2Slice(unsafe.Pointer(&sdi.Cache), int(sdi.Capacity)) |
| | | copy(tmpData, data) |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func ReadShmData(shmId int) ([]byte,error) { |
| | | shmdata,err := Attach(shmId) |
| | | if err != nil { |
| | | return nil,err |
| | | } |
| | | |
| | | sdi := shmData2Info(shmdata) |
| | | tmpData := ptr2Slice(unsafe.Pointer(&sdi.Cache), int(sdi.Capacity)) |
| | | |
| | | return tmpData, nil |
| | | } |