Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling *time.Ticker's Stop() blocks #72034

Closed
santhalakshminarayana opened this issue Feb 28, 2025 · 1 comment
Closed

Calling *time.Ticker's Stop() blocks #72034

santhalakshminarayana opened this issue Feb 28, 2025 · 1 comment

Comments

@santhalakshminarayana
Copy link

When time.NewTicker() is dereferenced and after some time Stop() is called on this ticker, it results in blocking sometimes.

In this code, when ran with single core, the programs halts at the t.ticker.Stop() statement.

type TT struct {
	ctx    context.Context
	ticker time.Ticker
}

func main() {
	runtime.GOMAXPROCS(1)
	wg := new(sync.WaitGroup)
	ctx, canceFunc := context.WithTimeout(context.Background(), 3*time.Second)
	defer canceFunc()
	tt := TT{
		ticker: *time.NewTicker(2 * time.Second),
		ctx:    ctx,
	}
	wg.Add(1)
	go tt.runTicker(wg)
	wg.Wait()
}

func (t *TT) runTicker(wg *sync.WaitGroup) {
	defer func() {
		fmt.Println("cleaning runTicker")
		wg.Done()
	}()

	for {
		select {
		case <-t.ctx.Done():
			fmt.Println("returning runTicker")
			t.ticker.Stop()
			return
		case <-t.ticker.C:
			fmt.Println("ticked")
		}
	}
}

Output:

ticked
returning runTicker
// Blocked and didn't print "cleaning runTicker"
^Csignal: interrupt // Signalled Exit

and if ran without GOMAXPROCS limitation, the following runtime panic seen

ticked
returning runTicker
fatal error: bad ts

runtime stack:
runtime.throw({0x4c3921?, 0x0?})
        /home/lnr/go/src/runtime/panic.go:1067 +0x48 fp=0x7ffe72378098 sp=0x7ffe72378068 pc=0x4670a8
runtime.(*timers).run(0xc00003e790, 0x1b8d4c673fab)
        /home/lnr/go/src/runtime/time.go:970 +0x116 fp=0x7ffe723780c0 sp=0x7ffe72378098 pc=0x452876
runtime.(*timers).check(0xc00003e790, 0x0?)
        /home/lnr/go/src/runtime/time.go:928 +0x13d fp=0x7ffe72378108 sp=0x7ffe723780c0 pc=0x45267d
runtime.stealWork(0xc00003a008?)
        /home/lnr/go/src/runtime/proc.go:3687 +0x1f3 fp=0x7ffe72378178 sp=0x7ffe72378108 pc=0x43bfb3
runtime.findRunnable()
        /home/lnr/go/src/runtime/proc.go:3364 +0x405 fp=0x7ffe723782f0 sp=0x7ffe72378178 pc=0x43b005
runtime.schedule()
        /home/lnr/go/src/runtime/proc.go:3995 +0xb1 fp=0x7ffe72378328 sp=0x7ffe723782f0 pc=0x43ca31
runtime.park_m(0xc000104540)
        /home/lnr/go/src/runtime/proc.go:4102 +0x1eb fp=0x7ffe72378380 sp=0x7ffe72378328 pc=0x43ce4b
runtime.mcall()
        /home/lnr/go/src/runtime/asm_amd64.s:459 +0x4e fp=0x7ffe72378398 sp=0x7ffe72378380 pc=0x46be8e

goroutine 1 gp=0xc0000061c0 m=nil [semacquire]:
runtime.gopark(0x68?, 0x40?, 0x0?, 0x0?, 0xc000124e98?)
        /home/lnr/go/src/runtime/proc.go:424 +0xce fp=0xc000124e30 sp=0xc000124e10 pc=0x46718e
runtime.goparkunlock(...)
        /home/lnr/go/src/runtime/proc.go:430
runtime.semacquire1(0xc00011a048, 0x0, 0x1, 0x0, 0x12)
        /home/lnr/go/src/runtime/sema.go:178 +0x225 fp=0xc000124e98 sp=0xc000124e30 pc=0x448065
sync.runtime_Semacquire(0xc000136018?)
        /home/lnr/go/src/runtime/sema.go:71 +0x25 fp=0xc000124ed0 sp=0xc000124e98 pc=0x467fc5
sync.(*WaitGroup).Wait(0x77359400?)
        /home/lnr/go/src/sync/waitgroup.go:118 +0x48 fp=0xc000124ef8 sp=0xc000124ed0 pc=0x4740e8
main.main()
        /home/lnr/Downloads/ruf/go_play/main.go:26 +0x131 fp=0xc000124f50 sp=0xc000124ef8 pc=0x4a04b1
