summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrediano Ziglio <fziglio@redhat.com>2017-07-06 09:02:11 +0100
committerFrediano Ziglio <fziglio@redhat.com>2018-07-03 11:12:19 +0100
commitdf88b204c6332a811f1ce15ff0b2b947fe183bc2 (patch)
treee33443c9f3739a5f816588323c8706acaa8e2e2a
parent42cae53d03fe4008938c1ae2f06edf7b68d2576e (diff)
WIP use 2 different processes for stability and not block on VT changes
-rw-r--r--src/spice-streaming-agent.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/spice-streaming-agent.cpp b/src/spice-streaming-agent.cpp
index e41b732..1711581 100644
--- a/src/spice-streaming-agent.cpp
+++ b/src/spice-streaming-agent.cpp
@@ -32,6 +32,9 @@
#include <poll.h>
#include <syslog.h>
#include <signal.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include <exception>
#include <stdexcept>
#include <memory>
@@ -59,6 +62,10 @@ struct SpiceStreamDataMessage
StreamMsgData msg;
};
+struct ChildStatus {
+ bool launch_again;
+};
+
static bool streaming_requested = false;
static bool quit_requested = false;
static std::set<SpiceVideoCodecType> client_codecs;
@@ -67,6 +74,9 @@ static const char vt_property_name[] = "XFree86_has_VT";
static const char *stream_port_name = "/dev/virtio-ports/org.spice-space.stream.0";
static Atom vt_property = None;
static std::atomic_bool vt_active;
+#ifdef CHILD_SEP
+static volatile ChildStatus *child_status;
+#endif
static bool have_something_to_read(StreamPort &stream_port, bool blocking, int &fd)
{
@@ -197,6 +207,9 @@ static void read_command(StreamPort &stream_port, bool blocking)
update_fd.ack();
bool vt_active = ::vt_active.load(std::memory_order_relaxed);
if (!vt_active) {
+#ifdef CHILD_SEP
+ child_status->launch_again = true;
+#endif
exit(0);
}
continue;
@@ -332,6 +345,9 @@ static void cursor_changes(StreamPort *stream_port, Display *display, int event_
// update vt property, activate screen read if needed
bool vt_active = get_win_prop_int(display, rootwindow, vt_property) != 0;
if (!vt_active) {
+#ifdef CHILD_SEP
+ child_status->launch_again = true;
+#endif
// this is necessary as to avoid a clean exit that will hangs :(
_Exit(0);
}
@@ -520,6 +536,36 @@ int main(int argc, char* argv[])
openlog("spice-streaming-agent",
isatty(fileno(stderr)) ? (LOG_PERROR|LOG_PID) : LOG_PID, LOG_USER);
+#ifdef CHILD_SEP
+ /* shared a bit of memory with the program which are going to do the hard job */
+ child_status =
+ (ChildStatus *) mmap(NULL, sizeof(ChildStatus), PROT_READ|PROT_WRITE,
+ MAP_SHARED|MAP_ANONYMOUS, -1, 0);
+ if (child_status == MAP_FAILED) {
+ syslog(LOG_ERR, "mmap failed\n");
+ return EXIT_FAILURE;
+ }
+
+ for (;;) {
+ child_status->launch_again = false;
+
+ printf("launching new child\n");
+ pid_t child = fork();
+ if (child == -1) {
+ syslog(LOG_ERR, "fork failed\n");
+ return EXIT_FAILURE;
+ }
+ if (!child)
+ break;
+
+ int status;
+ while (waitpid(child, &status, 0) == -1 && errno == EINTR)
+ continue;
+ if (!child_status->launch_again)
+ return WEXITSTATUS(status);
+ }
+#endif
+
// this should be done after the fork to avoid duplicating
// resources