mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Jan 2004
Posts: 2,127
maroon Offline OP
Hoopy frood
OP Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
Rarely, a timer executing immediately after timerNAME receives info from $timer(NAME) as well as info from $timer() .properties, even though timerNAME has already halted and will not execute again.

It's easier to reproduce when there are zero/few other timers active, but it does happen when other timers are active. I was able to frequently repeat this with 7.51 and the 7.51.212 beta using this alias:

Code:
alias timertest {
  var %delay $iif($1,$1,5)
  timerA %2 1 %delay echo -a $!ticks A sees A: secs $!timer(A).secs reps $!timer(A).reps sees B: secs $!timer(B).secs reps $!timer(B).reps A= $!timer(A)
  timerB %2 1 %delay echo -a $!ticks B sees A: secs $!timer(A).secs reps $!timer(A).reps sees B: secs $!timer(B).secs reps $!timer(B).reps A= $!timer(A)
  timerC %2 1 %delay echo -a $!ticks C sees A: secs $!timer(A).secs reps $!timer(A).reps sees B: secs $!timer(B).secs reps $!timer(B).reps A= $!timer(A)
  echo -a $ticks start | timer
  ; $(|) timerA off
  ; $(|) timerA -e
}


I disabled all my timers and generated the text quoted below with "/timertest". The 3 timers launch with an expected trigger 5 seconds later, always in this same ABC order. You can optionally provide the number of seconds to 3 by doing "/timertest 3" and can test the -m switch like "/timertest 5000 -m".

While no other timers are running it might be a little easier to get these timers to trigger during the same ticks value, but I've often been able to replicate with multiple 0-rep timers repeating each second. The output can looks like this:

Quote:

* Timer a activated
* Timer b activated
* Timer c activated
801197563 start
* Active timers:
* Timer a 1 time(s) 5s delay echo -a $ticks A sees A: secs $timer(A).secs reps $timer(A).reps sees B: secs $timer(B).secs reps $timer(B).reps A= $timer(A)
* Timer b 1 time(s) 5s delay echo -a $ticks B sees A: secs $timer(A).secs reps $timer(A).reps sees B: secs $timer(B).secs reps $timer(B).reps A= $timer(A)
* Timer c 1 time(s) 5s delay echo -a $ticks C sees A: secs $timer(A).secs reps $timer(A).reps sees B: secs $timer(B).secs reps $timer(B).reps A= $timer(A)
801202555 A sees A: secs 4 reps 0 sees B: secs 0 reps 1 A= 1
* Timer a halted
801202570 B sees A: secs 4 reps 0 sees B: secs 4 reps 0 A= 1
* Timer b halted
801202570 C sees A: secs 4 reps 0 sees B: secs 4 reps 0 A= 1
* Timer c halted


The main point of the bug is that TimerB and TimerC both see $timer(A) existing after TimerA has finished its only execution and displayed the message that it already halted, and TimerC also sees information about TimerB after it has halted too.

The above example showed it also happening with slightly non-matching ticks values. Usually, when the ticks value differing by such small values, timers lagging by 15ms or so sees no info about the halted timer, but always showed the info if the ticks matched. However when I played an .mp3 the timers lagging by a few ticks often showed the info about the halted timers as quoted above, and continued doing so after the .mp3 ended.

The "timer" command displaying the active timers confirms they are displaying $timer() values evaluated when the timer triggers 5 seconds later, not values evaluated at launch time. The 'timer' command can be removed to simplify the display.

A script running from a timer other than timerA expects that seeing $timer(A).reps of 0 means timerA was created with repetitions 0 and will repeatedly execute until halted, because that's the only time any outside timerA itself should see .reps being 0.

In case the following quirks help identify the source of this behavior:

* If the string " $(|) timerA off" is appended to the end of TimerA (telling it to halt itself), it has no effect on TimerA's info continuing to be seen by the other timers after it has halted, and doesn't generate an additional halt message.

* If the " $(|) timerA -e" string is appended to the end of TimerB, when TimerB is in a situation that it sees TimerA existing after it halted, "/timerA -e" is able to trigger TimerA again. After TimerB displays its message showing the halted TimerA existing with .reps 0, TimerA repeats its display showing identical info about itself, differing from its earlier message only in the updated info about TimerB. Following is an additional "* Timer a halted" message. This execution of a halted TimerA always pushes TimerC into a condition where it doesn't show info about TimerA existing.

In case it matters, this is happening on Win7-32.

Joined: Dec 2002
Posts: 5,421
Hoopy frood
Offline
Hoopy frood
Joined: Dec 2002
Posts: 5,421
Thanks for your bug report. The reason for this is that the timers are being processed at the same interval. For various reasons, timers cannot be freed until the end of an interval. This means that if they halt, they can still be referenced during that interval by other timers. This cannot be solved without a rewrite of the timer code, which is not planned at this time.


Link Copied to Clipboard