runtime.main()
        /home/lnr/go/src/runtime/proc.go:272 +0x28b fp=0xc000124fe0 sp=0xc000124f50 pc=0x43526b
runtime.goexit({})
        /home/lnr/go/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc000124fe8 sp=0xc000124fe0 pc=0x46dd41

goroutine 2 gp=0xc000006700 m=nil [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /home/lnr/go/src/runtime/proc.go:424 +0xce fp=0xc00005afa8 sp=0xc00005af88 pc=0x46718e
runtime.goparkunlock(...)
        /home/lnr/go/src/runtime/proc.go:430
runtime.forcegchelper()
        /home/lnr/go/src/runtime/proc.go:337 +0xb3 fp=0xc00005afe0 sp=0xc00005afa8 pc=0x4355b3
runtime.goexit({})
        /home/lnr/go/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc00005afe8 sp=0xc00005afe0 pc=0x46dd41
created by runtime.init.7 in goroutine 1
        /home/lnr/go/src/runtime/proc.go:325 +0x1a

goroutine 3 gp=0xc000006c40 m=nil [GC sweep wait]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /home/lnr/go/src/runtime/proc.go:424 +0xce fp=0xc00005b780 sp=0xc00005b760 pc=0x46718e
runtime.goparkunlock(...)
        /home/lnr/go/src/runtime/proc.go:430
runtime.bgsweep(0xc00007c000)
        /home/lnr/go/src/runtime/mgcsweep.go:277 +0x94 fp=0xc00005b7c8 sp=0xc00005b780 pc=0x420f34
runtime.gcenable.gowrap1()
        /home/lnr/go/src/runtime/mgc.go:204 +0x25 fp=0xc00005b7e0 sp=0xc00005b7c8 pc=0x4158a5
runtime.goexit({})
        /home/lnr/go/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc00005b7e8 sp=0xc00005b7e0 pc=0x46dd41
created by runtime.gcenable in goroutine 1
        /home/lnr/go/src/runtime/mgc.go:204 +0x66

goroutine 4 gp=0xc000006e00 m=nil [GC scavenge wait]:
runtime.gopark(0xc00007c000?, 0x4e9528?, 0x1?, 0x0?, 0xc000006e00?)
        /home/lnr/go/src/runtime/proc.go:424 +0xce fp=0xc00005bf78 sp=0xc00005bf58 pc=0x46718e
runtime.goparkunlock(...)
        /home/lnr/go/src/runtime/proc.go:430
runtime.(*scavengerState).park(0x572fe0)
        /home/lnr/go/src/runtime/mgcscavenge.go:425 +0x49 fp=0xc00005bfa8 sp=0xc00005bf78 pc=0x41e969
runtime.bgscavenge(0xc00007c000)
        /home/lnr/go/src/runtime/mgcscavenge.go:653 +0x3c fp=0xc00005bfc8 sp=0xc00005bfa8 pc=0x41eedc
runtime.gcenable.gowrap2()
        /home/lnr/go/src/runtime/mgc.go:205 +0x25 fp=0xc00005bfe0 sp=0xc00005bfc8 pc=0x415845
runtime.goexit({})
        /home/lnr/go/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc00005bfe8 sp=0xc00005bfe0 pc=0x46dd41
created by runtime.gcenable in goroutine 1
        /home/lnr/go/src/runtime/mgc.go:205 +0xa5

goroutine 17 gp=0xc000104380 m=nil [finalizer wait]:
runtime.gopark(0x490013?, 0xc00005a660?, 0x5e?, 0xc6?, 0x75b642682c28?)
        /home/lnr/go/src/runtime/proc.go:424 +0xce fp=0xc00005a620 sp=0xc00005a600 pc=0x46718e
runtime.runfinq()
        /home/lnr/go/src/runtime/mfinal.go:193 +0x107 fp=0xc00005a7e0 sp=0xc00005a620 pc=0x414927
runtime.goexit({})
        /home/lnr/go/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc00005a7e8 sp=0xc00005a7e0 pc=0x46dd41
created by runtime.createfing in goroutine 1
        /home/lnr/go/src/runtime/mfinal.go:163 +0x3d

goroutine 18 gp=0xc000104540 m=4 mp=0xc000060e08 [running]:
        goroutine running on other thread; stack unavailable
created by main.main in goroutine 1
        /home/lnr/Downloads/ruf/go_play/main.go:25 +0x127
exit status 2

Note: This only happens sometime but mostly and works fine without dereferencing

@seankhliao
Copy link
Member

see #69186

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Feb 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants