From 82a262ef5cf721e5a236c8b1d2ab3ff92ca33122 Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期五, 24 九月 2021 11:40:20 +0800
Subject: [PATCH] bug fixed withintime

---
 shmwrap.go |  132 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 127 insertions(+), 5 deletions(-)

diff --git a/shmwrap.go b/shmwrap.go
index 2f48b70..7697cb7 100644
--- a/shmwrap.go
+++ b/shmwrap.go
@@ -4,7 +4,12 @@
     "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
@@ -22,6 +27,16 @@
     }
 
     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
@@ -62,7 +77,7 @@
                 if err == nil {
                     break loopB
                 }
-                time.Sleep(time.Millisecond)
+                time.Sleep(sleepPeriod)
                 data, id, err = NewBlock(size, key)
             }
         }
@@ -83,12 +98,83 @@
                 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)
@@ -107,7 +193,7 @@
                 } else {
                     fmt.Println("createShm error:", err)
                 }
-                time.Sleep(time.Millisecond)
+                time.Sleep(sleepPeriod)
                 data, id, err = NewBlock(size, key)
             }
         }
@@ -115,6 +201,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,10 +237,11 @@
 
 // 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)
     }
 }
@@ -153,6 +252,7 @@
     if err != nil {
         return err
     } else {
+        Detach(d)
         return Detach(d)
     }
 }
@@ -167,3 +267,25 @@
         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
+}
\ No newline at end of file

--
Gitblit v1.8.0