Discussion:
silly question: 1.x to 2.x event_add behavior
(too old to reply)
Denis Hainsworth
2014-04-30 12:24:23 UTC
Permalink
Raw Message
I have question I'm hoping will short-cut an investigation I'm doing
into some inherited code. Essentially we have some real simple code
which sets up an event with a timer and depending on certain things
changes the timer during each loop. We are seeing a difference in
behavior from when it was using 1.x libevent and 2.x.

We call event_set at the start of the code for 60 seconds, and then
during each loop use event_add to set the timer to however many seconds
from current time to get to the next minute. Its pretty dumb code and
there are lots of things wrong with it but it has been working.

We recently noticed that after upgrade to libevent 2.x as well as many
other things it appears that changing the timout via event_add doesn't
reset the current timer. I did some quick looking for bug reports and
in the manuals and I couldnt find any indication that the libevent code
had changed but I also couldnt confirm which is the correct behavior.

1.x - call event_add with a timeout and the next callback seems to be
exactly timeout time from the time we called event_add

2.x - call event_add with a timeout and the next callback seems to be
exactly timeout time from the beginning of the current loop, as if the
timeout is being properly set but the current timer is not being reset
when before it seemed to be.

I will note we are still using event_set with 2.x even though its
deprecated. So I was curious if anyone could say "duh" this is becuase
you are using event_set, or this is because there is a known bug that
was fixed in 2.x.x, or there was a change with this function somewhere
along the line. At the very least I was hoping someone could confirm
what the behavior we should be expecting when calling event_add.

Sorry for the bother, but any advice would be much appreciated as this
is inherited code it may take a while to unravel the original author's
intent.

-denis
--
__________________________
Denis Alan Hainsworth
***@alumni.brandeis.edu
***********************************************************************
To unsubscribe, send an e-mail to ***@freehaven.net with
unsubscribe libevent-users in the body.
Nick Mathewson
2014-04-30 12:44:24 UTC
Permalink
Raw Message
On Wed, Apr 30, 2014 at 8:24 AM, Denis Hainsworth
Post by Denis Hainsworth
I have question I'm hoping will short-cut an investigation I'm doing
into some inherited code. Essentially we have some real simple code
which sets up an event with a timer and depending on certain things
changes the timer during each loop. We are seeing a difference in
behavior from when it was using 1.x libevent and 2.x.
We call event_set at the start of the code for 60 seconds, and then
during each loop use event_add to set the timer to however many seconds
from current time to get to the next minute. Its pretty dumb code and
there are lots of things wrong with it but it has been working.
I think you might be mixing something up here; event_set() doesn't set
timeouts; that's in event_add().

event_add(), on the other hand, doesn't change callbacks.

It's not supported to call event_set() on an event that is currently
pending, and it wasn't supported in Libevent 1.x either -- most
programs that do that will get mysterious crashes as the internal data
structures get corrupted. It's like using free()d memory -- some
programs will get away with it, and some programs won't, but it's a
bug either way.

If you need to call event_set() on an event that might be pending, you
need to call event_del(), then event_set(), then event_add() again.
That's necessary for correctness with Libevent 1.x and 2.x as well.

My apologies if I haven't understood the situation, though; if you
could post a tiny code sample demonstrating the behavior you're
talking about, that would probably help track down the issue.

