Programmer's Guide to the WvStreams Libraries | ||
---|---|---|
Prev | Chapter 13. WvStreamList - dealing with multiple streams | Next |
Here's a better way to choose between two lists, using WvStreamList. As you might have guessed, WvStreamList is a type of WvLinkList that contains WvStreams. It's also a stream itself, so (among other things) you can select() on a WvStreamList and include one WvStreamList inside another.
But let's keep it simple for now:
/* * A WvStream example. * * Some text about this example... */ #include <wvistreamlist.h> #include <wvpipe.h> int main() { const char *argv1[] = { "sh", "-c", "while :; do echo foo; sleep 3; done", NULL }; const char *argv2[] = { "sh", "-c", "while :; do echo snorkle; sleep 1; done", NULL }; WvPipe stream1(argv1[0], argv1, false, true, false); WvPipe stream2(argv2[0], argv2, false, true, false); stream1.autoforward(*wvcon); stream2.autoforward(*wvcon); WvIStreamList l; l.append(&stream1, false); l.append(&stream2, false); while (stream1.isok() || stream2.isok()) { if (l.select(-1)) l.callback(); } }
A streamlist is always okay (isok() == true) because you can always add and remove streams from it. That's why our main loop is checking for "okayness" of the two main streams, rather of the list.
But also notice the contents of the main loop. We select() on the list, and if it returns true, we then callback() the list. What's happening there?
What happens is this. WvStreamList::select() will return true if the select() of any of its member streams would return true. (It doesn't actually _call_ the select() function of each of its member streams, but the idea is the same. That's why WvStreamList is magic.) When you run WvStreamList::callback(), it calls back all the member streams that would have returned true to a select() call.
If you give select() a delay (in this case, infinity), it will wait until any one of the member streams is ready.
This mechanism increases fairness between streams, in case you have a lot of high-bandwidth streams and you're having trouble keeping up. If more than one stream is ready, callback() will call each one sequentially before it returns. That way, no one stream will get priority over the others.