
Hi Boris, No problem on the delay. I sometimes have long spells of silence due to work/family/church/life-in-general. :) My answers / opinions are below... --- Boris <boris@gtemail.net> wrote:
Hi Don,
sorry for my late answer but work caught me again. At least it's good to see others jumping in and keeping the discussion alive. :)
[...] ------ Sketch -------- [...]
It reminds me of I/O completion ports - several ports each of them handling several events? Is your idea similar to this?
It is similar, but the channel concept has no analogy. Then again, most async mechanisms are similar, it's just in the details that they diverge<g>. QueueUserAPC + SleepEx(ALERTABLE) is also similar, but again lacking the channel notion. The closest analogy in Windows is the USER thread message queue, an HWND and Get/DispatchMessage + PostMessage. I believe one can find nearly a one-to-one correspondence with that model.
------ Pseudo-code --------
class nexus
The concept of the class really reminds me of a I/O completion port. The only difference is that there is no invisible background thread being responsible for a nexus object - the application has to make sure that there is one thread controlling a nexus object?
Essentially, yes. Nothing is hidden with the possible exception of how does some body of code know the proper nexus object to which a channel should be connected. This can be explicit, but a thread-specific data item is also compelling.
[...] class channel
AFAICS you use this class to communicate with a nexus object. The owner thread does the multiplexing (waiting for different events in a nexus object) and other threads communicate with this nexus object through channels which are responsible for synchronizing? Is this correct?
If I understand you correctly, Yes. The channel objects are the means by which the user enqueues events to a nexus object and a different piece of user code calls the nexus object to dispatch/dequeue the messages.
So the difference between your approach and I/O completion ports in Windows is ... hm, I think in Windows a completion port is a combination of your nexus and channel, isn't it?
It is basically that, yes. The channel class, however, I believe to be a very important concept. Merging it with the nexus class would create dangerous situations where one would have to ask at the point a message is enqueued: "will it be OK to deliver this message regardless of what might happen between now and the time of delivery?" The key impulse that can make this answer always NO is "delete foo". The delete operation is synchronous. Without a channel to serve as a way to cancel pending messages to that object, we would have dangling pointers in the queue (a bad thing). Best, Don __________________________________ Do you Yahoo!? Yahoo! Small Business - Try our new resources site! http://smallbusiness.yahoo.com/resources/

Don G wrote:
[...]
So the difference between your approach and I/O completion ports in Windows is ... hm, I think in Windows a completion port is a combination of your nexus and channel, isn't it?
It is basically that, yes. The channel class, however, I believe to be a very important concept. Merging it with the nexus class would create dangerous situations where one would have to ask at the point a message is enqueued: "will it be OK to deliver this message regardless of what might happen between now and the time of delivery?" The key impulse that can make this answer always NO is "delete foo". The delete operation is synchronous. Without a channel to serve as a way to cancel pending messages to that object, we would have dangling pointers in the queue (a bad thing).
Hi Don, maybe we should go through an example - then I hopefully understand better. :) Let's say we have a function void block(). We call this function and we don't know when it will return. Now we want to use an asynchronicity library to call this function asynchronously. If we had a library similar to how .NET supports asynchronicity code would basically look like this: AsyncDelegate dlgt = new AsyncDelegate(block); dlgt.BeginInvoke(new AsyncCallback(callme)); There is a magic class AsyncDelegate which calls block() in a thread. When block() returns in the thread callme() is executed which is our callback function. If we forget about the class AsyncCallback for a moment I think the asynchronous support in .NET is pretty simple and easy to understand. How would you call block() asynchronously with your nexus and channel class? What is the difference? And what is the advantage of your design which introduces two classes whose meaning is difficult to grasp in the beginning? Regarding asynchronous I/O: If we had an asynchronicity library which could call any blocking function asynchronously it would do so by using threads. However if the asynchronicity library knew that a function blocks because of I/O it maybe would use a better implementation like overlapped I/O. This could be a reason *not* to build a network library upon a general purpose asynchronicity library. In Linux eg. it might be better to use the new epoll() function (new in Linux 2.6) to simulate asynchronous I/O instead of creating, managing and blocking in uncountable threads. In .NET the socket class has a method BeginAccept(). While there is no difference for the application programmer between this method and calling any other method asynchronously the .NET framework knows that BeginAccept() does I/O and will not create a new thread but do overlapped I/O instead. A network library with support of asynchronous I/O must then not be built upon a C++ asynchronicity library but must provide the same "look and feel" to an application programmer - asynchronicity looks everywhere the same but might be implemented differently in the network library for a better performance. Last but not least after thinking so much about asynchronicity: Isn't an asynchronicity library not just another interface for Boost.Thread? Instead of managing threads yourself you just tell the library to call a function in a thread and then call back. An asynchronicity library should then be tightly connected to Boost.Thread - it isn't a stand-alone library at all? Boris