best wishes,
--
Nick
***********************************************************************
To unsubscribe, send an e-mail to ***@freehaven.net with
unsubscribe libevent-users in the body.
Denis Hainsworth
2014-04-30 13:28:52 UTC
Permalink
Raw Message
Post by Nick Mathewson
On Wed, Apr 30, 2014 at 8:24 AM, Denis Hainsworth
Post by Denis Hainsworth
I have question I'm hoping will short-cut an investigation I'm doing
into some inherited code. Essentially we have some real simple code
which sets up an event with a timer and depending on certain things
changes the timer during each loop. We are seeing a difference in
behavior from when it was using 1.x libevent and 2.x.
We call event_set at the start of the code for 60 seconds, and then
during each loop use event_add to set the timer to however many seconds
from current time to get to the next minute. Its pretty dumb code and
there are lots of things wrong with it but it has been working.
I think you might be mixing something up here; event_set() doesn't set
timeouts; that's in event_add().
event_add(), on the other hand, doesn't change callbacks.
It's not supported to call event_set() on an event that is currently
pending, and it wasn't supported in Libevent 1.x either -- most
programs that do that will get mysterious crashes as the internal data
structures get corrupted. It's like using free()d memory -- some
programs will get away with it, and some programs won't, but it's a
bug either way.
If you need to call event_set() on an event that might be pending, you
need to call event_del(), then event_set(), then event_add() again.
That's necessary for correctness with Libevent 1.x and 2.x as well.
My apologies if I haven't understood the situation, though; if you
could post a tiny code sample demonstrating the behavior you're
talking about, that would probably help track down the issue.
Thanks Nick, I was trying to keep the question simple as there are a
number of extra complexities we are dealing with like that there is a
python layer in between libevent and the script. All I need to know
right now is when event_add is called on an existing event to change the
timer (which is a valid thing to do per the documentation) should that
mean the new timeout X is X seconds from when event_add was called or
should it be X seconds from the beginning of the current callback.

If we know that then we can focus our efforts on which behavior seems
broken or if this is a known change that the folks that upgraded
libevent missed.

-denis
***********************************************************************
To unsubscribe, send an e-mail to ***@freehaven.net with
unsubscribe libevent-users in the body.
Nick Mathewson
2014-04-30 21:28:01 UTC
Permalink
Raw Message
On Wed, Apr 30, 2014 at 9:28 AM, Denis Hainsworth
Post by Denis Hainsworth
Post by Nick Mathewson
On Wed, Apr 30, 2014 at 8:24 AM, Denis Hainsworth
Post by Denis Hainsworth
I have question I'm hoping will short-cut an investigation I'm doing
into some inherited code. Essentially we have some real simple code
which sets up an event with a timer and depending on certain things
changes the timer during each loop. We are seeing a difference in
behavior from when it was using 1.x libevent and 2.x.
We call event_set at the start of the code for 60 seconds, and then
during each loop use event_add to set the timer to however many seconds
from current time to get to the next minute. Its pretty dumb code and
there are lots of things wrong with it but it has been working.
I think you might be mixing something up here; event_set() doesn't set
timeouts; that's in event_add().
event_add(), on the other hand, doesn't change callbacks.
It's not supported to call event_set() on an event that is currently
pending, and it wasn't supported in Libevent 1.x either -- most
programs that do that will get mysterious crashes as the internal data
structures get corrupted. It's like using free()d memory -- some
programs will get away with it, and some programs won't, but it's a
bug either way.
If you need to call event_set() on an event that might be pending, you
need to call event_del(), then event_set(), then event_add() again.
That's necessary for correctness with Libevent 1.x and 2.x as well.
My apologies if I haven't understood the situation, though; if you
could post a tiny code sample demonstrating the behavior you're
talking about, that would probably help track down the issue.
Thanks Nick, I was trying to keep the question simple as there are a
number of extra complexities we are dealing with like that there is a
python layer in between libevent and the script. All I need to know
right now is when event_add is called on an existing event to change the
timer (which is a valid thing to do per the documentation) should that
mean the new timeout X is X seconds from when event_add was called or
should it be X seconds from the beginning of the current callback.
The semantics are that it the event should be executed X seconds from
when (approximately[*]) when event_add() was called. I believe these
were the semantics in Libevent 1 and Libevent 2 both.

[*] You should probably also be aware that Libevent 1 and Libevent 2,
by default, tried to minimize calls to clock_gettime(); see the
gettime() function for more info on that. You can control this
behavior in Libevent 2 by using EVENT_BASE_FLAG_NO_CACHE_TIME.

You should probably know that there are new semantics for EV_PERSIST
events with timeouts in Libevent 2.0; previously, there was no defined
meaning to an event timeout on an EV_PERSIST event. In Libevent, it
was defined as creating a periodic event.

