| @@ -2523,70 +2523,101 @@ SyncInitServerTime(void) | | | @@ -2523,70 +2523,101 @@ SyncInitServerTime(void) |
2523 | XSyncIntToValue(&resolution, 4); | | 2523 | XSyncIntToValue(&resolution, 4); |
2524 | ServertimeCounter = SyncCreateSystemCounter("SERVERTIME", Now, resolution, | | 2524 | ServertimeCounter = SyncCreateSystemCounter("SERVERTIME", Now, resolution, |
2525 | XSyncCounterNeverDecreases, | | 2525 | XSyncCounterNeverDecreases, |
2526 | ServertimeQueryValue, ServertimeBracketValues); | | 2526 | ServertimeQueryValue, ServertimeBracketValues); |
2527 | pnext_time = NULL; | | 2527 | pnext_time = NULL; |
2528 | } | | 2528 | } |
2529 | | | 2529 | |
2530 | | | 2530 | |
2531 | | | 2531 | |
2532 | /* | | 2532 | /* |
2533 | * IDLETIME implementation | | 2533 | * IDLETIME implementation |
2534 | */ | | 2534 | */ |
2535 | | | 2535 | |
2536 | static pointer IdleTimeCounter; | | 2536 | static SyncCounter *IdleTimeCounter; |
2537 | static XSyncValue *pIdleTimeValueLess; | | 2537 | static XSyncValue *pIdleTimeValueLess; |
2538 | static XSyncValue *pIdleTimeValueGreater; | | 2538 | static XSyncValue *pIdleTimeValueGreater; |
2539 | | | 2539 | |
2540 | static void | | 2540 | static void |
2541 | IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return) | | 2541 | IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return) |
2542 | { | | 2542 | { |
2543 | CARD32 idle = GetTimeInMillis() - lastDeviceEventTime.milliseconds; | | 2543 | CARD32 idle = GetTimeInMillis() - lastDeviceEventTime.milliseconds; |
2544 | XSyncIntsToValue (pValue_return, idle, 0); | | 2544 | XSyncIntsToValue (pValue_return, idle, 0); |
2545 | } | | 2545 | } |
2546 | | | 2546 | |
2547 | static void | | 2547 | static void |
2548 | IdleTimeBlockHandler (pointer env, | | 2548 | IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) |
2549 | struct timeval **wt, | | | |
2550 | pointer LastSelectMask) | | | |
2551 | { | | 2549 | { |
2552 | XSyncValue idle; | | 2550 | XSyncValue idle, old_idle; |
| | | 2551 | SyncTriggerList *list = IdleTimeCounter->pTriglist; |
| | | 2552 | SyncTrigger *trig; |
2553 | | | 2553 | |
2554 | if (!pIdleTimeValueLess && !pIdleTimeValueGreater) | | 2554 | if (!pIdleTimeValueLess && !pIdleTimeValueGreater) |
2555 | return; | | 2555 | return; |
2556 | | | 2556 | |
| | | 2557 | old_idle = IdleTimeCounter->value; |
2557 | IdleTimeQueryValue (NULL, &idle); | | 2558 | IdleTimeQueryValue (NULL, &idle); |
| | | 2559 | IdleTimeCounter->value = idle; /* push, so CheckTrigger works */ |
2558 | | | 2560 | |
2559 | if (pIdleTimeValueLess && | | 2561 | if (pIdleTimeValueLess && |
2560 | XSyncValueLessOrEqual (idle, *pIdleTimeValueLess)) | | 2562 | XSyncValueLessOrEqual (idle, *pIdleTimeValueLess)) |
2561 | { | | 2563 | { |
2562 | AdjustWaitForDelay (wt, 0); | | 2564 | /* |
| | | 2565 | * We've been idle for less than the threshold value, and someone |
| | | 2566 | * wants to know about that, but now we need to know whether they |
| | | 2567 | * want level or edge trigger. Check the trigger list against the |
| | | 2568 | * current idle time, and if any succeed, bomb out of select() |
| | | 2569 | * immediately so we can reschedule. |
| | | 2570 | */ |
| | | 2571 | |
| | | 2572 | for (list = IdleTimeCounter->pTriglist; list; list = list->next) { |
| | | 2573 | trig = list->pTrigger; |
| | | 2574 | if (trig->CheckTrigger(trig, old_idle)) { |
| | | 2575 | AdjustWaitForDelay(wt, 0); |
| | | 2576 | break; |
| | | 2577 | } |
| | | 2578 | } |
2563 | } | | 2579 | } |
2564 | else if (pIdleTimeValueGreater) | | 2580 | else if (pIdleTimeValueGreater) |
2565 | { | | 2581 | { |
2566 | unsigned long timeout = 0; | | 2582 | /* |
| | | 2583 | * There's a threshold in the positive direction. If we've been |
| | | 2584 | * idle less than it, schedule a wakeup for sometime in the future. |
| | | 2585 | * If we've been idle more than it, and someone wants to know about |
| | | 2586 | * that level-triggered, schedule an immediate wakeup. |
| | | 2587 | */ |
| | | 2588 | unsigned long timeout = -1; |
2567 | | | 2589 | |
2568 | if (XSyncValueLessThan (idle, *pIdleTimeValueGreater)) | | 2590 | if (XSyncValueLessThan (idle, *pIdleTimeValueGreater)) { |
2569 | { | | | |
2570 | XSyncValue value; | | 2591 | XSyncValue value; |
2571 | Bool overflow; | | 2592 | Bool overflow; |
2572 | | | 2593 | |
2573 | XSyncValueSubtract (&value, *pIdleTimeValueGreater, | | 2594 | XSyncValueSubtract (&value, *pIdleTimeValueGreater, |
2574 | idle, &overflow); | | 2595 | idle, &overflow); |
2575 | timeout = XSyncValueLow32 (value); | | 2596 | timeout = min(timeout, XSyncValueLow32 (value)); |
| | | 2597 | } else { |
| | | 2598 | for (list = IdleTimeCounter->pTriglist; list; list = list->next) { |
| | | 2599 | trig = list->pTrigger; |
| | | 2600 | if (trig->CheckTrigger(trig, old_idle)) { |
| | | 2601 | timeout = min(timeout, 0); |
| | | 2602 | break; |
| | | 2603 | } |
| | | 2604 | } |
2576 | } | | 2605 | } |
2577 | | | 2606 | |
2578 | AdjustWaitForDelay (wt, timeout); | | 2607 | AdjustWaitForDelay (wt, timeout); |
2579 | } | | 2608 | } |
| | | 2609 | |
| | | 2610 | IdleTimeCounter->value = old_idle; /* pop */ |
2580 | } | | 2611 | } |
2581 | | | 2612 | |
2582 | static void | | 2613 | static void |
2583 | IdleTimeWakeupHandler (pointer env, | | 2614 | IdleTimeWakeupHandler (pointer env, |
2584 | int rc, | | 2615 | int rc, |
2585 | pointer LastSelectMask) | | 2616 | pointer LastSelectMask) |
2586 | { | | 2617 | { |
2587 | XSyncValue idle; | | 2618 | XSyncValue idle; |
2588 | | | 2619 | |
2589 | if (!pIdleTimeValueLess && !pIdleTimeValueGreater) | | 2620 | if (!pIdleTimeValueLess && !pIdleTimeValueGreater) |
2590 | return; | | 2621 | return; |
2591 | | | 2622 | |
2592 | IdleTimeQueryValue (NULL, &idle); | | 2623 | IdleTimeQueryValue (NULL, &idle); |