Hi, On Sunday 19 April 2015 12:31:22 Marc Lehmann wrote: > They are being sorted by priority, just like any other event, which is the > primary reason to do it this way: Not specialcasing them, but treating > them the same.
Yep, I can see that is a good reason for ev_check watchers. But ev_prepare watchers are, like you said, a special case, different from ev_check watchers, since ev_prepare do not queue with other watchers. Look, I am not necessarily pushing for a change in libev here, and telling you "how libev should be done". I am telling you that I, as an end user not intimately familiar with internal libev code, did not see this coming. It is a pitfall that should be documented. > That's why there is this thing called "documentation" - ev_prepare > watchers are a very advanced concept (and have various limitations), and > work if you use them for the documented purpose. If you want to use them > for another purpose, it's not too much to ask to read the documentation > more thoroughly. Well you say it's already in the documentation. I have read most of the documentation at least once, many parts of it multiple times. I don't have total recall, and maybe I missed it, but I am pretty sure that these assertions of yours in our exchange here are missing: - The nature and extent of ev_prepare watcher limitations - Use of ev_prepare watchers not sanctioned by the libev author so I am not sure how "reading the documentation more thoroughly" would have helped. I'd also like to remind you of this section of the documentation: "Abusing an ev_check watcher for its side-effect" which is, the way I see it, pretty much what I am trying to achieve, but with the prepare instead of the check watcher. > > So I think this behaviour should at least be documented in the section > > for prepare watchers. > > It's not behaviour that is specific to prepare watchers. Yes, that is true indeed! However, for watchers other than prepare, this behaviour will not cause the blocking problem. ev_check watchers per documentation are only queued _after_ the poll syscall, so it is intuitive that adding an ev_check watcher from inside an ev_check watcher, or any other watcher for that matter, will see its execution only after the next poll/select syscall. This is not quite as clear for ev_prepare watchers. > From your other mail (that I read afterwards), it very much looks as if > you are - ev_prepare watchers are not meant to delay actions, that's what > idle watchers or timers are for. Actually, it is not delaying what I want. It is a side-effect of the requirements I have and that I want to minimize. I want code to execute as soon as possible after the return of a watcher, because I cannot have that code running from the callstack of the watcher. > > I stumbled over this problem when I wanted my program to shut down > > cleanly by stopping all watchers. This way I get an indication when > > a watcher is still running even though it should not, by, well, the > > program just not quitting when it should :) > > "This way" refers to what? The manner, in which ev_run() is made to return: By making sure all watchers are stopped. Not relevant to this discussion though. > Exactly - do you have any other use cases? > > > And for those use cases where the precision of ev_now() is > > sufficient. What about time critical code, where real time timestamps > > are of importance? > > You completely lost me now, first, what do timestamps have to do with > anything, and second, ev_now gives you a real time timestamp of the same > or higher precision as other real time stamps. I have a second use case, apart from the module unloading. I am writing a process automation system, with functionality somewhat akin to that of Matlab's System Generator. It has signal pathways with signals (having a value and an associated time stamp for when this value was generated) being passed on and processed in a fully event driven manner. The signalling lines are connected via nodes that provide for various operations and a change in one signal value may result in changes in a graph of edges and nodes. This may be a classic example for recursion, however, I want changes to progress one node at-a-time. So when computing the output values of one node, I need to defer further processing of the output values until all nodes connected to the input signal (the one triggering the change) have processed their respective output values. While all this is happening, even after the deferral, the timestamp returned by ev_now() must not change, because my code relies on the value returned by ev_now() as a reference time stamp for when a value is generated on some node types. This practically rules out the use of ev_timer and ev_idle. So, for my use-case, ev_prepare probably still is the way to go, but I'll just have to implement my own queueing inside a prepare watcher. > > ev_idle makes no guarantee whatsoever how many event loop interations > > need to happen before it is first invoked, which is bad. > > Actually, it's good, because that is what it is invented for. Of course that is what it was invented for. You're quoting me completely out of context and then you're objecting to the statement contained in it. Do you really think that is helpful to this discussion? > > And using ev_timer really seems like abusing the timer watcher. Use > > 0.000000001 as start time? That looks very hackish to me. > > Indeed, if you want the shortest possible delay, 0 would be simplest and > most succinct. Oh. For some reason, I thought that a timeout value of 0.0 was illegal which it clearly is not. My bad. Still, isn't there some unnecessary overhead connected to starting and stopping a timer for a simple deferral? > > What I was writing was merely a suggestion, it would make it easier for > > libev users to unravel recursion inside a watcher, which is basically > > what I want to do here. > > Can you define "recursion inside a watcher" more clearly? Well, returning to the graph example earlier, changing output values on a node may trigger calls in other nodes that the input value has changed. A naive implementation of this will lead to recursion, because those nodes may also subsequently change their output values. By this I mean "recursion inside a watcher". From a user's perspective, I feel that it would be cool if libev would give me some tools to break out of this recursion. Frankly, you can pick up on my suggestions or you cannot. I don't feel very strongly about it. In the end, I will just do the queueing myself. > As is the case with all your solutions: they are rather complicated, abuse > watchers for purposes they were not designed for Yup. Hence my suggestion for a new watcher type. -- Best regards, Thilo Schulz _______________________________________________ libev mailing list [email protected] http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
