<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 10 Nov 2017, at 14:15, Frediano Ziglio <<a href="mailto:fziglio@redhat.com" class="">fziglio@redhat.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><br class="">From: Christophe de Dinechin <<a href="mailto:dinechin@redhat.com" class="">dinechin@redhat.com</a>><br class=""><br class="">This incidentally fixes a race condition processing X events,<br class="">where we could possibly start sending cursor events to the<br class="">stream before it was actually open.<br class=""><br class="">Signed-off-by: Christophe de Dinechin <<a href="mailto:dinechin@redhat.com" class="">dinechin@redhat.com</a>><br class="">---<br class="">src/spice-streaming-agent.cpp | 68<br class="">+++++++++++++++++++++++--------------------<br class="">1 file changed, 37 insertions(+), 31 deletions(-)<br class=""><br class="">diff --git a/src/spice-streaming-agent.cpp b/src/spice-streaming-agent.cpp<br class="">index 8300cf2..33e0345 100644<br class="">--- a/src/spice-streaming-agent.cpp<br class="">+++ b/src/spice-streaming-agent.cpp<br class="">@@ -51,31 +51,39 @@ struct SpiceStreamDataMessage<br class="">    StreamMsgData msg;<br class="">};<br class=""><br class="">-struct Stream<br class="">+struct SpiceStream<br class="">{<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Would promote to a class.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></div></blockquote>OK</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">-  Stream(const char *name, int &fd): fd(fd)<br class="">+  SpiceStream(const char *name): streamfd(open(name, O_RDWR))<br class="">  {<br class="">-    fd = open(name, O_RDWR);<br class="">-    if (fd < 0)<br class="">+    if (streamfd < 0)<br class="">      throw std::runtime_error("failed to open streaming device");<br class="">  }<br class="">-  ~Stream()<br class="">+  ~SpiceStream()<br class="">  {<br class="">-    if (fd >= 0)<br class="">-      close(fd);<br class="">-    fd = -1;<br class="">+    if (streamfd >= 0)<br class="">+      close(streamfd);<br class="">+    streamfd = -1;<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">is the if still needed?</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></div></blockquote><div><br class=""></div>No</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">  }<br class="">-  int &fd;<br class="">+<br class="">+  int have_something_to_read(int *pfd, int timeout);<br class="">+  int read_command_from_stdin(void);<br class="">+  int read_command_from_device(void);<br class="">+  int read_command(int blocking);<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Some are not strictly related to the stream.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></div></blockquote><div><br class=""></div><div>But right now, things are a bit too interconnected because of the way read_command is structured.</div><div>Id’ like to split into another class, but I was planning to do that next.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+  size_t write_all(int fd, const void *buf, const size_t len);<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">this has nothing to specifically do with the structure,</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">mostly with some API (write) behaviour like partial write and</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">signals.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></div></blockquote><div><br class=""></div><div>Made it private. Also removed fd, it’s always streamfd.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+  int send_format(unsigned w, unsigned h, unsigned c);<br class="">+  int send_frame(const void *buf, const unsigned size);<br class="">+  void send_cursor(const XFixesCursorImage &image);<br class="">+private:<br class="">+  int streamfd;<br class="">};<br class=""><br class="">static int streaming_requested;<br class="">static bool quit;<br class="">-static int streamfd = -1;<br class="">static bool stdin_ok;<br class="">static int log_binary = 0;<br class="">static std::mutex stream_mtx;<br class=""><br class="">-static int have_something_to_read(int *pfd, int timeout)<br class="">+int SpiceStream::have_something_to_read(int *pfd, int timeout)<br class="">{<br class="">    int nfds;<br class="">    struct pollfd pollfds[2] = {<br class="">@@ -97,7 +105,7 @@ static int have_something_to_read(int *pfd, int timeout)<br class="">    return *pfd != -1;<br class="">}<br class=""><br class="">-static int read_command_from_stdin(void)<br class="">+int SpiceStream::read_command_from_stdin(void)<br class="">{<br class="">    char buffer[64], *p, *save = NULL;<br class=""><br class="">@@ -121,7 +129,7 @@ static int read_command_from_stdin(void)<br class="">    return 1;<br class="">}<br class=""><br class="">-static int read_command_from_device(void)<br class="">+int SpiceStream::read_command_from_device(void)<br class="">{<br class="">    StreamDevHeader hdr;<br class="">    uint8_t msg[64];<br class="">@@ -163,7 +171,7 @@ static int read_command_from_device(void)<br class="">    return 1;<br class="">}<br class=""><br class="">-static int read_command(int blocking)<br class="">+int SpiceStream::read_command(int blocking)<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">OT: maybe should be bool blocking ?</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></div></blockquote><div><br class=""></div>OK</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">{<br class="">    int fd, n=1;<br class="">    int timeout = blocking?-1:0;<br class="">@@ -185,8 +193,7 @@ static int read_command(int blocking)<br class="">    return n;<br class="">}<br class=""><br class="">-static size_t<br class="">-write_all(int fd, const void *buf, const size_t len)<br class="">+size_t SpiceStream::write_all(int fd, const void *buf, const size_t len)<br class="">{<br class="">    size_t written = 0;<br class="">    while (written < len) {<br class="">@@ -204,7 +211,7 @@ write_all(int fd, const void *buf, const size_t len)<br class="">    return written;<br class="">}<br class=""><br class="">-static int spice_stream_send_format(unsigned w, unsigned h, unsigned c)<br class="">+int SpiceStream::send_format(unsigned w, unsigned h, unsigned c)<br class="">{<br class=""><br class="">    SpiceStreamFormatMessage msg;<br class="">@@ -225,7 +232,7 @@ static int spice_stream_send_format(unsigned w, unsigned<br class="">h, unsigned c)<br class="">    return EXIT_SUCCESS;<br class="">}<br class=""><br class="">-static int spice_stream_send_frame(const void *buf, const unsigned size)<br class="">+int SpiceStream::send_frame(const void *buf, const unsigned size)<br class="">{<br class="">    SpiceStreamDataMessage msg;<br class="">    const size_t msgsize = sizeof(msg);<br class="">@@ -304,7 +311,7 @@ static void usage(const char *progname)<br class="">    exit(1);<br class="">}<br class=""><br class="">-static void send_cursor(const XFixesCursorImage &image)<br class="">+void SpiceStream::send_cursor(const XFixesCursorImage &image)<br class="">{<br class="">    if (image.width >= 1024 || image.height >= 1024)<br class="">        return;<br class="">@@ -337,7 +344,7 @@ static void send_cursor(const XFixesCursorImage &image)<br class="">    write_all(streamfd, msg.get(), cursor_size);<br class="">}<br class=""><br class="">-static void cursor_changes(Display *display, int event_base)<br class="">+static void cursor_changes(Display *display, int event_base, SpiceStream<br class="">*stream)<br class="">{<br class="">    unsigned long last_serial = 0;<br class=""><br class="">@@ -355,23 +362,25 @@ static void cursor_changes(Display *display, int<br class="">event_base)<br class="">            continue;<br class=""><br class="">        last_serial = cursor->cursor_serial;<br class="">-        send_cursor(*cursor);<br class="">+        stream->send_cursor(*cursor);<br class="">    }<br class="">}<br class=""><br class="">static void<br class="">-do_capture(const char *streamport, FILE *f_log)<br class="">+do_capture(const char *streamport, FILE *f_log, Display *display, int<br class="">event_base)<br class="">{<br class="">    std::unique_ptr<FrameCapture> capture(agent.GetBestFrameCapture());<br class="">    if (!capture)<br class="">        throw std::runtime_error("cannot find a suitable capture system");<br class=""><br class="">-    Stream stream(streamport, streamfd);<br class="">+    SpiceStream stream(streamport);<br class="">+    std::thread cursor_th(cursor_changes, display, event_base, &stream);<br class="">+    cursor_th.detach();<br class=""><br class="">    unsigned int frame_count = 0;<br class="">    while (! quit) {<br class="">        while (!quit && !streaming_requested) {<br class="">-            if (read_command(1) < 0) {<br class="">+            if (stream.read_command(1) < 0) {<br class="">                syslog(LOG_ERR, "FAILED to read command\n");<br class="">                return;<br class="">            }<br class="">@@ -406,7 +415,7 @@ do_capture(const char *streamport, FILE *f_log)<br class=""><br class="">                syslog(LOG_DEBUG, "wXh %uX%u  codec=%u\n", width, height,<br class="">                codec);<br class=""><br class="">-                if (spice_stream_send_format(width, height, codec) ==<br class="">EXIT_FAILURE)<br class="">+                if (stream.send_format(width, height, codec) ==<br class="">EXIT_FAILURE)<br class="">                    throw std::runtime_error("FAILED to send format<br class="">                    message");<br class="">            }<br class="">            if (f_log) {<br class="">@@ -417,12 +426,12 @@ do_capture(const char *streamport, FILE *f_log)<br class="">                    hexdump(frame.buffer, frame.buffer_size, f_log);<br class="">                }<br class="">            }<br class="">-            if (spice_stream_send_frame(frame.buffer, frame.buffer_size) ==<br class="">EXIT_FAILURE) {<br class="">+            if (stream.send_frame(frame.buffer, frame.buffer_size) ==<br class="">EXIT_FAILURE) {<br class="">                syslog(LOG_ERR, "FAILED to send a frame\n");<br class="">                break;<br class="">            }<br class="">            //usleep(1);<br class="">-            if (read_command(0) < 0) {<br class="">+            if (stream.read_command(0) < 0) {<br class="">                syslog(LOG_ERR, "FAILED to read command\n");<br class="">                return;<br class="">            }<br class="">@@ -516,12 +525,9 @@ int main(int argc, char* argv[])<br class="">    Window rootwindow = DefaultRootWindow(display);<br class="">    XFixesSelectCursorInput(display, rootwindow,<br class="">    XFixesDisplayCursorNotifyMask);<br class=""><br class="">-    std::thread cursor_th(cursor_changes, display, event_base);<br class="">-    cursor_th.detach();<br class="">-<br class="">    int ret = EXIT_SUCCESS;<br class="">    try {<br class="">-        do_capture(streamport, f_log);<br class="">+      do_capture(streamport, f_log, display, event_base);<br class="">    }<br class="">    catch (std::runtime_error &err) {<br class="">        syslog(LOG_ERR, "%s\n", err.what());<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Frediano</span></div></div></blockquote></div><br class=""></body></html>