about XSync extension problem.

lantian ai ailantian at googlemail.com
Mon Nov 16 18:21:00 PST 2009


Hello all:

I met a problem when I use XSync extension.

The application is gnome-screensaver, in 2.25.1 gnome-screensaver used
XSync extention to track the Xevents.

first It will create XSyncAlarm .

then when Alarm signal comes, gnome-screensaver will enter into sleep state.

on My desktop.

I set the timeout to 1 minite.

then I use date -s command to change the date to 2 minites later.

But gnome-screensaver can not get into sleep state.

I looked into gnome-screensaver source code.

XSync code looks like this.
src/gs-idle-monitor.c

static gboolean
init_xsync (GSIdleMonitor *monitor)
{
       int                 sync_error_base;
       int                 res;
       int                 major;
       int                 minor;
       int                 i;
       int                 ncounters;
       XSyncSystemCounter *counters;

       res = XSyncQueryExtension (GDK_DISPLAY (),
                                  &monitor->priv->sync_event_base,
                                  &sync_error_base);
       if (! res) {
               g_warning ("GSIdleMonitor: Sync extension not present");
               return FALSE;
       }

       res = XSyncInitialize (GDK_DISPLAY (), &major, &minor);
       if (! res) {
               g_warning ("GSIdleMonitor: Unable to initialize Sync
extension");
               return FALSE;
       }

       counters = XSyncListSystemCounters (GDK_DISPLAY (), &ncounters);
       for (i = 0; i < ncounters; i++) {
               if (counters[i].name != NULL
                   && strcmp (counters[i].name, "IDLETIME") == 0) {
                       monitor->priv->counter = counters[i].counter;
                       break;
               }
       }
       XSyncFreeSystemCounterList (counters);

       if (monitor->priv->counter == None) {
               g_warning ("GSIdleMonitor: IDLETIME counter not found");
               return FALSE;
       }

       /* select for sync events */
       gdk_error_trap_push ();
       XSelectInput (GDK_DISPLAY (), GDK_ROOT_WINDOW (), XSyncAlarmNotifyMask);
       if (gdk_error_trap_pop ()) {
               g_warning ("XSelectInput failed");
       }

       gdk_window_add_filter (NULL, (GdkFilterFunc)xevent_filter, monitor);

       return TRUE;
}


XSync Alarm create code here

in gnome-screensaver

src/gs-idle-monitor.c

static gboolean
_xsync_alarm_set (GSIdleMonitor      *monitor,
                 GSIdleMonitorWatch *watch)
{
       XSyncAlarmAttributes attr;
       XSyncValue           delta;
       guint                flags;

       flags = XSyncCACounter
               | XSyncCAValueType
               | XSyncCATestType
               | XSyncCAValue
               | XSyncCADelta;

       XSyncIntToValue (&delta, 0);
       attr.trigger.counter = monitor->priv->counter;
       attr.trigger.value_type = XSyncAbsolute;
       attr.trigger.wait_value = watch->interval;
       attr.delta = delta;

       attr.trigger.test_type = XSyncPositiveTransition;
       if (watch->xalarm_positive != None) {
               gs_debug ("GSIdleMonitor: updating alarm for positive
transition wait=%lld",
                         _xsyncvalue_to_int64 (attr.trigger.wait_value));
               XSyncChangeAlarm (GDK_DISPLAY (),
watch->xalarm_positive, flags, &attr);
       } else {
               gs_debug ("GSIdleMonitor: creating new alarm for
positive transition wait=%lld",
                         _xsyncvalue_to_int64 (attr.trigger.wait_value));
               watch->xalarm_positive = XSyncCreateAlarm (GDK_DISPLAY
(), flags, &attr);
       }

       attr.trigger.test_type = XSyncNegativeTransition;
       if (watch->xalarm_negative != None) {
               gs_debug ("GSIdleMonitor: updating alarm for negative
transition wait=%lld",
                         _xsyncvalue_to_int64 (attr.trigger.wait_value));
               XSyncChangeAlarm (GDK_DISPLAY (),
watch->xalarm_negative, flags, &attr);
       } else {
               gs_debug ("GSIdleMonitor: creating new alarm for
positive transition wait=%lld",
                         _xsyncvalue_to_int64 (attr.trigger.wait_value));
               watch->xalarm_negative = XSyncCreateAlarm (GDK_DISPLAY
(), flags, &attr);
       }

       return TRUE;
}


and I looked into Xorg 1.6.2's code about XSync extension.

Xext/sync.c

static Bool
SyncCheckTriggerPositiveTransition(pTrigger, oldval)
   SyncTrigger *pTrigger;
   CARD64      oldval;
{
   return (pTrigger->pCounter == NULL ||
           (XSyncValueLessThan(oldval, pTrigger->test_value) &&
            XSyncValueGreaterOrEqual(pTrigger->pCounter->value,
                                     pTrigger->test_value)));
}


when
pTrigger->pCounter->value
bigger than
pTrigger->test_value
bigger than
oldval

this will return TRUE

But on my desktop , seems after I changed my time with date -s

gnomescreensaver can not receive Alarm event from Xserver

But I have an arm machine .

after I changed the time, gnome-screensaver will enter sleep state.

I don't know why.

the idletime

static void
IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return)
{
   CARD32 idle = GetTimeInMillis() - lastDeviceEventTime.milliseconds;
   XSyncIntsToValue (pValue_return, idle, 0);
}

_X_EXPORT CARD32
GetTimeInMillis(void)
{
   struct timeval tv;

#ifdef MONOTONIC_CLOCK
   struct timespec tp;
   if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
       return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
#endif

   X_GETTIMEOFDAY(&tv);
   return(tv.tv_sec * 1000) + (tv.tv_usec / 1000);
}

May be on desktop  we use clock_gettime, on arm we use gettimeofday.

But when we change the time , both will change? isn't it?

Is this glibc problem? or a kernel problem?(rtc?)

Appreciate any  help from you .

Thanks

Best regards

ailantian



More information about the xorg mailing list