| | |
| | | "context" |
| | | "fmt" |
| | | "time" |
| | | "github.com/gen2brain/shm" |
| | | shm "basic.com/valib/goshm.git" |
| | | ) |
| | | |
| | | const ( |
| | | sleepPeriod = time.Duration(5) * time.Millisecond |
| | | attachTimes = 100 |
| | | ) |
| | | |
| | | // NewBlock shm block with size |
| | |
| | | } |
| | | |
| | | return data, id, nil |
| | | } |
| | | |
| | | // NewBlockOnly shm block with size, no attach |
| | | func NewBlockOnly(size int, key int) (int, error) { |
| | | id, err := shm.Get(key, size, shm.IPC_CREAT|0666) |
| | | if err != nil || id == -1 { |
| | | fmt.Printf("NewBlock Get:%x, %v\n", key, err) |
| | | return -1, err |
| | | } |
| | | return id, nil |
| | | } |
| | | |
| | | // AttachBlock attach exist shm |
| | |
| | | if err == nil { |
| | | break loopB |
| | | } |
| | | time.Sleep(time.Millisecond) |
| | | time.Sleep(sleepPeriod) |
| | | data, id, err = NewBlock(size, key) |
| | | } |
| | | } |
| | |
| | | if err == nil { |
| | | break loopB |
| | | } |
| | | time.Sleep(time.Millisecond) |
| | | time.Sleep(sleepPeriod) |
| | | data, id, err = AttachBlock(key) |
| | | } |
| | | } |
| | | } |
| | | return data, id |
| | | } |
| | | |
| | | //AttachRawShmTimeout don't create |
| | | func AttachRawShmTimeout(ctx context.Context, key int) ([]byte, int) { |
| | | tryCount := 0 |
| | | data, id, err := AttachBlock(key) |
| | | if err != nil { |
| | | loopB: |
| | | for { |
| | | select { |
| | | case <-ctx.Done(): |
| | | return nil, -1 |
| | | default: |
| | | if err == nil || tryCount > attachTimes { |
| | | break loopB |
| | | } |
| | | time.Sleep(sleepPeriod) |
| | | data, id, err = AttachBlock(key) |
| | | tryCount++ |
| | | } |
| | | } |
| | | } |
| | | return data, id |
| | | } |
| | | |
| | | // CreateShmOnly create shm block with size, only space, no padding, return id(int) |
| | | // context for quit |
| | | func CreateShmOnly(ctx context.Context, size int, key int) int { |
| | | id, err := NewBlockOnly(size, key) |
| | | if err != nil { |
| | | loopB: |
| | | for { |
| | | select { |
| | | case <-ctx.Done(): |
| | | return -1 |
| | | default: |
| | | if err == nil { |
| | | break loopB |
| | | } |
| | | time.Sleep(sleepPeriod) |
| | | id, err = NewBlockOnly(size, key) |
| | | } |
| | | } |
| | | } |
| | | return id |
| | | } |
| | | |
| | | // CreateShmOnly create shm block with size, only space, no padding, return id(int) |
| | | // context for quit |
| | | func CreateShmOnlyTime(ctx context.Context, size int, key int, timeout int) int { |
| | | id, err := NewBlockOnly(size, key) |
| | | if err != nil { |
| | | to := time.NewTimer(time.Duration(timeout) * time.Millisecond) |
| | | defer to.Stop() |
| | | loopB: |
| | | for { |
| | | select { |
| | | case <-ctx.Done(): |
| | | return -1 |
| | | case <-to.C: |
| | | return -1 |
| | | default: |
| | | if err == nil { |
| | | break loopB |
| | | } |
| | | time.Sleep(sleepPeriod) |
| | | id, err = NewBlockOnly(size, key) |
| | | } |
| | | } |
| | | } |
| | | return id |
| | | } |
| | | |
| | | // CreatePaddingShm create padding shm block with size, return data-with-padding([]byte), id(int) |
| | |
| | | } else { |
| | | fmt.Println("createShm error:", err) |
| | | } |
| | | time.Sleep(time.Millisecond) |
| | | time.Sleep(sleepPeriod) |
| | | data, id, err = NewBlock(size, key) |
| | | } |
| | | } |
| | |
| | | |
| | | copy(data, padding) |
| | | return data, id |
| | | } |
| | | |
| | | // CheckShmExist check if shm is exist or not |
| | | // if exist, return id and true, else return 0 and false |
| | | func CheckShmExist(key int) (int, bool) { |
| | | id, err := shm.Get(key, 0, 0) |
| | | if err != nil || id == -1 { //no exist |
| | | fmt.Printf("AttachBlock Get:%x, %v\n", key, err) |
| | | return 0, false |
| | | } |
| | | |
| | | return id, true |
| | | } |
| | | |
| | | // DetachShm destroy |
| | |
| | | |
| | | // RemoveShmKey Remove shmkey |
| | | func RemoveShmKey(shmkey int) error { |
| | | _, id, err := AttachBlock(shmkey) |
| | | d, id, err := AttachBlock(shmkey) |
| | | if err != nil { |
| | | return err |
| | | } else { |
| | | Detach(d) |
| | | return shm.Rm(id) |
| | | } |
| | | } |
| | |
| | | if err != nil { |
| | | return err |
| | | } else { |
| | | Detach(d) |
| | | return Detach(d) |
| | | } |
| | | } |
| | |
| | | return shm.Rm(id) |
| | | } |
| | | } |
| | | |
| | | func ShmAttachNum(shmId int) (int,error) { |
| | | var idDs shm.IdDs |
| | | |
| | | _, err := shm.Ctl(shmId, shm.IPC_STAT, &idDs) |
| | | if err != nil { |
| | | return 0, err |
| | | } |
| | | |
| | | return int(idDs.Nattch), nil |
| | | } |
| | | |
| | | func GetKeyById(shmId int) (int,error) { |
| | | var idDs shm.IdDs |
| | | |
| | | _, err := shm.Ctl(shmId, shm.IPC_STAT, &idDs) |
| | | if err != nil { |
| | | return 0, err |
| | | } |
| | | |
| | | return int(idDs.Perm.Key), nil |
| | | } |