mirror of
https://github.com/uselessd/alcove.git
synced 2026-04-15 09:15:19 +00:00
Allowing setting the number of children per fork
Add the ability to set the number of children per process at runtime.
Since the port uses select(), the number of processes is limited by
FD_SETSIZE:
FD_SETSIZE / 3 - 3
3 fd's per child process + the parent's stdin, stdout and stderr.
This commit is contained in:
@@ -88,16 +88,21 @@ main(int argc, char *argv[])
|
||||
if (!ap)
|
||||
erl_err_sys("calloc");
|
||||
|
||||
ap->child = calloc(ALCOVE_MAX_CHILD, sizeof(alcove_child_t));
|
||||
if (!ap->child)
|
||||
erl_err_sys("calloc");
|
||||
|
||||
act.sa_handler = sighandler;
|
||||
if (sigaction(SIGCHLD, &act, NULL) < 0)
|
||||
erl_err_sys("sigaction");
|
||||
|
||||
while ( (ch = getopt(argc, argv, "hv")) != -1) {
|
||||
/* 3 pipes per child */
|
||||
ap->maxchild = FD_SETSIZE / 3 - 3;
|
||||
|
||||
while ( (ch = getopt(argc, argv, "am:hv")) != -1) {
|
||||
switch (ch) {
|
||||
case 'm': {
|
||||
u_int16_t n = (u_int16_t)atoi(optarg);
|
||||
|
||||
if (n < ap->maxchild)
|
||||
ap->maxchild = n;
|
||||
}
|
||||
case 'v':
|
||||
ap->verbose++;
|
||||
break;
|
||||
@@ -107,6 +112,10 @@ main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
ap->child = calloc(ap->maxchild, sizeof(alcove_child_t));
|
||||
if (!ap->child)
|
||||
erl_err_sys("calloc");
|
||||
|
||||
alcove_ctl(ap);
|
||||
exit(0);
|
||||
}
|
||||
@@ -119,7 +128,7 @@ alcove_ctl(alcove_state_t *ap)
|
||||
|
||||
erl_init(NULL, 0);
|
||||
|
||||
(void)memset(ap->child, 0, sizeof(alcove_child_t) * ALCOVE_MAX_CHILD);
|
||||
(void)memset(ap->child, 0, sizeof(alcove_child_t) * ap->maxchild);
|
||||
sigcaught = 0;
|
||||
|
||||
for ( ; ; ) {
|
||||
@@ -380,7 +389,7 @@ pid_foreach(alcove_state_t *ap, pid_t pid, void *arg1, void *arg2,
|
||||
int i = 0;
|
||||
int rv = 0;
|
||||
|
||||
for (i = 0; i < ALCOVE_MAX_CHILD; i++) {
|
||||
for (i = 0; i < ap->maxchild; i++) {
|
||||
if ((*comp)(ap->child[i].pid, pid) == 0)
|
||||
continue;
|
||||
|
||||
@@ -555,6 +564,7 @@ usage(alcove_state_t *ap)
|
||||
__progname, ALCOVE_VERSION);
|
||||
(void)fprintf(stderr,
|
||||
"usage: %s <options>\n"
|
||||
" -m <num> max children\n"
|
||||
" -v verbose mode\n",
|
||||
__progname
|
||||
);
|
||||
|
||||
@@ -46,11 +46,10 @@ typedef struct {
|
||||
int fderr;
|
||||
} alcove_child_t;
|
||||
|
||||
#define ALCOVE_MAX_CHILD 16
|
||||
|
||||
typedef struct {
|
||||
u_int32_t opt;
|
||||
u_int8_t verbose;
|
||||
u_int16_t maxchild;
|
||||
alcove_child_t *child;
|
||||
} alcove_state_t;
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
static int cons_pid(alcove_child_t *c, void *arg1, void *arg2);
|
||||
|
||||
ETERM *
|
||||
alcove_call(alcove_state_t *ap, u_int32_t call, ETERM *arg)
|
||||
{
|
||||
@@ -52,15 +54,7 @@ alcove_version(alcove_state_t *ap, ETERM *arg)
|
||||
alcove_pid(alcove_state_t *ap, ETERM *arg)
|
||||
{
|
||||
ETERM *t = erl_mk_empty_list();
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < ALCOVE_MAX_CHILD; i++) {
|
||||
if (ap->child[i].pid <= 0)
|
||||
continue;
|
||||
|
||||
t = erl_cons(erl_mk_int(ap->child[i].pid), t);
|
||||
}
|
||||
|
||||
(void)pid_foreach(ap, 0, &t, NULL, pid_not_equal, cons_pid);
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -114,3 +108,11 @@ alcove_free_argv(char **argv)
|
||||
|
||||
free(argv);
|
||||
}
|
||||
|
||||
static int
|
||||
cons_pid(alcove_child_t *c, void *arg1, void *arg2)
|
||||
{
|
||||
ETERM **t = arg1;
|
||||
*t = erl_cons(erl_mk_int(c->pid), *t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -325,25 +325,21 @@ getopts(Options) when is_list(Options) ->
|
||||
Exec = proplists:get_value(exec, Options, ""),
|
||||
Progname = proplists:get_value(progname, Options, progname()),
|
||||
|
||||
Options1 = proplists:substitute_aliases([{ns, namespace}], Options),
|
||||
|
||||
Options2 = lists:map(fun
|
||||
Options1 = lists:map(fun
|
||||
(verbose) ->
|
||||
{verbose, 1};
|
||||
({Tag, [H|_] = N}) when is_atom(Tag), (is_list(H) orelse is_binary(H)) ->
|
||||
[{Tag, X} || X <- N];
|
||||
(N) when is_atom(N) ->
|
||||
{N, true};
|
||||
({_,_} = N) ->
|
||||
N
|
||||
end, Options1),
|
||||
end, Options),
|
||||
|
||||
Switches = lists:append([ optarg(N) || N <- lists:flatten(Options2) ]),
|
||||
Switches = lists:append([ optarg(N) || N <- Options1 ]),
|
||||
[Cmd|Argv] = [ N || N <- string:tokens(Exec, " ") ++ [Progname|Switches], N /= ""],
|
||||
[find_executable(Cmd)|Argv].
|
||||
|
||||
optarg({verbose, Arg}) -> switch(string:copies("v", Arg));
|
||||
optarg({namespace, Arg}) -> switch("n", Arg);
|
||||
optarg({maxchild, Arg}) -> switch("m", Arg);
|
||||
optarg(_) -> "".
|
||||
|
||||
switch(Switch) ->
|
||||
@@ -352,7 +348,7 @@ switch(Switch) ->
|
||||
switch(Switch, Arg) when is_binary(Arg) ->
|
||||
switch(Switch, binary_to_list(Arg));
|
||||
switch(Switch, Arg) ->
|
||||
[lists:concat(["-", Switch]), Arg].
|
||||
[lists:concat(["-", Switch, " ", Arg])].
|
||||
|
||||
find_executable(Exe) ->
|
||||
case os:find_executable(Exe) of
|
||||
|
||||
@@ -51,7 +51,7 @@ run(State) ->
|
||||
].
|
||||
|
||||
start() ->
|
||||
Port = alcove_drv:start([{exec, "sudo"}]),
|
||||
Port = alcove_drv:start([{exec, "sudo"}, {maxchild, 16}]),
|
||||
case os:type() of
|
||||
{unix,linux} = OS ->
|
||||
Flags = alcove:define(Port, clone, [
|
||||
|
||||
Reference in New Issue
Block a user