Hi Don,
maybe we should go through an example - then I hopefully understand better. :)
Let's say we have a function void block(). We call this function and we don't know when it will return. Now we want to use an asynchronicity
Hi Boris and Don, I wonder if my goals are so different that I'm just confusing this thread. Unless I see something to make me think otherwise I'll leave you with the following notes; ----- Original Message ----- From: "Boris" <boris@gtemail.net> To: <boost@lists.boost.org> Sent: Friday, April 01, 2005 7:43 AM Subject: [boost] Re: Asynchronicity (long) [snip] library
to call this function asynchronously. If we had a library similar to how .NET supports asynchronicity code would basically look like this:
AsyncDelegate dlgt = new AsyncDelegate(block); dlgt.BeginInvoke(new AsyncCallback(callme));
In your example are you intending that multiple delegates may be outstanding on "block" at any one time i.e. several "dlgt.BeginInvoke(new AsyncCallback(callme))" before the first callback to "callme"?
There is a magic class AsyncDelegate which calls block() in a thread. When block() returns in the thread callme() is executed which is our callback function. If we forget about the class AsyncCallback for a moment I think the asynchronous support in .NET is pretty simple and easy to understand. How would you call block() asynchronously with your nexus and channel class? What is the difference? And what is the advantage of your design which introduces two classes whose meaning is difficult to grasp in the beginning?
What thread is performing the callback to "callme"? Ah (answering my own question after reading below), any thread from the set of "uncountable threads".
Regarding asynchronous I/O: If we had an asynchronicity library which
call any blocking function asynchronously it would do so by using threads. However if the asynchronicity library knew that a function blocks because of I/O it maybe would use a better implementation like overlapped I/O. This could be a reason *not* to build a network library upon a general purpose asynchronicity library. In Linux eg. it might be better to use the new epoll() function (new in Linux 2.6) to simulate asynchronous I/O instead of creating, managing and blocking in uncountable threads. In .NET the socket class has a method BeginAccept(). While there is no difference for the application programmer between this method and calling any other method asynchronously the .NET framework knows that BeginAccept() does I/O and will not create a new thread but do overlapped I/O instead. A network library with support of asynchronous I/O must then not be built upon a C++ asynchronicity library but must provide the same "look and feel" to an application programmer - asynchronicity looks everywhere the same but might be implemented differently in the network library for a better
could performance.
Last but not least after thinking so much about asynchronicity: Isn't an asynchronicity library not just another interface for Boost.Thread?
Instead
of managing threads yourself you just tell the library to call a function in a thread and then call back. An asynchronicity library should then be tightly connected to Boost.Thread - it isn't a stand-alone library at all?
Maybe there are three designs lurking here; 1 an interface that wraps threads for concurrent execution of blocking functions, 2 an interface that wraps queued calls to blocking functions and 3 (long description omitted) mine :-) Avoiding the issue of which is best (maybe they all have their place), what about these points; * how are parameters passed and results returned * what concurrency issues are there (thread safety of parameters and globals) * does the (async) lib facillitate network messaging (an original target) * does the lib facillitate async processing of a file or socket ("callme" would need to carry state info from one call to the next) Cheers.

