ebitengine/purego

the maximum number of callbacks has been reached

Closed this issue · 5 comments

PureGo Version

0.7.1

Operating System

  • Windows
  • macOS
  • Linux
  • FreeBSD
  • Android
  • iOS

Go Version (go version)

go1.23

What steps will reproduce the problem?

panic

panic

panic: purego: the maximum number of callbacks has been reached

goroutine 4 [running]:
github.com/ebitengine/purego.compileCallback({0x135b980, 0xc00098d620})
        /usr/local/go/work/pkg/mod/github.com/ebitengine/purego@v0.7.1/syscall_sysv.go:104 +0x429
github.com/ebitengine/purego.NewCallback({0x135b980, 0xc00098d620})
        /usr/local/go/work/pkg/mod/github.com/ebitengine/purego@v0.7.1/syscall_sysv.go:41 +0x26
github.com/ebitengine/purego.RegisterFunc.func1({0xc0009099e0, 0x4, 0x4})
        /usr/local/go/work/pkg/mod/github.com/ebitengine/purego@v0.7.1/func.go:275 +0xcdc
rock/agent/internal/lmdb.(*LMdb).Foreach(0xc0004380a0, {0x146431c, 0x12}, 0xc00098d5f0)
        /vdb/dev/agent/internal/lmdb/lmdb.go:159 +0x192
rock/agent/collect/ban.(*Ban).Collect(0xc0002b8990)
        /vdb/dev/agent/collect/ban/ban.go:47 +0x1f6
rock/agent/collect/ban.(*Ban).Start(0xc0002b8990)
        /vdb/dev/agent/collect/ban/ban.go:71 +0x1de
rock/agent/pkg.Start({0x152f320, 0xc0002b8990})
        /vdb/dev/agent/pkg/exit.go:19 +0x3f
rock/agent/pkg.Spawn.func1()
        /vdb/dev/agent/pkg/exit.go:11 +0x25
created by rock/agent/pkg.Spawn in goroutine 1
        /vdb/dev/agent/pkg/exit.go:11 +0x76

code

The following logic will keep reading and writing operations in a loop event

       var err error
	expect := func(ptr uintptr, sz uint) {
		inf := clone(ptr, sz)
		err = errors.New(inf)
	}

	var flag int
	nextCb := func(ptr uintptr, idx uint) int {
		if idx >= sz {
			return -1
		}

		k, v, stop := next(idx)
		if stop {
			return -1
		}

		k_sz := uint(len(k))
		v_sz := uint(len(v))
		rc := db.lib.updateNext(ptr, k, k_sz, v, v_sz, 0)
		if rc != 0 {
			return -1
		}
		return 0
	}

	rc := db.lib.updateAll(db.env, dbname, sz, nextCb, expect)

What is the expected result?

no panic

What happens instead?

Program execution failed.

Anything else you feel useful to add?

This isn't a bug. There are only so many callbacks that can be created. You should rewrite the code so that it doesn't keep creating new callbacks. Just make them once and then pass them in as uintptr

ths..
Please provide a case.

Let me close this as this is not an issue.

Is this limitation due to high resource consumption or the possibility of causing memory overflow? Can it be removed?
Can it be made elastic and destroyed after use?

The limitation is that callbacks are never deallocated. Even if we allowed for them to grow it would constantly increase memory usage. The official windows syscall package has the same limitation so even if purego removed the constraint on macOS/Linux it would no longer have the same behavior as Windows