]> 127.0.0.1 Git - part/.git/commitdiff
1 (#18) v0.28.20250127053704
authorqydysky <qydysky@foxmail.com>
Mon, 27 Jan 2025 05:36:55 +0000 (13:36 +0800)
committerGitHub <noreply@github.com>
Mon, 27 Jan 2025 05:36:55 +0000 (13:36 +0800)
ctx/Ctx.go
ctx/Ctx_test.go

index 62c056c40b2ecf432262900017cd6ae0ffc282ad..361c44c3f88bd96cbf600201870e46c335075d52 100644 (file)
@@ -13,6 +13,7 @@ var (
        ptr            = &struct{}{}
        ErrWaitTo      = errors.New("ErrWaitTo")
        ErrNothingWait = errors.New("ErrNothingWait")
+       ErrDoneCalled  = errors.New("ErrDoneCalled")
 )
 
 type Ctx struct {
@@ -44,7 +45,13 @@ func WithWait(sctx context.Context, planNum int32, to ...time.Duration) (dctx co
 
        var doneWait context.CancelFunc
        dctx, doneWait = context.WithCancel(ctx.Ctx)
+
+       var oncef atomic.Bool
        done = func() error {
+               if !oncef.CompareAndSwap(false, true) {
+                       return ErrDoneCalled
+               }
+
                doneWait()
                if ctxp, ok := sctx.Value(ptr).(*Ctx); ok {
                        defer func() {
index f75a775cb2ca38e39882106857b90fa1507c8ce8..f15c07f46dcac48d812fcec761937b396aee74c9 100644 (file)
@@ -30,6 +30,31 @@ func TestMain(t *testing.T) {
 }
 
 func TestMain5(t *testing.T) {
+       ctx1, done := WithWait(context.Background(), 1)
+       t0 := time.Now()
+       go func() {
+               ctx2, done1 := WaitCtx(ctx1)
+               defer done1()
+               <-ctx2.Done()
+               if time.Since(t0) < time.Millisecond*100 {
+                       t.Fail()
+               }
+               time.Sleep(time.Second)
+       }()
+       time.Sleep(time.Second)
+       t1 := time.Now()
+       if done() != nil {
+               t.Fatal()
+       }
+       if time.Since(t1) < time.Second {
+               t.Fail()
+       }
+       if !errors.Is(done(), ErrDoneCalled) {
+               t.Fatal()
+       }
+}
+
+func TestMain7(t *testing.T) {
        ctx1, done := WithWait(context.Background(), 1, time.Second*2)
        go func() {
                ctx2, done1 := WaitCtx(ctx1)