src/event_callback.c

Fri, 27 Nov 2009 01:33:55 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Fri, 27 Nov 2009 01:33:55 +0000
changeset 65
e65466cee871
parent 25
5778073d2903
child 108
f123677dd748
permissions
-rw-r--r--

event_callback: Fix stack slot leak

21
728aafac9682 Added missing license header
Thomas Harning Jr <harningt@gmail.com>
parents: 20
diff changeset
1 /* LuaEvent - Copyright (C) 2007 Thomas Harning <harningt@gmail.com>
728aafac9682 Added missing license header
Thomas Harning Jr <harningt@gmail.com>
parents: 20
diff changeset
2 * Licensed as LGPL - See doc/COPYING for details */
20
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
3 #include "event_callback.h"
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
4 #include <assert.h>
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
5 #include <lauxlib.h>
24
cda8e1a2dfa2 Fixed compilation issues
Thomas Harning Jr <harningt@gmail.com>
parents: 23
diff changeset
6 #include <string.h>
20
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
7
22
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
8 #define EVENT_CALLBACK_ARG_MT "EVENT_CALLBACK_ARG_MT"
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
9
20
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
10 void freeCallbackArgs(le_callback* arg, lua_State* L) {
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
11 if(arg->base) {
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
12 arg->base = NULL;
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
13 event_del(&arg->ev);
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
14 luaL_unref(L, LUA_REGISTRYINDEX, arg->callbackRef);
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
15 }
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
16 }
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
17 /* le_callback is allocated at the beginning of the coroutine in which it
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
18 is used, no need to manually de-allocate */
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
19
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
20 /* Index for coroutine is fd as integer for *nix, as lightuserdata for Win */
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
21 void luaevent_callback(int fd, short event, void* p) {
23
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
22 le_callback* cb = p;
20
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
23 lua_State* L;
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
24 int ret;
23
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
25 double newTimeout = -1;
25
5778073d2903 Added timertest. Prevented GC-ed events from causing an abort.
Thomas Harning Jr <harningt@gmail.com>
parents: 24
diff changeset
26 assert(cb);
5778073d2903 Added timertest. Prevented GC-ed events from causing an abort.
Thomas Harning Jr <harningt@gmail.com>
parents: 24
diff changeset
27 if(!cb->base) {
5778073d2903 Added timertest. Prevented GC-ed events from causing an abort.
Thomas Harning Jr <harningt@gmail.com>
parents: 24
diff changeset
28 /* Callback has been collected... die */
5778073d2903 Added timertest. Prevented GC-ed events from causing an abort.
Thomas Harning Jr <harningt@gmail.com>
parents: 24
diff changeset
29 /* TODO: What should really be done here... */
5778073d2903 Added timertest. Prevented GC-ed events from causing an abort.
Thomas Harning Jr <harningt@gmail.com>
parents: 24
diff changeset
30 return;
5778073d2903 Added timertest. Prevented GC-ed events from causing an abort.
Thomas Harning Jr <harningt@gmail.com>
parents: 24
diff changeset
31 }
5778073d2903 Added timertest. Prevented GC-ed events from causing an abort.
Thomas Harning Jr <harningt@gmail.com>
parents: 24
diff changeset
32 assert(cb->base->loop_L);
23
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
33 L = cb->base->loop_L;
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
34 lua_rawgeti(L, LUA_REGISTRYINDEX, cb->callbackRef);
20
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
35 lua_pushinteger(L, event);
23
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
36 lua_call(L, 1, 2);
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
37 ret = lua_tointeger(L, -2);
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
38 if(lua_isnumber(L, -1)) {
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
39 newTimeout = lua_tonumber(L, -1);
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
40 if(newTimeout <= 0) {
24
cda8e1a2dfa2 Fixed compilation issues
Thomas Harning Jr <harningt@gmail.com>
parents: 23
diff changeset
41 memset(&cb->timeout, 0, sizeof(cb->timeout));
23
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
42 } else {
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
43 load_timeval(newTimeout, &cb->timeout);
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
44 }
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
45 }
65
e65466cee871 event_callback: Fix stack slot leak
Matthew Wild <mwild1@gmail.com>
parents: 25
diff changeset
46 lua_pop(L, 2);
20
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
47 if(ret == -1) {
23
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
48 freeCallbackArgs(cb, L);
20
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
49 } else {
23
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
50 struct event *ev = &cb->ev;
20
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
51 int newEvent = ret;
23
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
52 /* NOTE: Currently, even if new timeout is the same as the old, a new event is setup regardless... */
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
53 if(newEvent != event || newTimeout != -1) { // Need to hook up new event...
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
54 struct timeval *ptv = &cb->timeout;
24
cda8e1a2dfa2 Fixed compilation issues
Thomas Harning Jr <harningt@gmail.com>
parents: 23
diff changeset
55 if(!cb->timeout.tv_sec && !cb->timeout.tv_usec)
23
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
56 ptv = NULL;
20
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
57 event_del(ev);
23
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
58 event_set(ev, fd, EV_PERSIST | newEvent, luaevent_callback, cb);
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
59 /* Assume cannot set a new timeout.. */
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
60 event_add(ev, ptv);
20
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
61 }
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
62 }
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
63 }
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
64
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
65 static int luaevent_cb_gc(lua_State* L) {
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
66 le_callback* arg = luaL_checkudata(L, 1, EVENT_CALLBACK_ARG_MT);
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
67 freeCallbackArgs(arg, L);
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
68 return 0;
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
69 }
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
70
22
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
71 le_callback* event_callback_push(lua_State* L, int baseIdx, int callbackIdx) {
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
72 le_callback* cb;
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
73 le_base *base = event_base_get(L, baseIdx);
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
74 luaL_checktype(L, callbackIdx, LUA_TFUNCTION);
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
75 cb = lua_newuserdata(L, sizeof(*cb));
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
76 luaL_getmetatable(L, EVENT_CALLBACK_ARG_MT);
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
77 lua_setmetatable(L, -2);
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
78
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
79 lua_pushvalue(L, callbackIdx);
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
80 cb->callbackRef = luaL_ref(L, LUA_REGISTRYINDEX);
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
81 cb->base = base;
23
897150985f13 Added support for timeouts and timers.
Thomas Harning Jr <harningt@gmail.com>
parents: 22
diff changeset
82 memset(&cb->timeout, 0, sizeof(cb->timeout));
22
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
83 return cb;
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
84 }
48a109847dce Completely refactored event_callback creation out into event_callback.
Thomas Harning Jr <harningt@gmail.com>
parents: 21
diff changeset
85
20
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
86 int event_callback_register(lua_State* L) {
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
87 luaL_newmetatable(L, EVENT_CALLBACK_ARG_MT);
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
88 lua_pushcfunction(L, luaevent_cb_gc);
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
89 lua_setfield(L, -2, "__gc");
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
90 lua_newtable(L);
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
91 lua_pushcfunction(L, luaevent_cb_gc);
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
92 lua_setfield(L, -2, "close");
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
93 lua_setfield(L, -2, "__index");
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
94 lua_pop(L, 1);
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
95 return 0;
71bc2e49366c Beginning refactoring of the event_callback outside of the core
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
96 }

mercurial