Scott Woods wrote:
Hi Boris and Don,
I wonder if my goals are so different that I'm just confusing this thread. Unless I see something to make me think otherwise I'll leave you with the following notes;
Hi Scott, feel free to jump in. :)
Let's say we have a function void block(). We call this function and we don't know when it will return. Now we want to use an asynchronicity
[...] library
to call this function asynchronously. If we had a library similar to how .NET supports asynchronicity code would basically look like this:
AsyncDelegate dlgt = new AsyncDelegate(block); dlgt.BeginInvoke(new AsyncCallback(callme));
In your example are you intending that multiple delegates may be outstanding on "block" at any one time i.e. several "dlgt.BeginInvoke(new AsyncCallback(callme))" before the first callback to "callme"?
I brought this as an example as I like the simplicity of asynchronous support in .NET and wanted to force Don to explain why he proposes a more complicated design. :) At least it seems to me more complicated (or let's say less intuitive) as I could understand asynchronous support in .NET quite fast but still have to ask for the exact meaning of Don's nexus and channel class. To answer your question: Yes, in .NET you can call a blocking function asynchronously several times by creating different delegates (of course the function should be re-entrant). When you call BeginInvoke() you specifiy what function should be called back. That can be always the same function or a different one. Actually the code above is simplified as there is an object passed around which connects the delegate and callback function. In MSDN there is an overview about asynchronous programming in .NET: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm...
There is a magic class AsyncDelegate which calls block() in a thread. When block() returns in the thread callme() is executed which is our callback function. If we forget about the class AsyncCallback for a moment I think the asynchronous support in .NET is pretty simple and easy to understand. How would you call block() asynchronously with your nexus and channel class? What is the difference? And what is the advantage of your design which introduces two classes whose meaning is difficult to grasp in the beginning?
What thread is performing the callback to "callme"? Ah (answering my own question after reading below), any thread from the set of "uncountable threads".
Yes, I think "any thread" is the best assumption you can make in .NET. :)
[...]
Last but not least after thinking so much about asynchronicity: Isn't an asynchronicity library not just another interface for Boost.Thread? Instead of managing threads yourself you just tell the library to call a function in a thread and then call back. An asynchronicity library should then be tightly connected to Boost.Thread - it isn't a stand-alone library at all?
Maybe there are three designs lurking here; 1 an interface that wraps threads for concurrent execution of blocking functions, 2 an interface that wraps queued calls to blocking functions and 3 (long
If I understand correctly in 1) you have n threads for n blocking functions and in 2) n threads for m blocking function with n < m? So in 2) you call blocking functions one after the other?
description omitted) mine :-)
That was the posting which ended with "Confused?", right? ;)
Avoiding the issue of which is best (maybe they all have their place), what about these points;
* how are parameters passed and results returned * what concurrency issues are there (thread safety of parameters and globals) * does the (async) lib facillitate network messaging (an original target) * does the lib facillitate async processing of a file or socket ("callme" would need to carry state info from one call to the next)
All good questions! In this thread I have been trying to understand the advantages of Don's proposal by comparing his design with the one in .NET. And I have been wondering if it makes sense to build a network library with asynchronous support on top of an asynchronicity library as an implementation of the network library can not make use then of I/O APIs which seem to be much better supported by different operating systems than asynchronous APIs. A better solution could be to agree upon some rules about how methods (which support asynchronous operations) should be called and what their signatures should look like. Eg. in .NET you can always create a delegate and call BeginInvoke() to execute a blocking function in a thread. But when you have a socket you call BeginAccept() which has a similar signature as BeginInvoke(). For the application developer no difference - for the library developer the chance to implement BeginAccept() more efficiently than with a delegate and BeginInvoke() which would just create another thread. Boris

Hi Boris,
I brought this as an example as I like the simplicity of asynchronous support in .NET and wanted to force Don to explain why he proposes a more complicated design. :) At least it seems to me more complicated (or let's say less intuitive) as I could understand asynchronous support in .NET quite fast but still have to ask for the exact meaning of Don's nexus and channel class.
I hope my previous message clarifies things a bit. The big difference between .NET and C++ is garbage collection. Many patterns/idioms that work well in a GC environment just don't work or get more complex, less intuitive, etc. in C++ where objects and data can be zapped while operations that were using them are still pending. Best, Don __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com

Hi, Still reading the thread and after your message I think I can offer this as my last (again ;-) contribution and bow out after gaining some insights. See below; ----- Original Message ----- From: "Boris" <boris@gtemail.net> To: <boost@lists.boost.org> Sent: Friday, April 01, 2005 10:46 AM Subject: [boost] Re: Re: Asynchronicity (long) [snip]
Maybe there are three designs lurking here; 1 an interface that wraps threads for concurrent execution of blocking functions, 2 an interface that wraps queued calls to blocking functions and 3 (long
If I understand correctly in 1) you have n threads for n blocking functions and in 2) n threads for m blocking function with n < m? So in 2) you call blocking functions one after the other?
description omitted) mine :-)
That was the posting which ended with "Confused?", right? ;)
And I have been wondering if it makes sense to build a network library with asynchronous support on top of an asynchronicity library as an implementation of the network library can not make use then of I/O APIs which seem to be much better supported by different operating systems than asynchronous APIs. A better solution could be to agree upon some rules about how methods (which support asynchronous operations) should be called and what their signatures should look like. Eg. in .NET you can always create a delegate and call BeginInvoke() to execute a blocking function in a
For me the possible architectures now boil down to; 1) A pool of threads available to assume responsibility for concurrent execution of a specified function. The calling code may block (i.e. wait) on "all threads busy" or return immediately with an error condition. 2) A thread taking its work from a queue. 3) Mine (AKA Confused) There are of course some large number of combinations and permutations possible. thread.
But when you have a socket you call BeginAccept() which has a similar signature as BeginInvoke(). For the application developer no difference - for the library developer the chance to implement BeginAccept() more efficiently than with a delegate and BeginInvoke() which would just create another thread.
Understood. IMO this thread is attempting to wrap specific code fragments (i.e. calls to blocking functions) with some mechanism that allows the caller to continue execution, dealing with the "return" at some later, optimal moment (when the underlying operation actually completes). The specific plumbing underneath the wrapper (best use of threads, signaling mechansims and queues) seems secondary to me. This certainly removes blocking calls from application code - this thread is "on track" :-) But for me this is only part way there. A library that wraps blocking calls in a non-blocking framework reinforces a style of programming. There is a "main" thread that needs to be "always ready" (not blocked). It spends its time waiting for the next event (i.e. callback) and responding by creating more wrappers around blocking operations (amongst other things). This is a simplification but one that hopefully helps make my point. What such a library doesnt attempt to do is provide a framework for the async processing of a "block stream" whether that be a disk file of a network connection. Because that processing is actually what the application is about, that is where my thoughts are headed. Software written using the library sketched above must implement its own custom framework for carrying state from one callback the next. This is do-able but for me seems to be coding "on the back foot". My directions have been influenced by the work of D. Schmidt and his Active Objects as well as others (e.g. SDL). In the world of AO's the creation of a delegate is fulfilled by sending of a message. The AO world is symmetric; there is no "main" thread that supervises the scheduling of concurrent activities. Messages are standalone objects (i.e. effectively call-by-value) and messages can "fall into the void" (specifically occurring when a call is made, and queued, to an object that disappears before the related processing occurs). I mention such points as related questions have arisen in this thread. In the AO world these questions are also answered ;-) An AO is the context for the processing of a "block stream". Maybe the aync-wrapper-lib will evolve into something akin to AO's? Maybe AO's will be nicely implementable over that lib? Maybe these two directions are utterly distinct and independently useful? These questions are too big for me :-) Cheers, Scott

