2014-09-10 5 views
0

Я реализовал таймер простоя на ресурсе (классе), экземпляры которого могут быть открыты сразу в нескольких приложениях. Следовательно, idleTimer - это не только простой QTimer, но слот (триггер) должен проверить, не обращались ли другие приложения к тем же ресурсам в течение последних N минут. Если это так, таймер сбрасывается (без обновления значения lastAccessedTime), иначе ресурс будет закрыт. Таким образом, таймер является однократным, а lastAccessTime хранится в объекте QSharedMemory.singleclhot QTimer на OS X быстрых огней несколько раз и слишком рано

Вот некоторые Трассировочная:

### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83601 timer QTimer(0x11d273d60) triggered 1 times 
### slotIdleTimedOut ->handleIdleTiming: setting QTimer(0x11d273d60) for wallet "kdewallet" handle 0 timeout to 6 
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ;  elapsed minutes= 5.83634 timer QTimer(0x11d273d60) triggered 2 times 
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83634 timer QTimer(0x11d273d60) triggered 3 times 
### "Google Contacts()of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83634 timer QTimer(0x11d273d60) triggered 4 times 
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83634 timer QTimer(0x11d273d60) triggered 5 times 
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83635 timer QTimer(0x11d273d60) triggered 6 times 
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ;  elapsed minutes= 5.83635 timer QTimer(0x11d273d60) triggered 7 times 
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83635 timer QTimer(0x11d273d60) triggered 8 times 
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle 0 ; elapsed minutes= 6 timer QTimer(0x120a1b5f0) triggered 1 times 
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00008 timer QObject(0x0) triggered 2 times 
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00009 timer QObject(0x0) triggered 3 times 
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00012 timer QObject(0x0) triggered 4 times 
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00012 timer QObject(0x0) triggered 5 times 
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00012 timer QObject(0x0) triggered 6 times 
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00012 timer QObject(0x0) triggered 7 times 
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00012 timer QObject(0x0) triggered 8 times 

Принцип работы, но я заметил 2 вещи:

  • таймер срабатывает рановато. Конечно, это приводит к сбросу таймера.
  • это пожары несколько раз в быстрой последовательности. Тот факт, что ранний огонь должен сбросить его, не имеет ни малейшего эффекта.

Ниже приведена соответствующая часть моего кода, включая функцию, которая сбрасывает таймер при каждом доступе к ресурсу и слот триггера таймера.

Любая идея, что я делаю неправильно? Я останавливаю таймер перед тем, как (re) установит его в режим singleleshot и начнет его (заново). Идентификаторы объектов и приложений показывают, что это действительно тот же самый таймер, который срабатывает несколько раз и что он может срабатывать даже после того, как я удалил объект таймера.

Возможно, слот триггера не является специфичным для приложения (или даже экземпляра), что приводит к тому, что один экземпляр получает триггерные сигналы idleTimer из всех других экземпляров в различных приложениях, которые устанавливают экземпляр этого таймера? idleTimer получает значение NULL только в деструкторе класса и/или когда timeOut равно < = 0, поэтому я зашел в тупик, что мой слот триггера может быть вызван с помощью объекта NULL timer!

С таймером установки функции (handleIdleTiming, член KWallet::Wallet как сам idleTimer):

// This function is to be called at every operation that is supposed to launch or reset 
// the idle timing. @p timeOut is a time in minutes. 
void handleIdleTiming(const char *caller="", bool touchAccessTime=true) 
{ 
    // ... 
    if(timeOut >= 0){ 
     if(!idleTimer){ 
      idleTimer = new QTimer(0); 
     } 
     else{ 
      idleTimer->stop(); 
     } 
     // when the idle timer fires, the wallet is supposed to be closed. There is thus 
     // no reason to use a repeating timer. 
     idleTimer->setSingleShot(true); 
     connect(idleTimer, SIGNAL(timeout()), q, SLOT(slotIdleTimedOut())); 
     if(touchAccessTime){ 
      if(lastAccessTime.lock()){ 
       *((double*)lastAccessTime.data()) = HRTime_Time(); 
       lastAccessTime.unlock(); 
      } 
      else{ 
       qDebug() << "Cannot lock lastAccessTime for wallet" << name << "error" << lastAccessTime.errorString(); 
      } 
     } 
     idleTimer->start(timeOut * 60 * 1000); 

Спусковой таймер слот:

void Wallet::slotIdleTimedOut() 
{ double lastAccessTime = 0; 
    // check the last time anyone accessed this wallet: 
    if(d->lastAccessTime.lock()){ 
     lastAccessTime = *((double*)d->lastAccessTime.data()); 
     d->lastAccessTime.unlock(); 
    } 
    else{ 
     qDebug() << "Cannot lock lastAccessTime for wallet" << d->name << "error" << d->lastAccessTime.errorString(); 
    } 
    // the time elapsed since that last access, in minutes: 
    double elapsed = (HRTime_Time() - lastAccessTime)/60; 
    d->idleTimerTriggered += 1; 
    qDebug() << "###" << appid() << "Idle timeout" << d->timeOut << "min. for" << this << d->name << "handle" << d->handle 
     << "; elapsed minutes=" << elapsed << "timer" << d->idleTimer << "triggered" << d->idleTimerTriggered << "times"; 
    if(elapsed >= d->timeOut){ 
     // we have a true timeout, i.e. we didn't access the wallet in timeOut minutes, and no one else did either. 
     slotWalletClosed(d->handle); 
    } 
    else{ 
     // false alarm, reset the timer, but there's no need to count this as an access! 
     d->handleIdleTiming(__FUNCTION__, false); 
    } 
} 
+0

Может ли это быть потому, что я вызываю connect() (потенциально) несколько раз, а не один раз после 'new QTimer (0)'? – RJVB

ответ

0

действительно должны быть, потому что я издал connect каждый раз при сбросе таймера, а не только после его создания.

 Смежные вопросы

  • Нет связанных вопросов^_^