#define TIME_ERRORS
#define CLOSE_ON_FORK_ERRORS
#define DAEMON_ERRORS
-#define GUI_ERRORS
#define GUI_THEME_ERRORS
#define RINGBUFFER_ERRORS
#define SCORE_ERRORS
PARA_ERROR(FLACDEC_DECODER_INIT, "could not init stream decoder"), \
PARA_ERROR(FLACDEC_EOF, "flacdec encountered end of file condition"), \
+#define GUI_ERRORS \
+ PARA_ERROR(GUI_SIGCHLD, "received SIGCHLD"), \
#define FLAC_AFH_ERRORS \
PARA_ERROR(FLAC_CHAIN_ALLOC, "could not create metadata chain"), \
struct status_task {
struct task task;
+ pid_t pid;
char *buf;
int bufsize, loaded;
struct timeval next_exec;
struct status_task *st = container_of(t, struct status_task, task);
if (st->fd >= 0)
- return para_fd_set(st->fd, &s->rfds, &s->max_fileno);
- sched_request_barrier_or_min_delay(&st->next_exec, s);
+ para_fd_set(st->fd, &s->rfds, &s->max_fileno);
+ if (task_get_notification(t) < 0)
+ return sched_min_delay(s);
+ if (st->fd < 0)
+ sched_request_barrier_or_min_delay(&st->next_exec, s);
}
static int status_post_select(struct sched *s, struct task *t)
{
struct status_task *st = container_of(t, struct status_task, task);
size_t sz;
- pid_t pid;
int ret, ret2;
+ ret = task_get_notification(t);
+ if (ret == -E_GUI_SIGCHLD && st->pid > 0) {
+ int exit_status;
+ if (waitpid(st->pid, &exit_status, WNOHANG) == st->pid) {
+ st->pid = 0;
+ PARA_ERROR_LOG("stat command exit status: %d",
+ exit_status);
+ }
+ }
if (st->fd < 0) {
int fds[3] = {0, 1, 0};
+ if (st->pid > 0)
+ return 0;
/* Avoid busy loop */
if (tv_diff(&st->next_exec, now, NULL) > 0)
return 0;
st->next_exec.tv_sec = now->tv_sec + 2;
- ret = para_exec_cmdline_pid(&pid, conf.stat_cmd_arg, fds);
+ ret = para_exec_cmdline_pid(&st->pid, conf.stat_cmd_arg, fds);
if (ret < 0)
return 0;
ret = mark_fd_nonblocking(fds[1]);
// noecho(); /* don't echo input */
}
-static void check_sigchld(void)
-{
- int ret;
- pid_t pid;
-
-reap_next_child:
- ret = para_reap_child(&pid);
- if (ret <= 0)
- return;
- if (pid == exec_pid) {
- exec_pid = 0;
- init_curses();
- print_in_bar(COLOR_MSG, " ");
- }
- goto reap_next_child;
-}
-
/*
* This sucker modifies its first argument. *handler and *arg are
* pointers to 0-terminated strings (inside line). Crap.
reread_conf();
return 1;
case SIGCHLD:
- check_sigchld();
+ task_notify_all(s, E_GUI_SIGCHLD);
return 1;
}
return 1;
return EXEC_IDLE;
}
-static void exec_pre_select(struct sched *s, __a_unused struct task *t)
+static void exec_pre_select(struct sched *s, struct task *t)
{
- enum exec_status es = exec_status();
-
- if (es != EXEC_DCMD)
- return;
if (exec_fds[0] >= 0)
para_fd_set(exec_fds[0], &s->rfds, &s->max_fileno);
if (exec_fds[1] >= 0)
para_fd_set(exec_fds[1], &s->rfds, &s->max_fileno);
+ if (task_get_notification(t) < 0)
+ sched_min_delay(s);
}
static int exec_post_select(struct sched *s, struct task *t)
{
struct exec_task *ct = container_of(t, struct exec_task, task);
int i, ret;
- enum exec_status es = exec_status();
- if (es != EXEC_DCMD)
- return 0;
+ ret = task_get_notification(t);
+ if (ret == -E_GUI_SIGCHLD && exec_pid > 0) {
+ int exit_status;
+ if (waitpid(exec_pid, &exit_status, WNOHANG) == exec_pid) {
+ exec_pid = 0;
+ init_curses();
+ PARA_INFO_LOG("command exit status: %d", exit_status);
+ print_in_bar(COLOR_MSG, " ");
+ }
+ }
for (i = 0; i < 2; i++) {
size_t sz;
if (exec_fds[i] < 0)