chenshijun
2020-06-04 47a19e070f57d92aadf52c62361da6ab5397bd4c
shmwrap.go
@@ -4,35 +4,49 @@
    "context"
    "fmt"
    "time"
    "github.com/gen2brain/shm"
    shm "basic.com/valib/goshm.git"
)
const sleepPeriod = time.Duration(5) * time.Millisecond
// NewBlock shm block with size
func NewBlock(size int, key int) ([]byte, int, error) {
    id, err := shm.Get(key, size, shm.IPC_CREAT|0666)
    fmt.Println("Get:", id, err)
    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)
    fmt.Println("Get:", id, err)
    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
    }
@@ -50,7 +64,6 @@
// context for quit
func CreateRawShm(ctx context.Context, size int, key int) ([]byte, int) {
    data, id, err := AttachBlock(key)
    fmt.Println("err:", err)
    if err != nil {
    loopB:
        for {
@@ -60,10 +73,8 @@
            default:
                if err == nil {
                    break loopB
                } else {
                    fmt.Println("createShm error:", err)
                }
                time.Sleep(time.Millisecond)
                time.Sleep(sleepPeriod)
                data, id, err = NewBlock(size, key)
            }
        }
@@ -83,15 +94,61 @@
            default:
                if err == nil {
                    break loopB
                } else {
                    fmt.Println("createShm error:", err)
                }
                time.Sleep(time.Millisecond)
                time.Sleep(sleepPeriod)
                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(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)
@@ -110,7 +167,7 @@
                } else {
                    fmt.Println("createShm error:", err)
                }
                time.Sleep(time.Millisecond)
                time.Sleep(sleepPeriod)
                data, id, err = NewBlock(size, key)
            }
        }
@@ -118,6 +175,18 @@
    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
@@ -139,3 +208,58 @@
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
}