Please consider the general design of having asynchronous I/O handled by callbacks in threads. The callbacks can be easily designated by Boost Function functions and there is already a Boost Thread library for creating and manipulating threads. I have already worked in such an environment, albeit with .NET and not the Boost libraries, but I know this general model works well and is very flexible. How asynchronous I/O is specifically implemented in this model is up to the programmer(s) who create it, but I do not see a reason to invent a model which has already been proven to work well and which can be supported by other libraries which Boost already incorporates. Boris wrote:
Don G wrote:
[...]
So the difference between your approach and I/O completion ports in Windows is ... hm, I think in Windows a completion port is a combination of your nexus and channel, isn't it?
It is basically that, yes. The channel class, however, I believe to be a very important concept. Merging it with the nexus class would create dangerous situations where one would have to ask at the point a message is enqueued: "will it be OK to deliver this message regardless of what might happen between now and the time of delivery?" The key impulse that can make this answer always NO is "delete foo". The delete operation is synchronous. Without a channel to serve as a way to cancel pending messages to that object, we would have dangling pointers in the queue (a bad thing).
Hi Don,
maybe we should go through an example - then I hopefully understand better. :)
Let's say we have a function void block(). We call this function and we don't know when it will return. Now we want to use an asynchronicity library to call this function asynchronously. If we had a library similar to how .NET supports asynchronicity code would basically look like this:
AsyncDelegate dlgt = new AsyncDelegate(block); dlgt.BeginInvoke(new AsyncCallback(callme));
There is a magic class AsyncDelegate which calls block() in a thread. When block() returns in the thread callme() is executed which is our callback function. If we forget about the class AsyncCallback for a moment I think the asynchronous support in .NET is pretty simple and easy to understand. How would you call block() asynchronously with your nexus and channel class? What is the difference? And what is the advantage of your design which introduces two classes whose meaning is difficult to grasp in the beginning?
Regarding asynchronous I/O: If we had an asynchronicity library which could call any blocking function asynchronously it would do so by using threads. However if the asynchronicity library knew that a function blocks because of I/O it maybe would use a better implementation like overlapped I/O. This could be a reason *not* to build a network library upon a general purpose asynchronicity library. In Linux eg. it might be better to use the new epoll() function (new in Linux 2.6) to simulate asynchronous I/O instead of creating, managing and blocking in uncountable threads. In .NET the socket class has a method BeginAccept(). While there is no difference for the application programmer between this method and calling any other method asynchronously the .NET framework knows that BeginAccept() does I/O and will not create a new thread but do overlapped I/O instead. A network library with support of asynchronous I/O must then not be built upon a C++ asynchronicity library but must provide the same "look and feel" to an application programmer - asynchronicity looks everywhere the same but might be implemented differently in the network library for a better performance.
Last but not least after thinking so much about asynchronicity: Isn't an asynchronicity library not just another interface for Boost.Thread? Instead of managing threads yourself you just tell the library to call a function in a thread and then call back. An asynchronicity library should then be tightly connected to Boost.Thread - it isn't a stand-alone library at all?
Boris
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Edward Diener wrote:
Please consider the general design of having asynchronous I/O handled by callbacks in threads. The callbacks can be easily designated by Boost Function functions and there is already a Boost Thread library for creating and manipulating threads. I have already worked in such an environment, albeit with .NET and not the Boost libraries, but I know this general model works well and is very flexible. How asynchronous I/O is specifically implemented in this model is up to the programmer(s) who create it, but I do not see a reason to invent a model which has already been proven to work well and which can be supported by other libraries which Boost already incorporates.
While asynchronicity in .NET is basically based on threads it is not true for asynchronous I/O. If you built asynchronous I/O on top of an asynchronicity library with callbacks in threads you will end up with 1000 threads blocked in read() if you have 1000 sockets. This doesn't happen in .NET and I don't think anyone want this to happen in a C++ network library. As an asynchronicity library doesn't know if a blocking function does I/O it will always call this function in a thread. The network library however knows better and can provide a much more efficient implementation of asynchronous I/O than an asynchronicity library can do. However in order not to confuse the application programmer asynchronous operations should look the same: rules for naming functions that do asynchronous operations, basically similar signatures of these functions etc. .NET has these rules (see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm...) and it apparently works well. From this webpage: "The called object can choose to explicitly support asynchronous behavior, either because it can implement it more efficiently than a general architecture ..." In my opinion a socket is such an object which should explicitly support asynchronous behavior. Boris
[...]

