
Hello,
I see that the string is taken by value in your small examples.
Shouldn't it be taken by const-reference instead?
Same for async_o etc.
Yes, in real application code, it should be reference. In Join, async / synch methods take whatever signature users defined (similar to Boost.Signals), users are expected to follow general rule when making normal function calls, such as pass large data set thru pointers and references. The Join library just let user define the signature as normal.
Let me further clarify argument passing in the Join library a little bit (my rush reply in the morning is not accurate). The semantics of async method calls are one-way, no-result, non-blocking, returning immediately; possibly the arguments will be buffered in a queue for future consumption. So the callers of async methods could return, unwind stack and go on with other work long before the arguments get used. In general client code should not use pointers and references to data in stack as arguments to async methods (values or pointers / references to heap allocated objects are fine), Just remember that async methods should become the "owner" of argument data. For synch methods, since they will block waiting for results, normal function arguments can be used: references, pointers, and values. - why are you using boost.function? Aren't regular function objects enough?
I am not sure which specific places in code you are referring to. Boost.Function is a generalization of function pointers and callbacks, which could be free functions, methods, result of boost.bind() and of course function objects, For example in the Join library, the way to spawn a new task in thread pool is by calling the following async method "execute" which take boost.function as argument: class executor { public: async<boost::function<void()> > execute; .... }; this way we can spawn a task for a free function, method, result of bind() and function objects. - how is concurrency handled? Locks? What kind? Is the scheduling fair?
these are more involving. let me get back to it during night.
The question is kind of vague so i can only reply in general. Each object which define async /synch methods and chords will use only one mutex to protect the internal synchronization status and all data in async / synch methods. Besides this mutex, each synch method also has a condition variable for possible blocking of calling threads. When messages come in and more than one chords become ready to fire, there are 3 kinds of scheduling to decide which chord will fire and consume the messages: fire the first chord which is ready, fire the ready chord with most methods which will consume most buffered messages, and round-robin scheduling. You can find all the above info and more details in the design document. Again i am not sure if this is exactly what your question is about. If not, please clarify your questions a little bit. Thanks Yigong