Skip to content
This repository was archived by the owner on Feb 26, 2022. It is now read-only.

Timer::stop returns TIMER_NOT_AN_EVENT when timer was stopped #5

Closed
wants to merge 1 commit into from

Conversation

thomo
Copy link
Contributor

@thomo thomo commented Nov 2, 2013

When Timer::stop returns TIMER_NOT_AN_EVENT when a timer was stopped it is more easy to invalidate a timer ID variable.
tmr = t.stop(tmr);

Otherwise some side effect may happen especially when you use more than one timer, e.g.:
t1 = t.every(200, foo);
t.stop(t1);
....
t2 = t.every(100, bar);
t.stop(t1); // for some reason you call stop(t1) here again

may result in stopping t2 if t1 is not invalidated

@JChristensen
Copy link
Owner

I'm not understanding the issue here. Can you provide a complete example that demonstrates it? I don't understand the statement, "MAY result in stopping t2 if t1 is not invalidated" -- under what specific circumstances DOES stopping t2 occur?

With the current code, if stop() is called twice on the same ID, it will simply set eventType to EVENT_NONE a second time for that ID. There is no harm in this, I do not see how it would be possible that a different timer would be stopped instead.

@thomo
Copy link
Contributor Author

thomo commented Nov 2, 2013

Ok, I will try to explain it better.

Let's assume you observe two events and switch on a corresponding LED when an event occur. After a timeout the led should be switched off - if inbetween the event reoccurs then the timeout is reset.

void restartT1() {
    t.stop(t1);
    t1 = t.after(1000, ledA_off);
    ledA_on();
}

void restartT2() {
    t.stop(t2);
    t2 = t.after(1000, ledB_off);
    ledB_on();
}

void stopTimer() {
    t.stop(t1);
    t.stop(t2);
}

...

void loop() {
    if eventA {
        restartT1();
    }

    if eventB {
      restartT2();
    }

    if eventC {
        stopTimer();
    }
}

Lets look what happend:

Time | Event | t1     | t2     | desc
0    | -     | -1     | -1     | -
1    | A     | 0      | -1     | start t1 (ID=0)
...                            
10   | B     | 0      | 1      | start t2 (ID=0)
...                            
100  | C     | 0      | 1      | stop t1 and t2
...
300  | B     | 0      | 1 -> 0 | start t2 - new ID (!)
400  | A     | 0 -> 1 | 0      | stop(0) - will stop t2 (!), new t1 ID (!), start t1 

Note: If you initialize t1 and t2 with 0 - the issue already occur at t=10

When t.stop(tmr) returns a "INVALIDATION ID" it may help in the example above.

But while writing down this I realize that if the timer timed out in the normal way, the IDs will also not invalidated. So I wonder if it would not better to not use the array idx as timer ID but add a field ID to Event and store there a generated ID.

@JChristensen
Copy link
Owner

Thanks for the additional explanation, I'm with you now. My first reaction was that the calling program failed to properly maintain the state of its timer variables t1 and t2. On the other hand I can definitely see how the proposed change facilitates doing just that.

Is the intent to implement a retriggerable timer? That is, if the timer is already running, and another input event occurs, then the timer duration is elongated by the original amount.

g19fanatic pushed a commit to g19fanatic/Timer that referenced this pull request Apr 3, 2015
…en a valid timer event ID. Given an invalid (out of bounds) ID, it simply returns the same ID that it was given.

Converted the ReadMe file to Markdown, added examples, reference, etc. from Dr. Monk's site.
Minor cosmetic editing, tabs to spaces.
Closes JChristensen#5.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants