stat_task->stat_item_values[SI_STATUS_BAR] = make_message(
"%s:no connection to para_server\n",
status_item_list[SI_STATUS_BAR]);
- stat_client_write(stat_task->stat_item_values[SI_STATUS_BAR], SI_STATUS_BAR);
+ stat_client_write(stat_task->stat_item_values[SI_STATUS_BAR],
+ SI_STATUS_BAR);
+ if (stat_task->clock_diff_count) {
+ stat_task->clock_diff_barrier.tv_sec = now->tv_sec + 1;
+ stat_task->clock_diff_barrier.tv_usec = now->tv_usec;
+ }
}
void __noreturn clean_exit(int status, const char *msg)
count > 10? sign : sign * time_smooth, &diff,
&tmp);
stat_task->sa_time_diff = tmp;
- PARA_DEBUG_LOG("time diff (cur/avg): %s%lums/%s%lums\n",
+ PARA_INFO_LOG("time diff (cur/avg): %s%lums/%s%lums\n",
sign > 0? "+" : "-",
tv2ms(&diff),
sa_time_diff_sign ? "+" : "-",
PARA_WARNING_LOG("invalid status line: %s\n", line);
return;
}
+ if (stat_task->clock_diff_count && itemnum != SI_CURRENT_TIME)
+ return;
tmp = make_message("%s\n", line);
stat_client_write(tmp, itemnum);
free(tmp);
struct timeval tv = {sec, usec};
compute_time_diff(&tv);
}
+ if (stat_task->clock_diff_count)
+ stat_task->clock_diff_count--;
break;
}
}
static void status_pre_select(struct sched *s, struct task *t)
{
struct status_task *st = t->private_data;
- int argc = 2;
- char *argv[] = {"audiod", "stat", NULL};
+
t->ret = 1;
if (st->pcd && (audiod_status == AUDIOD_OFF || st->pcd->eof))
close_stat_pipe();
- if (!st->pcd && audiod_status != AUDIOD_OFF
- && tv_diff(now, &st->restart_barrier, NULL) > 0) {
- t->ret = client_parse_config(argc, argv, &st->pcd);
- if (t->ret < 0)
- return;
- t->ret = client_open(st->pcd);
- if (t->ret < 0)
+ if (st->pcd || audiod_status == AUDIOD_OFF)
+ return;
+ if (!st->clock_diff_count && tv_diff(now, &st->restart_barrier, NULL)
+ < 0)
+ return;
+ if (st->clock_diff_count) {
+ char *argv[] = {"audiod", "stat", "1", NULL};
+ int argc = 3;
+ if (tv_diff(now, &st->clock_diff_barrier, NULL) < 0)
return;
- st->pcd->task.event_handler = client_task_event_handler;
- s->timeout.tv_sec = 0;
- s->timeout.tv_usec = 1;
+ PARA_INFO_LOG("clock diff count: %d\n", st->clock_diff_count);
+ t->ret = client_parse_config(argc, argv, &st->pcd);
+
+ } else {
+ char *argv[] = {"audiod", "stat", NULL};
+ int argc = 2;
+ t->ret = client_parse_config(argc, argv, &st->pcd);
}
+
+ if (t->ret < 0)
+ return;
+ t->ret = client_open(st->pcd);
+ if (t->ret < 0)
+ return;
+ st->pcd->task.event_handler = client_task_event_handler;
+ s->timeout.tv_sec = 0;
+ s->timeout.tv_usec = 1;
}
static void status_post_select(__a_unused struct sched *s, struct task *t)
st->task.event_handler = status_event_handler;
st->task.private_data = st;
st->sa_time_diff_sign = 1;
+ st->clock_diff_count = conf.clock_diff_count_arg;
sprintf(st->task.status, "status task");
}
multiple
+option "clock_diff_count" -
+#~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+"check the clock difference between
+server_host (the host running para_server)
+and the local host (running para_audiod)
+that many times before starting any stream
+I/0. Set this to non-zero for non-local
+setups if the clocks of these two hosts are
+not syncronized by ntp or similar."
+
+ int typestr="count"
+ default="0"
+ optional
section "stream i/o options."
};
/**
- * the task for audiod's child (para_client stat)
+ * the task for obtaining para_server's status (para_client stat)
*
* \sa struct task, struct sched
*/
struct status_task {
/** the associated task structure of audiod */
struct task task;
+ /** client data associated with the stat task */
struct private_client_data *pcd;
/** the array of status items sent by para_server */
char *stat_item_values[NUM_STAT_ITEMS];
int length_seconds;
/** the start of the current stream from the view of para_server */
struct timeval server_stream_start;
- /** the averaged time deviation between para_server and para_audiod */
+ /** the average time deviation between para_server and para_audiod */
struct timeval sa_time_diff;
/** whether client time is ahead of server time */
int sa_time_diff_sign;
- /** non-zero if \a af_status is "playing" */
+ /** non-zero if para_server's status is "playing" */
int playing;
+ /** number of times the clock difference is to be checked */
+ unsigned clock_diff_count;
+ /** when to start the next check for clock difference */
+ struct timeval clock_diff_barrier;
};
extern struct status_task *stat_task;
CPPFLAGS="$OLD_CPPFLAGS"
LDFLAGS="$OLD_LDFLAGS"
########################################################################### zmw
-slide="para_slider"
-msg="can not build para_slider"
-CPPFLAGS="$GTK_CFLAGS"
+build_slider="yes"
+OLD_CPPFLAGS="$CPPFLAGS"
+OLD_LD_FLAGS="$LDFLAGS"
+PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.0.4], [], [build_slider="no"])
+CPPFLAGS="$GTK_CFLAGS $GLIB_CFLAGS"
LDFLAGS="$LDFLAGS $GTK_LIBS"
-AC_CHECK_HEADERS([zmw/zmw.h], [], [
- AC_MSG_WARN([zero memory widget header files not found, $msg])
- slide=""
-])
-AC_CHECK_LIB([zmw], [zmw_init], [], [
- AC_MSG_WARN([zero memory widget library not found, $msg])
- slide=""
-])
-extras="$extras $slide"
+AC_CHECK_HEADERS([zmw/zmw.h], [], [build_slider="no"])
+AC_CHECK_LIB([zmw], [zmw_init], [], [build_slider="no"])
+if test "$build_slider" = "no"; then
+ AC_MSG_WARN([will not build para_slider])
+else
+ extras="$extras para_slider"
+fi
+CPPFLAGS="$OLD_CPPFLAGS"
+LDFLAGS="$OLD_LDFLAGS"
receivers supported by para_audiod/para_recv: $receivers
filters supported by para_audiod/para_filter: $filters
writers supported by para_audiod/para_write: $writers
+optional executables: $extras
])
/**
* give up superuser privileges
*
+ * \param username the user to switch to
+ * \param groupname the group to switch to
+ *
* This function returns immediately if not invoked with EUID zero. Otherwise,
* it tries to obtain the GID of \a groupname and the UID of \a username. On
* success, effective and real GID/UID and the saved set-group-ID/set-user-ID
- * are all set accordingly. On errors, an appropriate message is logged and exit()
- * is called to terminate the process.
+ * are all set accordingly. On errors, an appropriate message is logged and
+ * exit() is called to terminate the process.
*
* \sa getpwnam(3), getuid(2), setuid(2), getgrnam(2), setgid(2)
*/
PARA_INFO_LOG("%s", "dropping root privileges\n");
setuid(p->pw_uid);
PARA_DEBUG_LOG("uid: %d, euid: %d\n", getuid(), geteuid());
- setuid(p->pw_uid);
}
/**
d[SI_SELECTOR].align = CENTER;
d[SI_SELECTOR].x = 21;
d[SI_SELECTOR].y = 17;
- d[SI_SELECTOR].len = 20;
+ d[SI_SELECTOR].len = 21;
d[SI_FORMAT].prefix = "format: ";
d[SI_FORMAT].postfix = "";
d[SI_FORMAT].align = CENTER;
d[SI_FORMAT].x = 42;
d[SI_FORMAT].y = 17;
- d[SI_FORMAT].len = 14;
-
+ d[SI_FORMAT].len = 18;
d[SI_NUM_PLAYED].prefix = "#";
d[SI_NUM_PLAYED].postfix = "";