Boris wrote:
Edward Diener wrote:
Please consider the general design of having asynchronous I/O handled by callbacks in threads. The callbacks can be easily designated by Boost Function functions and there is already a Boost Thread library for creating and manipulating threads. I have already worked in such an environment, albeit with .NET and not the Boost libraries, but I know this general model works well and is very flexible. How asynchronous I/O is specifically implemented in this model is up to the programmer(s) who create it, but I do not see a reason to invent a model which has already been proven to work well and which can be supported by other libraries which Boost already incorporates.
While asynchronicity in .NET is basically based on threads it is not true for asynchronous I/O. If you built asynchronous I/O on top of an asynchronicity library with callbacks in threads you will end up with 1000 threads blocked in read() if you have 1000 sockets.
1) No one normally uses 1000 sockets. Be real rather than hyperbolic if you are trying to make a point. 2) Any good asynchronous I/O library should be able to callback on the same thread or another thread. 3) If I am doing socket programming I often do not want to hold up my main thread by having callbacks in it.
This doesn't happen in .NET and I don't think anyone want this to happen in a C++ network library. As an asynchronicity library doesn't know if a blocking function does I/O it will always call this function in a thread.
Good. If you are using an asynchronous library, it means by its very nature that you want to perform your action in another thread, so that your current thread can continue. Whether it is blocking waiting on I/O or not is irrelevant. That is up to the programmer to know, not the library. If it is not blocking the new thread will handle it quickly and exit. Worrying about creating threads is thinking about performance instead of design. No matter what anyone says, design well first and deal with performance later.
The network library however knows better and can provide a much more efficient implementation of asynchronous I/O than an asynchronicity library can do.
You are trying to tie a network library to an asynchronous library, and so you are confusing two issues.. Decouple them instead. An asynchronous library could be modelled around the suggestion I made, and your network library could decide to use its asynchronous I/O facilities depending on what it wants to do.
However in order not to confuse the application programmer asynchronous operations should look the same: rules for naming functions that do asynchronous operations, basically similar signatures of these functions etc. .NET has these rules (see
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm...)
and it apparently works well. From this webpage: "The called object can choose to explicitly support asynchronous behavior, either because it can implement it more efficiently than a general architecture ..." In my opinion a socket is such an object which should explicitly support asynchronous behavior.
A socket in .NET chooses to operate synchronously or asynchronously. Look at the .NET socket doc. Similarly your network library can choose synchronous calls for whatever it does, or it can choose to use an asynchronous I/O library along my general suggestion.

Edward Diener wrote:
Boris wrote: [...]
While asynchronicity in .NET is basically based on threads it is not true for asynchronous I/O. If you built asynchronous I/O on top of an asynchronicity library with callbacks in threads you will end up with 1000 threads blocked in read() if you have 1000 sockets.
1) No one normally uses 1000 sockets. Be real rather than hyperbolic if you are trying to make a point.
I don't know why a C++ network library shouldn't be able to do what eg. is possible in .NET.
2) Any good asynchronous I/O library should be able to callback on the same thread or another thread.
No problem with that.
3) If I am doing socket programming I often do not want to hold up my main thread by having callbacks in it.
Yes, there are various possibilities to support asynchronous I/O although callbacks seem to be most asynchronous. :)
This doesn't happen in .NET and I don't think anyone want this to happen in a C++ network library. As an asynchronicity library doesn't know if a blocking function does I/O it will always call this function in a thread.
Good. If you are using an asynchronous library, it means by its very nature that you want to perform your action in another thread, so that your current thread can continue. Whether it is blocking waiting on I/O or not is irrelevant. That is up to the programmer to know,
Okay.
not the library. If it is not blocking the new thread will handle it quickly and exit. Worrying about creating threads is thinking about performance instead of design. No matter what anyone says, design well first and deal with performance later.
Considering the bad support of asynchronous I/O on different operating systems I disagree that we should ignore the performance impacts of design decisions.
The network library however knows better and can provide a much more efficient implementation of asynchronous I/O than an asynchronicity library can do.
You are trying to tie a network library to an asynchronous library,
No, I don't want to do this. It is perfectly okay to have a stand-alone asynchronicity library. I am trying to find out if a network library should make use of such a stand-alone asynchronicity library or if the network library should deal with asynchronous I/O itself.
and so you are confusing two issues.. Decouple them instead. An asynchronous library could be modelled around the suggestion I made, and your network library could decide to use its asynchronous I/O facilities depending on what it wants to do.
But how does the network library provide asynchronous I/O operations to the library user? If you tell me that's up to the network library asynchronous I/O provided by the network library will be used differently than what eg. an asynchronicity library might provide. And I am only talking about the interface not about the implementation. The nice thing in .NET is that asynchronous operations look everywhere the same no matter if you are in the network library or somewhere else. Boris

