#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
+#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <ctype.h>
#include "input.h"
#include "state.pb.h"
-#define STREAM_ID "stream"
-#define STREAM_URL "http://gruessi.zrh.sesse.net:4013/"
-
using namespace std;
ServerPool *servers = NULL;
pfd.events = POLLIN;
int nfds = poll(&pfd, 1, 50);
- if (nfds == 0 || (nfds == -1 && errno == EAGAIN)) {
+ if (nfds == 0 || (nfds == -1 && errno == EINTR)) {
continue;
}
if (nfds == -1) {
int left_to_sleep = parms->stats_interval;
do {
left_to_sleep = sleep(left_to_sleep);
- } while (left_to_sleep > 0);
+ } while (left_to_sleep > 0 && !hupped);
}
return NULL;
}
{
fprintf(stderr, "\nCubemap starting.\n");
+ struct timeval serialize_start;
+ bool is_reexec = false;
+
string config_filename = (argc == 1) ? "cubemap.config" : argv[1];
vector<ConfigLine> config = parse_config(config_filename);
set<string> deserialized_stream_ids;
map<string, Input *> deserialized_inputs;
if (argc == 4 && strcmp(argv[2], "-state") == 0) {
+ is_reexec = true;
+
fprintf(stderr, "Deserializing state from previous process... ");
int state_fd = atoi(argv[3]);
CubemapStateProto loaded_state = read_tempfile(state_fd);
+ serialize_start.tv_sec = loaded_state.serialize_start_sec();
+ serialize_start.tv_usec = loaded_state.serialize_start_usec();
+
// Deserialize the streams.
for (int i = 0; i < loaded_state.streams_size(); ++i) {
servers->add_stream_from_serialized(loaded_state.streams(i));
}
signal(SIGHUP, hup);
+
+ struct timeval server_start;
+ gettimeofday(&server_start, NULL);
+ if (is_reexec) {
+ // Measure time from we started deserializing (below) to now, when basically everything
+ // is up and running. This is, in other words, a conservative estimate of how long our
+ // “glitch” period was, not counting of course reconnects if the configuration changed.
+ double glitch_time = server_start.tv_sec - serialize_start.tv_sec +
+ 1e-6 * (server_start.tv_usec - serialize_start.tv_usec);
+ fprintf(stderr, "Re-exec happened in approx. %.0f ms.\n", glitch_time * 1000.0);
+ }
while (!hupped) {
usleep(100000);
}
// OK, we've been HUPed. Time to shut down everything, serialize, and re-exec.
+ gettimeofday(&serialize_start, NULL);
+
if (!stats_file.empty()) {
+ pthread_kill(stats_thread, SIGHUP);
if (pthread_join(stats_thread, NULL) == -1) {
perror("pthread_join");
exit(1);
}
}
+ pthread_kill(acceptor_thread, SIGHUP);
if (pthread_join(acceptor_thread, NULL) == -1) {
perror("pthread_join");
exit(1);
}
CubemapStateProto state;
+ state.set_serialize_start_sec(serialize_start.tv_sec);
+ state.set_serialize_start_usec(serialize_start.tv_usec);
state.set_server_sock(server_sock);
state.set_port(port);