hope this helps,
--
Nick
***********************************************************************
To unsubscribe, send an e-mail to ***@freehaven.net with
unsubscribe libevent-users in the body.
Denis Hainsworth
2014-05-01 01:18:54 UTC
Permalink
Raw Message
Post by Nick Mathewson
hope this helps,
Thanks Nick. Its great to get a doublecheck on what we were thinking.
Much appreciated. Hopefully it won't take us much longer to figure out
what the heck is going on :)

-denis
***********************************************************************
To unsubscribe, send an e-mail to ***@freehaven.net with
unsubscribe libevent-users in the body.
Denis Hainsworth
2014-06-16 23:31:20 UTC
Permalink
Raw Message
Post by Nick Mathewson
On Wed, Apr 30, 2014 at 9:28 AM, Denis Hainsworth
Post by Denis Hainsworth
Post by Nick Mathewson
On Wed, Apr 30, 2014 at 8:24 AM, Denis Hainsworth
Post by Denis Hainsworth
I have question I'm hoping will short-cut an investigation I'm doing
into some inherited code. Essentially we have some real simple code
which sets up an event with a timer and depending on certain things
changes the timer during each loop. We are seeing a difference in
behavior from when it was using 1.x libevent and 2.x.
We call event_set at the start of the code for 60 seconds, and then
during each loop use event_add to set the timer to however many seconds
from current time to get to the next minute. Its pretty dumb code and
there are lots of things wrong with it but it has been working.
I think you might be mixing something up here; event_set() doesn't set
timeouts; that's in event_add().
event_add(), on the other hand, doesn't change callbacks.
It's not supported to call event_set() on an event that is currently
pending, and it wasn't supported in Libevent 1.x either -- most
programs that do that will get mysterious crashes as the internal data
structures get corrupted. It's like using free()d memory -- some
programs will get away with it, and some programs won't, but it's a
bug either way.
If you need to call event_set() on an event that might be pending, you
need to call event_del(), then event_set(), then event_add() again.
That's necessary for correctness with Libevent 1.x and 2.x as well.
My apologies if I haven't understood the situation, though; if you
could post a tiny code sample demonstrating the behavior you're
talking about, that would probably help track down the issue.
Thanks Nick, I was trying to keep the question simple as there are a
number of extra complexities we are dealing with like that there is a
python layer in between libevent and the script. All I need to know
right now is when event_add is called on an existing event to change the
timer (which is a valid thing to do per the documentation) should that
mean the new timeout X is X seconds from when event_add was called or
should it be X seconds from the beginning of the current callback.
The semantics are that it the event should be executed X seconds from
when (approximately[*]) when event_add() was called. I believe these
were the semantics in Libevent 1 and Libevent 2 both.
[*] You should probably also be aware that Libevent 1 and Libevent 2,
by default, tried to minimize calls to clock_gettime(); see the
gettime() function for more info on that. You can control this
behavior in Libevent 2 by using EVENT_BASE_FLAG_NO_CACHE_TIME.
You should probably know that there are new semantics for EV_PERSIST
events with timeouts in Libevent 2.0; previously, there was no defined
meaning to an event timeout on an EV_PERSIST event. In Libevent, it
was defined as creating a periodic event.
Hi Nick,
Just wanted to close the loop on this. Smarter people than I looked
into the libevent code and confirmed what you seemed to have figured
out above. It appears the change in behavior was in fact due to the
deprecation of the calls we are using to be a shim layer over the new
libevent2 calls and the possible further minimization of calls to
clock_gettime() such that when we were calling event_add the last call
to clock_gettime() was not right then during the event_add call. It
looks like EVENT_BASE_FLAG_NO_CACHE_TIME may do what we need. The more
proper coversion to libevent2 call is tech debt we can't pay off right
now :)

Thanks for the replies, hope this helps someone else hitting similar
oddness after conversion. It was a subtle change and has so far only
really shown up in functions we needed very precise timers for.

-denis
***********************************************************************
To unsubscribe, send an e-mail to ***@freehaven.net with
unsubscribe libevent-users in the body.

Loading...