Boris wrote:
Edward Diener wrote:
Boris wrote: [...]
While asynchronicity in .NET is basically based on threads it is not true for asynchronous I/O. If you built asynchronous I/O on top of an asynchronicity library with callbacks in threads you will end up with 1000 threads blocked in read() if you have 1000 sockets.
1) No one normally uses 1000 sockets. Be real rather than hyperbolic if you are trying to make a point.
I don't know why a C++ network library shouldn't be able to do what eg. is possible in .NET.
2) Any good asynchronous I/O library should be able to callback on the same thread or another thread.
No problem with that.
3) If I am doing socket programming I often do not want to hold up my main thread by having callbacks in it.
Yes, there are various possibilities to support asynchronous I/O although callbacks seem to be most asynchronous. :)
This doesn't happen in .NET and I don't think anyone want this to happen in a C++ network library. As an asynchronicity library doesn't know if a blocking function does I/O it will always call this function in a thread.
Good. If you are using an asynchronous library, it means by its very nature that you want to perform your action in another thread, so that your current thread can continue. Whether it is blocking waiting on I/O or not is irrelevant. That is up to the programmer to know,
Okay.
not the library. If it is not blocking the new thread will handle it quickly and exit. Worrying about creating threads is thinking about performance instead of design. No matter what anyone says, design well first and deal with performance later.
Considering the bad support of asynchronous I/O on different operating systems I disagree that we should ignore the performance impacts of design decisions.
The network library however knows better and can provide a much more efficient implementation of asynchronous I/O than an asynchronicity library can do.
You are trying to tie a network library to an asynchronous library,
No, I don't want to do this. It is perfectly okay to have a stand-alone asynchronicity library. I am trying to find out if a network library should make use of such a stand-alone asynchronicity library or if the network library should deal with asynchronous I/O itself.
In .NET, asychronous calls have their own general interface. When the programmer uses, as an example, a socket he/she may choose to call a number of functions either synchronously or asynchronously, with the asynchronous calls using the same general interface as the rest of asynchronous calls in .NET. In the same way if Boost has an asynchronous I/O library built around threads and callbacks, a separate Boost network library should offer both synchronous or asynchronous functionality to the end-programmer. In offering asynchronous functionality the network library can use the asynchronous I/O library to make asynchronous calls. The good thing about this decoupling is that another completely different Boost library, for example a file I/O libary, should be able to use the general purpose asynchronous I/O library for its own purposes also. I am only arguing generally for an asynchronous I/O library built around what already exists in Boost from Boost threads and Boost function ( for callbacks ).
and so you are confusing two issues.. Decouple them instead. An asynchronous library could be modelled around the suggestion I made, and your network library could decide to use its asynchronous I/O facilities depending on what it wants to do.
But how does the network library provide asynchronous I/O operations to the library user?
That is up to the network library designer/implementer but I see no reason why the network library can not provide both synchronous and asynchronous functionality in a number of areas. This is very similar to the way that sockets, as an example, works in .NET, where one can call certain functionality either synchronously, waiting for the call to finish, or asynchronously, returning to do other things while the call will finish when a delegate on another thread is invoked.
If you tell me that's up to the network library asynchronous I/O provided by the network library will be used differently than what eg. an asynchronicity library might provide.
The challenge of an asynchronous I/O library is to provide a general enough interface to allow other more specific libraries to use it for their own specific asynchronous I/O purposes, else there is little purpose in creating it.
And I am only talking about the interface not about the implementation. The nice thing in .NET is that asynchronous operations look everywhere the same no matter if you are in the network library or somewhere else.
I agree, looking very much the same but allowing both the end-programmer, and the particularly implementation of asynchronous callback functionality, to pass different data to an asynchronous callback, and also using the results of data picked up by the callback in different ways depending on the implementation. I think we are mostly agreeing. My original appeal is that building a general purpose asynchronous I/O library around Boost threads and Boost function seems feasible, since the equivalent concepts have already been shown to work in another environment, and might save a great deal of trouble from trying to re-invent the code from scratch all over again. On top of that general purpose asynchronous I/O library other implementors which need asynchronous I/O in their particular libraries can build whatever elaborate schemes they want. Perhaps "asynchronous I/O" is a bad name and one should just settle for an "asynchronous calls" library, although the I/O portion of it may incorporate general ideas of how to do I/O, perhaps using streams ala the I/O streams library but with the idea that a particular streaming operation may block waiting for input or output to complete. So the breakdown of the problem, from a network library point of view, could be: 1) A general purpose asynchronous callback library. 2) A general purpose asynchronous I/O library using 1) and considering how I/O should be implemented. 3) A network library, or any other library which might want to make asynchronous I/O calls, using 2). Usually when a problem is complex it is much easier breaking it down into manageable pieces, and makes for more resuable programming. That is why Boost is so great, since it offers many great pieces which one can use to build even more complicated things.

