Re: How do I cancel a timer?
On Mon, Dec 15, 2008 at 06:34:10PM +0200, Graham Leggett wrote: > Can someone confirm first of all for me that ev_timer_stop is the > correct way to cancel a timer? Yes - are you sure you don't start it again, or modify it in illegal ways? > The docs make no mention of how you destroy a timer, only how you might > create one or reset one. Because destruction is on your side of the API - libev has no facilities to create or destroy timers, that's what the application does. The documentation mentions exactly, however, when you can safely reuse the watcher structure for something else, which is what you seem to want. But remember, creation and destruction _for watchers_ is completely outside the libev API, only _event loops_ can be created and destructed. -- The choice of a Deliantra, the free code+content MORPG -==- _GNU_ http://www.deliantra.net ==-- _ generation ---==---(_)__ __ __ Marc Lehmann --==---/ / _ \/ // /\ \/ / p...@goof.com -=/_/_//_/\_,_/ /_/\_\ ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
Marc Lehmann wrote: On Mon, Dec 15, 2008 at 06:34:10PM +0200, Graham Leggett wrote: Can someone confirm first of all for me that ev_timer_stop is the correct way to cancel a timer? Yes - are you sure you don't start it again, or modify it in illegal ways? What I found I had done was initialised the timer twice. It seems that when this happens you have to stop the timer twice, or a single stop of the timer isn't effective. The docs make no mention of how you destroy a timer, only how you might create one or reset one. Because destruction is on your side of the API - libev has no facilities to create or destroy timers, that's what the application does. The documentation mentions exactly, however, when you can safely reuse the watcher structure for something else, which is what you seem to want. But remember, creation and destruction _for watchers_ is completely outside the libev API, only _event loops_ can be created and destructed. What I meant by "destroy a timer" is "make sure this callback is never executed, because the memory beneath this is about to be freed". At the moment, I am using ev_timer_stop() for this, and as long as I don't initialise the same timer twice, it seems to work. Regards, Graham -- smime.p7s Description: S/MIME Cryptographic Signature ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
On Tue, Dec 16, 2008 at 01:11:24PM +0200, Graham Leggett wrote: > What I found I had done was initialised the timer twice. It seems that You can initialise the timer as many times as you want, as long as it isn't started. Although this is completely obvious (when you start a timer, obviously you can't just reinitialise the memory it uses), this is also mentioned very strongly in the manual. > when this happens you have to stop the timer twice, or a single stop of > the timer isn't effective. No, you simply have a bug in that case - you must not wipe out data structures that are in use, obviously. >> But remember, creation and destruction _for watchers_ is completely >> outside the libev API, only _event loops_ can be created and destructed. > > What I meant by "destroy a timer" is "make sure this callback is never > executed, because the memory beneath this is about to be freed". stopping it, as documented, will do that. > At the moment, I am using ev_timer_stop() for this, and as long as I > don't initialise the same timer twice, it seems to work. you can initialise the timer as many times as you want. you should find the bug in your code where you initialise a *running* timer again, which of course overwrites the data structures that are already in use. -- The choice of a Deliantra, the free code+content MORPG -==- _GNU_ http://www.deliantra.net ==-- _ generation ---==---(_)__ __ __ Marc Lehmann --==---/ / _ \/ // /\ \/ / p...@goof.com -=/_/_//_/\_,_/ /_/\_\ ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
Marc Lehmann wrote: You can initialise the timer as many times as you want, as long as it isn't started. Although this is completely obvious (when you start a timer, obviously you can't just reinitialise the memory it uses), this is also mentioned very strongly in the manual. I don't see anything obvious about this at all. If a timer that has been started is reinitialised, I would expect it to either a) abort/assert with an error, or b) remove the first timer cleanly before reinitialising it. Right now the behaviour is that the timer stop is ignored, and that is looks broken to me. Regards, Graham -- smime.p7s Description: S/MIME Cryptographic Signature ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
On Wed, Dec 17, 2008 at 01:02:07PM +0200, Graham Leggett wrote: > If a timer that has been started is reinitialised, I would expect it to > either a) abort/assert with an error, or b) remove the first timer > cleanly before reinitialising it. You better adjust your expectations quickly, as you will run into the same problem with about any other software. The problem with your expectation is that it cannot be done, at all: To do what you want one would have to rely on the _existing_ contents of the memory area, i.e. it has to be _initialised_ already to some known values. That's a hen and egg problem: to initialise some memory area, you cannot rely on it. If you want to rely on it, you have to initialise it first, presumably with... an initialisation function that doesn't rely on its contents! :) The only way around that would be another checking layer, much like a memory checker, that checked your initialisation request for validity, by having a shadow data structure to check against, which is obviously not sensible. > Right now the behaviour is that the timer stop is ignored, and that is > looks broken to me. Well, so trust somebody with experience: your expectation is bogus, just think about how you would implement that and it should become all clear. -- The choice of a Deliantra, the free code+content MORPG -==- _GNU_ http://www.deliantra.net ==-- _ generation ---==---(_)__ __ __ Marc Lehmann --==---/ / _ \/ // /\ \/ / p...@goof.com -=/_/_//_/\_,_/ /_/\_\ ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
Marc Lehmann wrote: You better adjust your expectations quickly, as you will run into the same problem with about any other software. The problem with your expectation is that it cannot be done, at all: To do what you want one would have to rely on the _existing_ contents of the memory area, i.e. it has to be _initialised_ already to some known values. This makes no sense. You initialised the area to known values, then you started the timer, then - by mistake - you initialised the already started timer again. Are you telling me that it cannot be detected that a timer has a) been initialised and b) started? Regards, Graham -- smime.p7s Description: S/MIME Cryptographic Signature ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
On Thu, Dec 18, 2008 at 07:09:19PM +0200, Graham Leggett wrote: > You initialised the area to known values, then you started the timer, > then - by mistake - you initialised the already started timer again. Well, that mistake is simply a bug - once you fix it, everything should work. > Are you telling me that it cannot be detected that a timer has a) been > initialised and b) started? Yes - It is also totally obvious, just think about it please: To detect whether a timer has been started or initialised, you either have to _look_ at the memory it uses (which could happen to have the exact bit pattern that indicates the timer is active, when it isn't, or worse, the program could just crash or even worse), or you have to record the address of the watcher in some extra data structure and check twice (which would be very slow). Libev wasn't meant as a teaching tool that double-checks the user or auto-corrects bugs, it's meant as a high-performance library that does what you tell it with minimal overhead. If you want double-checking, you could use a language better suited for learning, such as Perl: the Perl interface to libev (EV) actively checks for these cases (actually, perl does), as it manages initialisation for you (actually by not letting you initialise). In general, C is a difficult language, as it doesn't check your data (or your pointers) for validity, or tells you when you access iuninitialised memory etc. -- The choice of a Deliantra, the free code+content MORPG -==- _GNU_ http://www.deliantra.net ==-- _ generation ---==---(_)__ __ __ Marc Lehmann --==---/ / _ \/ // /\ \/ / p...@goof.com -=/_/_//_/\_,_/ /_/\_\ ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
Marc Lehmann wrote: If you want double-checking, you could use a language better suited for learning, such as Perl: the Perl interface to libev (EV) actively checks for these cases (actually, perl does), as it manages initialisation for you (actually by not letting you initialise). In general, C is a difficult language, as it doesn't check your data (or your pointers) for validity, or tells you when you access iuninitialised memory etc. This is so nineties, seriously :) C is not a difficult language at all, and it doesn't have to be. A well written well structured library should give the programmer assertions that the code is still sane, and when you are on a critical performance path, you should be able to make the assertions disappear using a #define. Performance means nothing whatsoever if the code is unreliable, and if your code doesn't help my code be reliable, a point is reached when the library collapses under it's own weight: man assert Regards, Graham -- smime.p7s Description: S/MIME Cryptographic Signature ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
Graham, libev is a performance-oriented library; since allocations can be a bottleneck and can be handled in many different ways, the library uses a common pattern and gives memory control to the user. Perhaps the user wants to allocate only a fixed number of watchers statically, perhaps they use a memory pool, or perhaps they just use malloc - all of these use cases are supported by ev_*_init. The mistake checking you want could be added with very much overhead (keeping a list of all the pointers initialized, and adding a ev_*_deinit function? putting a checksum in the structure?), but that would negate the point of giving user memory control in the first place. Also, no one needs it because it's clear from the outset that managing watcher memory is the user's job. If you had read the manual or looked at the source code you'd realize libev is filled with assertions. ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
ryah dahl wrote: The mistake checking you want could be added with very much overhead That's not necessarily true. Just have a signal byte at a known offset and require it to be 0 to do the initialisation, and the initialisationn will change the signal. This is low overhead on users and runtime - but it IS an API change. To say its not possible in general is wrong, though. And, to be honest, having an *optional*check that looks in memory and says 'if it looks initialised, then it IS in itialised' and accepts a probabilistic false positive, is also cheap and unlikely to be a problem in reality while catching a class of bug. (Though, you might want to increase the size of the structure slightly to have a magic flag - 64 bits or so perhaps). James ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
James Mansion wrote: ryah dahl wrote: The mistake checking you want could be added with very much overhead That's not necessarily true. Just have a signal byte at a known offset and require it to be 0 to do the initialisation, and the initialisationn will change the signal. This is low overhead on users and runtime - but it IS an API change. To say its not possible in general is wrong, though. And, to be honest, having an *optional*check that looks in memory and says 'if it looks initialised, then it IS in itialised' and accepts a probabilistic false positive, is also cheap and unlikely to be a problem in reality while catching a class of bug. (Though, you might want to increase the size of the structure slightly to have a magic flag - 64 bits or so perhaps). The problem with an initialization flag byte is this then requires that the memory being passed to the init function be zero-d (or at least, the flag byte within it be zero-d), whereas with the current simpler scheme, an application may be managing its own local pools of memory and reusing old chunks of memory without zeroing them before calling the initialization function. So again, there's a performance loss there of the application needing to zero the memory before each re-use for that scheme to work (not to mention failing to zero the memory before reuse, or zeroing the wrong thing before reusing the right one, is basically going to fall into the same class of application programming bug/mistake as the problem we're trying to avoid in the first place). ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
ryah dahl wrote: libev is a performance-oriented library; since allocations can be a bottleneck and can be handled in many different ways, the library uses a common pattern and gives memory control to the user. Perhaps the user wants to allocate only a fixed number of watchers statically, perhaps they use a memory pool, or perhaps they just use malloc - all of these use cases are supported by ev_*_init. The mistake checking you want could be added with very much overhead (keeping a list of all the pointers initialized, and adding a ev_*_deinit function? putting a checksum in the structure?), but that would negate the point of giving user memory control in the first place. Also, no one needs it because it's clear from the outset that managing watcher memory is the user's job. I am not following what memory allocation has to do with this problem? The problem that I am seeing is that if the same timer is initialised twice, an attempt to stop the timer does not cause the timer to stop. In theory, it shouldn't matter how many times you init the timer, a stop should stop it. Regards, Graham -- smime.p7s Description: S/MIME Cryptographic Signature ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
On Fri, Dec 19, 2008 at 01:52:30AM +0200, Graham Leggett wrote: > This is so nineties, seriously :) And you are starting to get needlessly insulting. > C is not a difficult language at all, and it doesn't have to be. Right, but you apparently make it one. > A well written well structured library should give the programmer > assertions that the code is still sane, libev is that and does just that - there are 45 assertions in the (relatively short) code that mostly check user input. > and when you are on a critical performance path, you should be able to > make the assertions disappear using a #define. That's the case with libev already. > Performance means nothing whatsoever if the code is unreliable, True, which is why you probably shouldn't write in C, as you have trouble understanding memory management and the rules of the C language regarding what acessess are valid and what aren't. > and if your code doesn't help my code be reliable, a point is reached > when the library collapses under it's own weight: Well, upo your ass, go elsewhere then, I won't help you anymore. > man assert man brain indeed - that proves your absolute incompetence. next time you make stupid statements such as that, you are well advised to actually *read* the code you are talking about. *plonk* -- The choice of a Deliantra, the free code+content MORPG -==- _GNU_ http://www.deliantra.net ==-- _ generation ---==---(_)__ __ __ Marc Lehmann --==---/ / _ \/ // /\ \/ / p...@goof.com -=/_/_//_/\_,_/ /_/\_\ ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
On Fri, Dec 19, 2008 at 06:12:51AM +, James Mansion wrote: > That's not necessarily true. Just have a signal byte at a known offset First of all, please do other people a favour and don't send such horribly misformatted messages like yours. Remember that other people might want to read your e-mails, and making it needlessly hard for them is just pointless. > and require it to be 0 to > do the initialisation, and the initialisationn will change the signal. You are arguing in circles - requiring it to be zero means it needs ot be *initialised* first. So your argument boils down to: to avoid having to initialise the watcher seperately, you need to initialise it first. But that's exactly what the intialise function is for. > This is low overhead on users and runtime - but it IS an API change. To > say its not possible in general is wrong, though. It is also stupid - it would require *two* initialisation functions, one that sets that magic byte to zero, and one that, well, initialiases the rest of the structure. All you would gain would be more complexity. > And, to be honest, having an *optional*check that looks in memory and > says 'if it looks initialised, then it IS in itialised' and accepts a > probabilistic false positive, is also cheap and unlikely Unfortunately, such a check is not possible in C. In addition, it would be stupid - looking at some structure to see if it *might* be valid is the worst ting you can do (as opposed to looking at a structure to see if it *is* invalid, which is what libev does). > to be a problem in reality while catching a class of bug. (Though, you > might want to increase > the size of the structure slightly to have a magic flag - 64 bits or so > perhaps). Remember that this magic byte thing also requires another deinitialisation function that makes that memory reusable again, which you *need* to call before freeing the memory, so again, you would lose considerably. -- The choice of a Deliantra, the free code+content MORPG -==- _GNU_ http://www.deliantra.net ==-- _ generation ---==---(_)__ __ __ Marc Lehmann --==---/ / _ \/ // /\ \/ / p...@goof.com -=/_/_//_/\_,_/ /_/\_\ ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
Marc Lehmann wrote: And you are starting to get needlessly insulting. Well, upo your ass, go elsewhere then, I won't help you anymore. As you said, you are starting to get needlessly insulting. Can we keep focus on the problem at hand? Regards, Graham -- smime.p7s Description: S/MIME Cryptographic Signature ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
On Fri, Dec 19, 2008 at 01:00:53PM +0200, Graham Leggett wrote: > In theory, it shouldn't matter how many times you init the timer, a stop > should stop it. Unfortunately, the real world works diferently than your theory, and the designers and authors of libev opted to folow a theory that closely matches reality, which fortunately wasn't your theory, which turns out to be unreasonable to implement. -- The choice of a Deliantra, the free code+content MORPG -==- _GNU_ http://www.deliantra.net ==-- _ generation ---==---(_)__ __ __ Marc Lehmann --==---/ / _ \/ // /\ \/ / p...@goof.com -=/_/_//_/\_,_/ /_/\_\ ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
On Fri, Dec 19, 2008 at 06:19:37PM +0200, Graham Leggett wrote: >> Well, upo your ass, go elsewhere then, I won't help you anymore. > > As you said, you are starting to get needlessly insulting. Well, it was correct when I said it, it no longer is correct when you parrot it. > Can we keep focus on the problem at hand? Yes, that problem would be you. This list is a support, as opposed to a troll, forum, and you stretched my patience too thin. Good bye. -- The choice of a Deliantra, the free code+content MORPG -==- _GNU_ http://www.deliantra.net ==-- _ generation ---==---(_)__ __ __ Marc Lehmann --==---/ / _ \/ // /\ \/ / p...@goof.com -=/_/_//_/\_,_/ /_/\_\ ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
Brandon Black wrote: The problem with an initialization flag byte is this then requires that the memory being passed to the init function be zero-d (or at least, the flag byte within it be zero-d), Well, I'd question whether its a problem (certainly not from any performance perspective) but since it busts the API its not relevant in this case, clearly, because the design decision to have the multiple-init bug undetectable is effectively made. I'm just objecting to Mr Lehman's characteristically condescending and heavy-handed 'its not possible'. is basically going to fall into the same class of application programming bug/mistake as the problem we're trying to avoid in the first place). I don't think that's true at all. An API that refuses to work unless the user has fullfilled preconditions will tend to be overzealous rejecting calls, and will be more inconvenient, but I do think it will tend to have fewer errors. No API will be completely immune after all, particularly if you are going to *try* to think of ways that it *could* be subverted, rather than accept that the API lends itself to a reinit bug.. Personally I'd be hesitant about overoptimising in a library that is fundamentally about calling select in one way or another, and would have thought that a simple object pool would be adequate. All that's happened is that we've shifted the allocation somewhere else, and it will only actually be a saving if there's a zero-or-one-to-one relationship between timers and application entities. All the timer-centric systems I've worked with have had timers in the Controller in the overall MVC and held them to one side, so I suspect it may not be all that much of a cost unless you go for a really malloc-heavy approach with no pooling. ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
This is a bit of a pointless discussion. If you have a problem managing your memory, why don't you write your own wrapper. struct my_ev_watcher { int initialized; ev_timer timer; }; void my_ev_init_timer (struct my_ev_watcher * w) { if (w->initialized) return; //... initialize it } This code is very quickly thrown together to show a basic idea, it obviously won't work in its current form. ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
Space Ship Traveller wrote: This code is very quickly thrown together to show a basic idea, it obviously won't work in its current form. And you have fallen directly foul of the point that Marc made about that being unreliable. You have to ensure that 'initialized' is 0 before the first call (and reset during the tear-down). ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
That part was left as an exercise for the reader I thought it was fairly obvious the pitfalls of this approach. Anyway, good to have it in black and white :) Regards, Samuel On 20/12/2008, at 11:33 AM, James Mansion wrote: Space Ship Traveller wrote: This code is very quickly thrown together to show a basic idea, it obviously won't work in its current form. And you have fallen directly foul of the point that Marc made about that being unreliable. You have to ensure that 'initialized' is 0 before the first call (and reset during the tear-down). ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
On Fri, Dec 19, 2008 at 08:44:07PM +, James Mansion wrote: > because the design decision to have the multiple-init bug undetectable is > effectively made. I'm just objecting to Mr Lehman's characteristically > condescending and heavy-handed 'its not possible'. You'd be well-advised to read what I wrote. I explicitly wrote that the only methods to do so are requiring initialisation, or remembering the address of the watcher structure in some other way. While it might be possible that there is yet another variant (that isn't just a play on those two principal ideas), nobody so far came up with one. So if it *is* possible, then please state how. I skipped the rest of your e-mail and will likely do so with future e-mails as you are making your e-mails needlessly hard to read, despite being asked to format them in a readable way. -- The choice of a Deliantra, the free code+content MORPG -==- _GNU_ http://www.deliantra.net ==-- _ generation ---==---(_)__ __ __ Marc Lehmann --==---/ / _ \/ // /\ \/ / p...@goof.com -=/_/_//_/\_,_/ /_/\_\ ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
On 20/12/2008, at 5:10 PM, Marc Lehmann wrote: On Fri, Dec 19, 2008 at 08:44:07PM +, James Mansion > wrote: because the design decision to have the multiple-init bug undetectable is effectively made. I'm just objecting to Mr Lehman's characteristically condescending and heavy-handed 'its not possible'. You'd be well-advised to read what I wrote. I explicitly wrote that the only methods to do so are requiring initialisation, or remembering the address of the watcher structure in some other way. While it might be possible that there is yet another variant (that isn't just a play on those two principal ideas), nobody so far came up with one. So if it *is* possible, then please state how. Hey, you could always use C++ and have a constructor :) Just thought I'd throw that out there. Lol.. ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Re: How do I cancel a timer?
On Sat, Dec 20, 2008 at 06:11:34PM +1300, Space Ship Traveller wrote: > > Hey, you could always use C++ and have a constructor :) > > Just thought I'd throw that out there. Lol.. Just in case you meant that seriously, the c++ interface of libev indeed does that, but that doesn't change the fact that you need to initialise the watcher structure with an initialisation function, in this case it's a constructor. In fact, you can call the ev_xx_init macro a constructor, and, yes, c++ doesn't really like it what you call the constructor twice on the same memory area either. -- The choice of a Deliantra, the free code+content MORPG -==- _GNU_ http://www.deliantra.net ==-- _ generation ---==---(_)__ __ __ Marc Lehmann --==---/ / _ \/ // /\ \/ / p...@goof.com -=/_/_//_/\_,_/ /_/\_\ ___ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev