From e06a1ded4858392dd233d53a5fd5ce29442baec4 Mon Sep 17 00:00:00 2001 From: qydysky Date: Thu, 2 Nov 2023 02:33:28 +0800 Subject: [PATCH] 1 --- ctx/Ctx.go | 75 ++++++++++---------------------------- ctx/Ctx_test.go | 97 +++++++++++++------------------------------------ 2 files changed, 45 insertions(+), 127 deletions(-) diff --git a/ctx/Ctx.go b/ctx/Ctx.go index f77087f..80e19cd 100644 --- a/ctx/Ctx.go +++ b/ctx/Ctx.go @@ -20,19 +20,17 @@ type Ctx struct { r32 *atomic.Int32 } -/* -planNum 可以为0 表示无法预知的调用次数,如果在done调用前没有Wait、WithWait时,done将返回ErrNothingWait - -ctx,done := WithWait(ctx, time.Second) - -defer done()// wait done1 or after one second - - go func(){// may be run - done1 := Wait(ctx) - defer done1() - do something.. - }() -*/ +// planNum 可以为0 表示无法预知的调用次数,如果在mainDone调用前没有Wait、WithWait时,mainDone将返回ErrNothingWait +// +// mainCtx, mainDone := WithWait(ctx, 0, time.Second) +// defer mainDone()// wait done1 or after one second +// +// go func(){ +// ctx1, done1 := WaitCtx(mainCtx) +// defer done1() +// do something.. +// <-ctx1.Done() // wait mainDone call +// }() func WithWait(sctx context.Context, planNum int32, to ...time.Duration) (dctx context.Context, done func() error) { if ctxp, ok := sctx.Value(ptr).(*Ctx); ok { ctxp.r32.Add(1) @@ -43,8 +41,10 @@ func WithWait(sctx context.Context, planNum int32, to ...time.Duration) (dctx co ctx.Ctx = context.WithValue(sctx, ptr, ctx) ctx.w32.Add(planNum) - dctx = ctx.Ctx + var doneWait context.CancelFunc + dctx, doneWait = context.WithCancel(ctx.Ctx) done = func() error { + doneWait() if ctxp, ok := sctx.Value(ptr).(*Ctx); ok { defer func() { ctxp.r32.Add(-1) @@ -74,38 +74,12 @@ func WithWait(sctx context.Context, planNum int32, to ...time.Duration) (dctx co return } -/* - func(ctx context.Context){ - done := Wait(ctx) - defer done() - do something.. - } -*/ -func Wait(ctx context.Context) (done func()) { - if ctxp, ok := ctx.Value(ptr).(*Ctx); ok { - ctxp.r32.Add(1) - ctxp.w32.Add(-1) - } - return func() { - if ctxp, ok := ctx.Value(ptr).(*Ctx); ok { - ctxp.r32.Add(-1) - } - } -} - -/* - func(ctx context.Context){ - ctx, done := WaitCtx(ctx) - defer done() - - do something.. - select { - case <-ctx: - defualt: - } - do something.. - } -*/ +// go func(){ +// ctx1, done1 := WaitCtx(mainCtx) +// defer done1() +// do something.. +// <-ctx1.Done() // wait mainDone call +// }() func WaitCtx(ctx context.Context) (dctx context.Context, done func()) { if ctxp, ok := ctx.Value(ptr).(*Ctx); ok { ctxp.r32.Add(1) @@ -117,12 +91,3 @@ func WaitCtx(ctx context.Context) (dctx context.Context, done func()) { } } } - -func Done(ctx context.Context) bool { - select { - case <-ctx.Done(): - return true - default: - } - return false -} diff --git a/ctx/Ctx_test.go b/ctx/Ctx_test.go index 87e054b..2d255aa 100644 --- a/ctx/Ctx_test.go +++ b/ctx/Ctx_test.go @@ -8,98 +8,51 @@ import ( ) func TestMain(t *testing.T) { - ctx, _ := context.WithTimeout(context.Background(), time.Second) - ctx1, done := WithWait(ctx, 1, time.Second) + ctx1, done := WithWait(context.Background(), 1, time.Second) + t0 := time.Now() go func() { - done := Wait(ctx1) - defer done() + ctx2, done1 := WaitCtx(ctx1) + defer done1() + <-ctx2.Done() + if time.Since(t0) < time.Millisecond*100 { + t.Fail() + } }() + time.Sleep(time.Second) if done() != nil { t.Fatal() } } func TestMain1(t *testing.T) { - ctx, _ := context.WithTimeout(context.Background(), time.Second) - ctx1, done := WithWait(ctx, 0, time.Second) - go func() { - done := Wait(ctx1) - defer done() - time.Sleep(100 * time.Millisecond) - }() - if e := done(); !errors.Is(e, ErrNothingWait) { - t.Fatal(e) - } -} - -func TestMain2(t *testing.T) { - ctx, _ := context.WithTimeout(context.Background(), time.Second*2) - ctx1, done := WithWait(ctx, 1, time.Second) - go func() { - done := Wait(ctx1) - time.Sleep(time.Second * 2) - defer done() - }() - if e := done(); !errors.Is(e, ErrWaitTo) { - t.Fatal(e) - } -} - -func TestMain3(t *testing.T) { - ctx, _ := context.WithTimeout(context.Background(), time.Second*2) - ctx1, done := WithWait(ctx, 1, time.Second) + ctx1, done := WithWait(context.Background(), 1, time.Second) + t0 := time.Now() go func() { - ctx2, done := WithWait(ctx1, 1, time.Second) - go func() { - done := Wait(ctx2) - defer done() - }() - if done() != nil { + ctx2, _ := WaitCtx(ctx1) + <-ctx2.Done() + if time.Since(t0) < time.Millisecond*100 { t.Fail() } }() time.Sleep(time.Second) - if done() != nil { + if !errors.Is(done(), ErrWaitTo) { t.Fatal() } } -func TestMain4(t *testing.T) { - ctx, _ := context.WithTimeout(context.Background(), time.Second*2) - ctx1, done := WithWait(ctx, 1, time.Second) +func TestMain2(t *testing.T) { + ctx1, done := WithWait(context.Background(), 0, time.Second) + t0 := time.Now() go func() { - ctx2, done := WithWait(ctx1, 1, time.Second) - go func() { - done := Wait(ctx2) - time.Sleep(time.Second * 2) - defer done() - }() - if e := done(); !errors.Is(e, ErrWaitTo) { + time.Sleep(time.Second) + ctx2, done := WaitCtx(ctx1) + defer done() + <-ctx2.Done() + if time.Since(t0) < time.Millisecond*100 { t.Fail() } }() - if e := done(); !errors.Is(e, ErrWaitTo) { - t.Fatal(e) - } -} - -func TestMain5(t *testing.T) { - ctx, can := context.WithTimeout(context.Background(), time.Millisecond*500) - defer can() - - ctx, done := WithWait(ctx, 1) - - var gr = func(ctx context.Context, to time.Duration) { - done := Wait(ctx) - defer done() - time.Sleep(to) + if !errors.Is(done(), ErrNothingWait) { + t.Fatal() } - - bg := time.Now() - - go gr(ctx, 0) - // go gr(ctx, time.Second) - // go gr(ctx, time.Second*5) - - t.Log(done(), time.Since(bg)) } -- 2.39.2