Edward Diener wrote:
[...]
But how does the network library provide asynchronous I/O operations to the library user?
That is up to the network library designer/implementer but I see no reason why the network library can not provide both synchronous and asynchronous functionality in a number of areas. This is very similar to the way that sockets, as an example, works in .NET, where one can call certain functionality either synchronously, waiting for the call to finish, or asynchronously, returning to do other things while the call will finish when a delegate on another thread is invoked.
Maybe I didn't explain myself very good because I also like how .NET supports asynchronous operations. :) If I take the socket class in .NET as an example: You could call Socket.Connect() asynchronously like any other function using a delegate. However the socket class supports asynchronous I/O explicitly providing a BeginConnect() and EndConnect() method which is more efficiently implemented. However there is an asynchronous design pattern in .NET so whoever designed BeginConnect() and EndConnect() had to follow some rules. As far as I understand you agree that we should do in C++ similarly? There should be an asynchronicity library based on threads and callbacks (and maybe some other features). Then we have a network library supporting different models of I/O including asynchronous I/O. The asynchronous support will be explicitly provided by the network library. The library user doesn't need to use the asynchronicity library himself to do asynchronous I/O as there will be explicit support just like in .NET. How this explicit support of asynchronous I/O is implemented doesn't matter. If we agree upon this we need an asynchronous design pattern in C++, too. Asynchronous I/O support in a network library must be then designed according to this pattern. And of course any other library which will support asynchronous operations explicitly have to follow this design pattern, too.
If you tell me that's up to the network library asynchronous I/O provided by the network library will be used differently than what eg. an asynchronicity library might provide.
The challenge of an asynchronous I/O library is to provide a general enough interface to allow other more specific libraries to use it for their own specific asynchronous I/O purposes, else there is little purpose in creating it.
Until now I was thinking about an asynchronicity library and a network library. You think about putting another library in between - an asynchronous I/O library? Boris
[...]

Boris wrote:
Edward Diener wrote:
[...]
But how does the network library provide asynchronous I/O operations to the library user?
That is up to the network library designer/implementer but I see no reason why the network library can not provide both synchronous and asynchronous functionality in a number of areas. This is very similar to the way that sockets, as an example, works in .NET, where one can call certain functionality either synchronously, waiting for the call to finish, or asynchronously, returning to do other things while the call will finish when a delegate on another thread is invoked.
Maybe I didn't explain myself very good because I also like how .NET supports asynchronous operations. :) If I take the socket class in .NET as an example: You could call Socket.Connect() asynchronously like any other function using a delegate. However the socket class supports asynchronous I/O explicitly providing a BeginConnect() and EndConnect() method which is more efficiently implemented. However there is an asynchronous design pattern in .NET so whoever designed BeginConnect() and EndConnect() had to follow some rules.
As far as I understand you agree that we should do in C++ similarly?
Similarly, but using the facilities of modern C++. There is no need to exactly emulate .NET's design when C++ provides a possibly richer way of doing things.
There should be an asynchronicity library based on threads and callbacks (and maybe some other features).
Agreed. A separate asynchronous library which has nothing to do with I/O per se but rather defines a model for doing callbacks in threads which can be invoked asynchronously.
Then we have a network library supporting different models of I/O including asynchronous I/O.
The reason I posited a separate library for purely asynchronous I/O, rather than folding that into the network library, is that there are models in which an asynchronous I/O library may have nothing to do with network access. For instance it is possible in some operating systems to read/write files asynchronously. Should this come under the aegis of a network library ? I do not think so since the file I/O will normally occur locally. On the other hand, remote access to files may be thought of as network functionality and it may be possible to do file I/O remotely asynchronously. So my point was simply that an asynchronous I/O model may be something that can be used by more than just a network library and may be considered separately.
The asynchronous support will be explicitly provided by the network library. The library user doesn't need to use the asynchronicity library himself to do asynchronous I/O as there will be explicit support just like in .NET. How this explicit support of asynchronous I/O is implemented doesn't matter.
Agreed.
If we agree upon this we need an asynchronous design pattern in C++, too. Asynchronous I/O support in a network library must be then designed according to this pattern. And of course any other library which will support asynchronous operations explicitly have to follow this design pattern, too.
That is the idea. If the pattern is flexible enough, an asynchronous I/O library could be useful outside of what is thought of as networking operations. It all depends on what is considered "network programming" and what is not. If I send data through a USB port to read/write from/to a hardare device, is that "network programming" ? Probably not, but a good asynchronous I/O model might be built that can be used in that situation also. C++ currently has a standard I/O library. Many people may not like it because of its complexity but it was designed to be broadly applied and to be flexible for many forms of I/O. Unfortunately it is purely synchronous, mainly because the idea of asynchronicity was considered outside the sope of the standard C++ libraries and outside the scope of the language itself, not to speak also of the idea of threading. In the same way a general purpose asynchronous I/O library could serve the same purpose as the standard C++ "synchronous" I/O library.
If you tell me that's up to the network library asynchronous I/O provided by the network library will be used differently than what eg. an asynchronicity library might provide.
The challenge of an asynchronous I/O library is to provide a general enough interface to allow other more specific libraries to use it for their own specific asynchronous I/O purposes, else there is little purpose in creating it.
Until now I was thinking about an asynchronicity library and a network library. You think about putting another library in between - an asynchronous I/O library?
Yes, see argument above. The main reason for my argument is reuse by other libraries doing asynchronous I/O but which may not be network related. If the network library is going to support asynchronous operations, which is only natural because of the time it takes for things to happen over networks, other libraries not defined as "network" but still wanting to offer asynchronous I/O operations could use a general purpose asynchronous I/O library to achieve their ends also. Of course all this is theoretical design. It may be that the ideas of a separate asynchronous library, asynchronous I/O library, and network library are unrealistic and one can not separate these things as cleanly as I would believe, but I still think the idea of having these libraries for re-use is the right one. Even just a separate asynchronous library could be used when not doing I/O but just wanting to provide asynchronous "background" operations for processes which have to be responsive to end-user input. Of course separate asynchronous libraries and asynchronous I/O libraries exist in C++ but their models appear to me to be essentially C procedural programming models. Modern C++ should be able to come up with things that are more robust and take advantage of possibly both OOP programming and generic programming knowledge. Eddie

