Skip to content

Commit c3b08a1

Browse files
author
Brian Maher
committed
Add loop:fork() API, remove dependency on pthread, and stop calling ev_default_fork automatically.
1 parent 4d759e3 commit c3b08a1

File tree

4 files changed

+33
-14
lines changed

4 files changed

+33
-14
lines changed

README

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ Choosing a backend:
5454

5555
Please see the documentation for libev for more details.
5656

57+
WARNING:
58+
59+
If your program fork()s, then you will need to re-initialize
60+
your event loop(s) in the child process. You can do this
61+
re-initialization using the loop:fork() function.
62+
5763
-- ev functions --
5864

5965
major, minor = ev.version()
@@ -167,6 +173,11 @@ ev.SIGNAL (constant)
167173

168174
-- ev.Loop object methods --
169175

176+
loop:fork()
177+
178+
You *must* call this function in the child process after fork(2)
179+
system call and before the next iteration of the event loop.
180+
170181
loop:loop()
171182

172183
Run the event loop! Returns when there are no more watchers

loop_lua_ev.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ static int create_loop_mt(lua_State *L) {
3333
{ "loop", loop_loop },
3434
{ "unloop", loop_unloop },
3535
{ "backend", loop_backend },
36+
{ "fork", loop_fork },
3637
{ "__gc", loop_delete },
3738
{ NULL, NULL }
3839
};
@@ -81,9 +82,6 @@ static struct ev_loop** check_loop_and_init(lua_State *L, int loop_i) {
8182
" is causing it to select a bad backend?");
8283
}
8384
register_obj(L, loop_i, *loop_r);
84-
85-
/* TODO: Only enable this if linked with pthread: */
86-
pthread_atfork(0, 0, ev_default_fork);
8785
}
8886
return loop_r;
8987
}
@@ -262,3 +260,22 @@ static int loop_backend(lua_State *L) {
262260
lua_pushinteger(L, ev_backend(*check_loop_and_init(L, 1)));
263261
return 1;
264262
}
263+
264+
/**
265+
* Make it safe to resume an event loop after the fork(2) system call.
266+
*
267+
* [-0, +0, m]
268+
*/
269+
static int loop_fork(lua_State *L) {
270+
struct ev_loop* loop = *check_loop(L, 1);
271+
272+
if ( UNINITIALIZED_DEFAULT_LOOP == loop ) {
273+
// Do nothing!
274+
} else if ( ev_is_default_loop(loop) ) {
275+
ev_default_fork();
276+
} else {
277+
ev_loop_fork(loop);
278+
}
279+
280+
return 0;
281+
}

lua-ev.rockspec

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,6 @@ external_dependencies = {
2323
header = "ev.h",
2424
library = "libev.so"
2525
},
26-
PTHREADS = {
27-
header = "pthread.h",
28-
},
29-
platforms = {
30-
linux = {
31-
PTHREADS = {
32-
library = "libpthread.so"
33-
}
34-
}
35-
}
3626
}
3727

3828
build = {
@@ -52,7 +42,7 @@ build = {
5242
modules = {
5343
ev = {
5444
libraries = {
55-
"ev", "pthread"
45+
"ev"
5646
}
5747
}
5848
}

lua_ev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ static int loop_update_now(lua_State *L);
8585
static int loop_loop(lua_State *L);
8686
static int loop_unloop(lua_State *L);
8787
static int loop_backend(lua_State *L);
88+
static int loop_fork(lua_State *L);
8889

8990
/**
9091
* Object functions:

0 commit comments

Comments
 (0)