package shmqueue import ( "context" "fmt" "time" "github.com/gen2brain/shm" ) // NewBlock shm block with size func NewBlock(size int, key int) ([]byte, 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 nil, -1, err } data, err2 := shm.At(id, 0, 0) if err2 != nil { fmt.Printf("NewBlock At:%x, %v\n", key, err2) return nil, -1, err2 } 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 func AttachBlock(key int) ([]byte, int, error) { id, err := shm.Get(key, 0, 0) if err != nil || id == -1 { //no exist fmt.Printf("AttachBlock Get:%x, %v\n", key, err) return nil, -1, err } data, err2 := shm.At(id, 0, 0) if err2 != nil { fmt.Printf("AttachBlock Get:%x, %v\n", key, err2) return nil, -1, err2 } return data, id, nil } // ReleaseBlock release shm block func ReleaseBlock(data []byte) { if data != nil { shm.Dt(data) } } // CreateRawShm create raw shm block with size, only space, no padding, return data([]byte), id(int) // context for quit func CreateRawShm(ctx context.Context, size int, key int) ([]byte, int) { data, id, err := AttachBlock(key) if err != nil { loopB: for { select { case <-ctx.Done(): return nil, -1 default: if err == nil { break loopB } time.Sleep(time.Millisecond) data, id, err = NewBlock(size, key) } } } return data, id } //AttachRawShm don't create func AttachRawShm(ctx context.Context, key int) ([]byte, int) { data, id, err := AttachBlock(key) if err != nil { loopB: for { select { case <-ctx.Done(): return nil, -1 default: if err == nil { break loopB } time.Sleep(time.Millisecond) data, id, err = AttachBlock(key) } } } 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(time.Millisecond) id, err = NewBlockOnly(size, key) } } } return id } // CreatePaddingShm create padding shm block with size, return data-with-padding([]byte), id(int) // context for quit, padding for fill raw shm block func CreatePaddingShm(ctx context.Context, size int, key int, padding []byte) ([]byte, int) { data, id, err := NewBlock(size, key) if err != nil { loopB: for { select { case <-ctx.Done(): return nil, -1 default: if err == nil { break loopB } else { fmt.Println("createShm error:", err) } time.Sleep(time.Millisecond) 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 func DetachShm(data []byte) { ReleaseBlock(data) } // Attach attach shmid get block func Attach(id int) ([]byte, error) { return shm.At(id, 0, 0) } // Detach detach shm block func Detach(d []byte) error { return shm.Dt(d) } // RemoveShmID Remove shmid func RemoveShmID(id int) error { return shm.Rm(id) } // RemoveShmKey Remove shmkey func RemoveShmKey(shmkey int) error { d, id, err := AttachBlock(shmkey) if err != nil { return err } else { Detach(d) return shm.Rm(id) } } // DetachShmKey detach shmkey func DetachShmKey(shmkey int) error { d, _, err := AttachBlock(shmkey) if err != nil { return err } else { Detach(d) return Detach(d) } } // DetachAndRemoveShmKey detach and Remove shmkey func DetachAndRemoveShmKey(shmkey int) error { d, id, err := AttachBlock(shmkey) if err != nil { return err } else { 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 }