Hi Eddie, Please find my comments below.
The reason I posited a separate library for purely asynchronous I/O, rather than folding that into the network library, is that there are models in which an asynchronous I/O library may have nothing to do with network access. For instance it is possible in some operating systems to read/write files asynchronously. Should this come under the aegis of a network library? I do not think so since the file I/O will normally occur locally. On the other hand, remote access to files may be thought of as network functionality and it may be possible to do file I/O remotely asynchronously. So my point was simply that an asynchronous I/O model may be something that can be used by more than just a network library and may be considered separately.
I agree in spirit, but the details make a library of this kind unlikely to work. For example, (on Windows) the techniques used for async file I/O are completely different than async network I/O. Even pipe I/O is just slightly different that file I/O. What I have found is that all one can hope for is a pattern with which async operations should be designed. The implementation details may be shared in some cases, but not enough to make those much of a reusable library. For example, I created a socket select/poll engine at work, and it was highly portable for the purposes of sockets. It could be applied to file descriptors in general on Unix, but as that was only helpful for those platforms, I didn't give it much polish. Async file I/O has a completely different implementation, as did async pipe I/O.
The main reason for my argument is reuse by other libraries doing asynchronous I/O but which may not be network related. If the network library is going to support asynchronous operations, which is only natural because of the time it takes for things to happen over networks, other libraries not defined as "network" but still wanting to offer asynchronous I/O operations could use a general purpose asynchronous I/O library to achieve their ends also.
See above. The means by which asynchronicity is gained differs by API and OS, making a general, reusable async I/O library impracticle.
Of course all this is theoretical design. It may be that the ideas of a separate asynchronous library, asynchronous I/O library, and network library are unrealistic and one can not separate these things as cleanly as I would believe, but I still think the idea of having these libraries for re-use is the right one.
Some non-portable portions can be made reusable, but still specific to a certain part of the overall async I/O problem. To me, this means that the async I/O facility is of use to very few people and should be concidered an implementation detail.
Even just a separate asynchronous library could be used when not doing I/O but just wanting to provide asynchronous "background" operations for processes which have to be responsive to end-user input.
I agree; a general async library can go a long way to making async programming real. The I/O problem is a thing to solve on top of that.
Of course separate asynchronous libraries and asynchronous I/O libraries exist in C++ but their models appear to me to be essentially C procedural programming models. Modern C++ should be able to come up with things that are more robust and take advantage of possibly both OOP programming and generic programming knowledge.
That's the hope :) Best, Don __________________________________ Yahoo! Messenger Show us what our next emoticon should look like. Join the fun. http://www.advision.webevents.yahoo.com/emoticontest
participants (4)
-
Boris
-
Don G
-
Edward Diener
-
Scott Woods