Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does LuaJIT produce a "too many callbacks error" from this simple code?

I'm using LuaJIT and running into a "too many callbacks" exception with this code. I know there is a limit to the number of c callbacks that can be generated, but as far as I know, this should just generate one callback... right?

ffi = require('ffi')
ffi.cdef([[typedef double cpFloat;
typedef struct cpSpace cpSpace;
typedef struct cpBody cpBody;

cpSpace* cpSpaceNew(void);
cpBody* cpBodyNew(cpFloat mass, cpFloat moment);
cpBody* cpSpaceAddBody(cpSpace *space, cpBody *body);

typedef void (*cpSpaceBodyIteratorFunc)(cpBody *body, void *data);
void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIteratorFunc func, void *data);

]])

chipmunk = ffi.load("chipmunk")
space = chipmunk.cpSpaceNew()
body = chipmunk.cpBodyNew(10, 100)
chipmunk.cpSpaceAddBody(space, body)

drawBody = function(body, x) end
CALL_COUNT = 5000
for i = 1, CALL_COUNT do
  chipmunk.cpSpaceEachBody(space, drawBody, nil)
end

If CALL_COUNT is reduced to 500, it works without error.

Exception is as follows:

Error: main.lua:25: too many callbacks
stack traceback:
    [C]: in function 'cpSpaceEachBody'
    mainmoon.lua:25: in main chunk
    [C]: in function 'require'
    main.lua:1: in main chunk
    [C]: in function 'require'
    [string "boot.lua"]:374: in function <[string "boot.lua"]:244>
    [C]: in function 'xpcall'

Context: I'm integrating Chipmunk with the Love2D platform on Mac OS X.

like image 457
Bob Terrapin Avatar asked May 16 '26 20:05

Bob Terrapin


1 Answers

In LuaJIT, C callbacks are a finite resource. See http://luajit.org/ext_ffi_semantics.html#callback

Your function cpSpaceEachBody takes a function as a second parameter. Every time you call it; you are creating a new C function.

In addition to creating too many of them; you never free them.

You should use as few C functions as possible. In your example you're using the same function every time, so this is a simple fix:

ffi = require('ffi')
ffi.cdef([[typedef double cpFloat;
typedef struct cpSpace cpSpace;
typedef struct cpBody cpBody;

cpSpace* cpSpaceNew(void);
cpBody* cpBodyNew(cpFloat mass, cpFloat moment);
cpBody* cpSpaceAddBody(cpSpace *space, cpBody *body);

typedef void (*cpSpaceBodyIteratorFunc)(cpBody *body, void *data);
void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIteratorFunc func, void *data);

]])

chipmunk = ffi.load("chipmunk")
space = chipmunk.cpSpaceNew()
body = chipmunk.cpBodyNew(10, 100)
chipmunk.cpSpaceAddBody(space, body)

drawBody = function(body, x) end
drawBody_C_func = ffi.cast("cpSpaceBodyIteratorFunc", drawBody)
CALL_COUNT = 5000
for i = 1, CALL_COUNT do
  chipmunk.cpSpaceEachBody(space, drawBody_C_func, nil)
end
drawBody_C_func:free()
like image 104
daurnimator Avatar answered May 19 '26 02:05

daurnimator



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!