20 /* Index for coroutine is fd as integer for *nix, as lightuserdata for Win */ |
20 /* Index for coroutine is fd as integer for *nix, as lightuserdata for Win */ |
21 void luaevent_callback(int fd, short event, void* p) { |
21 void luaevent_callback(int fd, short event, void* p) { |
22 le_callback* cb = p; |
22 le_callback* cb = p; |
23 lua_State* L; |
23 lua_State* L; |
24 int ret; |
24 int ret; |
25 double newTimeout = -1; |
25 struct timeval new_tv = { 0, 0 }; |
26 assert(cb); |
26 assert(cb); |
27 if(!cb->base) |
27 if(!cb->base) |
28 return; /* Event has already been collected + destroyed */ |
28 return; /* Event has already been collected + destroyed */ |
29 assert(cb->base->loop_L); |
29 assert(cb->base->loop_L); |
30 L = cb->base->loop_L; |
30 L = cb->base->loop_L; |
32 lua_pushinteger(L, event); |
32 lua_pushinteger(L, event); |
33 lua_call(L, 1, 2); |
33 lua_call(L, 1, 2); |
34 if(!cb->base) |
34 if(!cb->base) |
35 return; /* event was destroyed during callback */ |
35 return; /* event was destroyed during callback */ |
36 ret = lua_tointeger(L, -2); |
36 ret = lua_tointeger(L, -2); |
37 if(lua_isnumber(L, -1)) { |
37 if(lua_isnumber(L, -1)) |
38 newTimeout = lua_tonumber(L, -1); |
38 { |
39 if(newTimeout <= 0) { |
39 double newTimeout = lua_tonumber(L, -1); |
40 memset(&cb->timeout, 0, sizeof(cb->timeout)); |
40 if(newTimeout>0) |
41 } else { |
41 load_timeval(newTimeout, &new_tv); |
42 load_timeval(newTimeout, &cb->timeout); |
|
43 } |
|
44 } |
42 } |
45 lua_pop(L, 2); |
43 lua_pop(L, 2); |
46 if(ret == -1) { |
44 if(ret == -1) { |
47 freeCallbackArgs(cb, L); |
45 freeCallbackArgs(cb, L); |
48 } else { |
46 } else { |
49 struct event *ev = &cb->ev; |
47 struct event *ev = &cb->ev; |
50 int newEvent = ret; |
48 int newEvent = ret; |
51 /* NOTE: Currently, even if new timeout is the same as the old, a new event is setup regardless... */ |
49 if( newEvent != event || (cb->timeout.tv_sec != new_tv.tv_sec || cb->timeout.tv_usec != new_tv.tv_usec) ) |
52 if(newEvent != event || newTimeout != -1) { // Need to hook up new event... |
50 { |
53 struct timeval *ptv = &cb->timeout; |
51 struct timeval *ptv = &cb->timeout; |
|
52 cb->timeout = new_tv; |
54 if(!cb->timeout.tv_sec && !cb->timeout.tv_usec) |
53 if(!cb->timeout.tv_sec && !cb->timeout.tv_usec) |
55 ptv = NULL; |
54 ptv = NULL; |
56 event_del(ev); |
55 event_del(ev); |
57 event_set(ev, fd, EV_PERSIST | newEvent, luaevent_callback, cb); |
56 event_set(ev, fd, EV_PERSIST | newEvent, luaevent_callback, cb); |
58 /* Assume cannot set a new timeout.. */ |
57 /* Assume cannot set a new timeout.. */ |