2 Copyright (C) 2007,2012,2013 Thomas Harning <harningt@gmail.com>
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 #include "event_callback.h"
24 #include "event_buffer.h"
25 #include "buffer_event.h"
31 #define EVENT_BASE_MT "EVENT_BASE_MT"
33 le_base
* event_base_get(lua_State
* L
, int idx
) {
34 return (le_base
*)luaL_checkudata(L
, idx
, EVENT_BASE_MT
);
37 int luaevent_newbase(lua_State
* L
) {
38 le_base
*base
= (le_base
*)lua_newuserdata(L
, sizeof(le_base
));
39 base
->loop_L
= NULL
; /* No running loop */
40 base
->base
= event_init();
41 luaL_getmetatable(L
, EVENT_BASE_MT
);
42 lua_setmetatable(L
, -2);
46 int luaevent_libevent_version(lua_State
* L
) {
47 lua_pushstring(L
, event_get_version());
51 static int luaevent_base_gc(lua_State
* L
) {
52 le_base
*base
= event_base_get(L
, 1);
54 event_base_free(base
->base
);
60 int getSocketFd(lua_State
* L
, int idx
) {
62 if(lua_isnumber(L
, idx
)) {
63 fd
= lua_tonumber(L
, idx
);
65 luaL_checktype(L
, idx
, LUA_TUSERDATA
);
66 lua_getfield(L
, idx
, "getfd");
68 return luaL_error(L
, "Socket type missing 'getfd' method");
69 lua_pushvalue(L
, idx
);
71 fd
= lua_tointeger(L
, -1);
77 void load_timeval(double time
, struct timeval
*tv
) {
78 tv
->tv_sec
= (int) time
;
79 tv
->tv_usec
= (int)( (time
- tv
->tv_sec
) * 1000000 );
82 /* sock, event, callback, timeout */
83 static int luaevent_addevent(lua_State
* L
) {
85 le_callback
* arg
= event_callback_push(L
, 1, 4);
86 struct timeval
*tv
= &arg
->timeout
;
87 if(lua_isnil(L
, 2) && lua_isnumber(L
, 5)) {
88 fd
= -1; /* Per event_timer_set.... */
90 fd
= getSocketFd(L
, 2);
92 event
= luaL_checkinteger(L
, 3);
93 if(lua_isnumber(L
, 5)) {
94 double time
= lua_tonumber(L
, 5);
95 load_timeval(time
, tv
);
101 event_set(&arg
->ev
, fd
, event
| EV_PERSIST
, luaevent_callback
, arg
);
102 event_base_set(arg
->base
->base
, &arg
->ev
);
103 event_add(&arg
->ev
, tv
);
107 static int luaevent_loop(lua_State
* L
) {
109 le_base
*base
= event_base_get(L
, 1);
111 base
->errorMessage
= LUA_NOREF
;
112 ret
= event_base_loop(base
->base
, 0);
113 if(base
->errorMessage
!= LUA_NOREF
)
115 lua_rawgeti(L
, LUA_REGISTRYINDEX
, base
->errorMessage
);
116 luaL_unref(L
, LUA_REGISTRYINDEX
, base
->errorMessage
);
117 base
->errorMessage
= LUA_NOREF
;
120 lua_pushinteger(L
, ret
);
124 static int luaevent_loopexit(lua_State
*L
) {
126 le_base
*base
= event_base_get(L
, 1);
127 struct timeval tv
= { 0, 0 };
128 if(lua_gettop(L
) >= 2) /* Optional timeout before exiting the loop */
129 load_timeval(luaL_checknumber(L
, 2), &tv
);
130 ret
= event_base_loopexit(base
->base
, &tv
);
131 lua_pushinteger(L
, ret
);
135 static int luaevent_method(lua_State
* L
) {
136 #ifdef _EVENT_VERSION
137 le_base
*base
= event_base_get(L
, 1);
138 if(strcmp(_EVENT_VERSION
, "1.3")<0)
139 lua_pushstring(L
, event_base_get_method(base
->base
));
142 lua_pushstring(L
, event_get_method());
146 static luaL_Reg base_funcs
[] = {
147 { "addevent", luaevent_addevent
},
148 { "loop", luaevent_loop
},
149 { "loopexit", luaevent_loopexit
},
150 { "method", luaevent_method
},
154 static luaL_Reg funcs
[] = {
155 { "new", luaevent_newbase
},
156 { "libevent_version", luaevent_libevent_version
},
165 static namedInteger consts
[] = {
167 {"EV_READ", EV_READ
},
168 {"EV_WRITE", EV_WRITE
},
169 {"EV_TIMEOUT", EV_TIMEOUT
},
170 {"EV_SIGNAL", EV_SIGNAL
},
171 {"EV_PERSIST", EV_PERSIST
},
173 {"EVBUFFER_READ", EVBUFFER_READ
},
174 {"EVBUFFER_WRITE", EVBUFFER_WRITE
},
175 {"EVBUFFER_EOF", EVBUFFER_EOF
},
176 {"EVBUFFER_ERROR", EVBUFFER_ERROR
},
177 {"EVBUFFER_TIMEOUT", EVBUFFER_TIMEOUT
},
181 void setNamedIntegers(lua_State
* L
, namedInteger
* p
) {
183 lua_pushinteger(L
, p
->value
);
184 lua_setfield(L
, -2, p
->name
);
190 int luaopen_luaevent_core(lua_State
* L
) {
192 WORD wVersionRequested
= MAKEWORD(2, 2);
194 WSAStartup(wVersionRequested
, &wsaData
);
197 /* Setup metatable */
198 luaL_newmetatable(L
, EVENT_BASE_MT
);
200 luaL_register(L
, NULL
, base_funcs
);
201 lua_setfield(L
, -2, "__index");
202 lua_pushcfunction(L
, luaevent_base_gc
);
203 lua_setfield(L
, -2, "__gc");
207 luaL_register(L
, NULL
, funcs
);
208 setNamedIntegers(L
, consts
);
210 /* Register external items */
211 event_callback_register(L
);
212 event_buffer_register(L
, lua_gettop(L
));
213 buffer_event_register(L
, lua_gettop(L
));