<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, May 9, 2013 at 5:06 PM, Yonit Halperin <span dir="ltr"><<a href="mailto:yhalperi@redhat.com" target="_blank">yhalperi@redhat.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">On 05/09/2013 10:46 AM, Marc-André Lureau wrote:<br>
</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">
<br>
<br>
<br>
On Wed, May 1, 2013 at 4:19 PM, Yonit Halperin <<a href="mailto:yhalperi@redhat.com" target="_blank">yhalperi@redhat.com</a><br></div><div><div class="h5">
<mailto:<a href="mailto:yhalperi@redhat.com" target="_blank">yhalperi@redhat.com</a>>> wrote:<br>
<br>
    mm-time can change after migration. This can cause video synchronization<br>
    problems after migration if not handled appropriately (see rhbz#951664).<br>
    ---<br>
      gtk/spice-session.c | 39 ++++++++++++++++++++++++++++++<u></u>+++++++++<br>
      1 file changed, 39 insertions(+)<br>
<br>
    diff --git a/gtk/spice-session.c b/gtk/spice-session.c<br>
    index f46ac01..1b5a2f2 100644<br>
    --- a/gtk/spice-session.c<br>
    +++ b/gtk/spice-session.c<br>
    @@ -115,11 +115,23 @@ enum {<br>
      enum {<br>
          SPICE_SESSION_CHANNEL_NEW,<br>
          SPICE_SESSION_CHANNEL_DESTROY,<br>
    +    SPICE_SESSION_MM_TIME_RESET,<br>
          SPICE_SESSION_LAST_SIGNAL,<br>
      };<br>
<br>
      static guint signals[SPICE_SESSION_LAST_<u></u>SIGNAL];<br>
<br>
    +/* main context */<br>
    +static void do_emit_main_context(GObject *object, int signum,<br>
    gpointer params)<br>
    +{<br>
    +    switch (signum) {<br>
    +    case SPICE_SESSION_MM_TIME_RESET:<br>
    +        g_signal_emit(object, signals[signum], 0);<br>
    +        break;<br>
    +    default:<br>
    +        g_warn_if_reached();<br>
    +    }<br>
    +}<br>
<br>
      static void update_proxy(SpiceSession *self, const gchar *str)<br>
      {<br>
    @@ -1071,6 +1083,23 @@ static void<br>
    spice_session_class_init(<u></u>SpiceSessionClass *klass)<br>
                           SPICE_TYPE_CHANNEL);<br>
<br>
          /**<br>
    +     * SpiceSession::mm-time-reset:<br>
    +     * @session: the session that emitted the signal<br>
    +     *<br>
    +     * The #SpiceSession::mm-time-reset is emitted when we identify<br>
    discontinuity in mm-time<br>
    +     *<br>
    +     * Since 0.20<br>
    +     **/<br>
    +    signals[SPICE_SESSION_MM_TIME_<u></u>RESET] =<br>
    +        g_signal_new("mm-time-reset",<br>
    +                     G_OBJECT_CLASS_TYPE(gobject_<u></u>class),<br>
    +                     G_SIGNAL_RUN_FIRST,<br>
    +                     0, NULL, NULL,<br>
    +                     g_cclosure_marshal_VOID__VOID,<br>
    +                     G_TYPE_NONE,<br>
    +                     0);<br>
    +<br>
    +    /**<br>
           * SpiceSession:read-only:<br>
           *<br>
           * Whether this connection is read-only mode.<br>
    @@ -1927,16 +1956,26 @@ guint32<br>
    spice_session_get_mm_time(<u></u>SpiceSession *session)<br>
          return s->mm_time + (g_get_monotonic_time() -<br>
    s->mm_time_at_clock) / 1000;<br>
      }<br>
<br>
    +#define MM_TIME_DIFF_RESET_THRESH 500 // 0.5 sec<br>
    +<br>
      G_GNUC_INTERNAL<br>
      void spice_session_set_mm_time(<u></u>SpiceSession *session, guint32 time)<br>
      {<br>
          SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(<u></u>session);<br>
    +    guint32 old_time;<br>
<br>
          g_return_if_fail(s != NULL);<br>
<br>
    +    old_time = spice_session_get_mm_time(<u></u>session);<br>
    +<br>
          s->mm_time = time;<br>
          s->mm_time_at_clock = g_get_monotonic_time();<br>
          SPICE_DEBUG("set mm time: %u",<br>
    spice_session_get_mm_time(<u></u>session));<br>
    +    if (time > old_time + MM_TIME_DIFF_RESET_THRESH ||<br>
    +        old_time > time + MM_TIME_DIFF_RESET_THRESH) {<br>
<br>
<br>
If time goes backward, I think we should reset mm-time without threshold..<br>
</div></div></blockquote>
I don't see why it should be different.<div class="im"><br></div></blockquote><div><br></div><div>The threshold is a simple heuristic to detect timer discontinuity, in my view.<br><br></div><div>But when time goes backward although it is supposed to be monotonic, there isn't any need for a threshold.<br>
<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
    +        SPICE_DEBUG("%s: mm-time-reset, old %u, new %u",<br>
    __FUNCTION__, old_time, s->mm_time);<br>
    +        emit_main_context(session, SPICE_SESSION_MM_TIME_RESET);<br>
<br>
<br>
This looks problematic, as this function is called from main and<br>
coroutine context. We need to handle that, perhaps like I proposed in<br>
previous review<br>
</blockquote></div>
mmm...I thought this is what you proposed in the previous review, to replace g_signal_emit, with emit_main_context. If not, please explain the problem.<br></blockquote><div><br><br>There is no facility today to send signal on main/leader (g_signal_emit)
 or coroutine (emit_main_context) depending on the context automatically. So far, we have avoided sending signaling in both contexts. Using emit_main_context() from main context will at least produce some warnings, and the delayed emission might have undesired result depending on coroutine backend.<br>
<br>One solution would be to check if the
 current context  is main/leader or if it has a caller coroutine ("coroutine context"). Perhaps the easier would be to augment emit_main_context() 
macro to handle this...<br clear="all"></div></div><br>-- <br>Marc-André Lureau
</div></div>