
scott <scottw <at> qbik.com> writes:
At the point where the scheduler is holding the result of type int, it needs to be able to "deliver" it to the caller. The only way it can do this is call a method on the appropriate object (instance) passing the results. Which method and which object? The scheduler can only get these from the queued task, i.e. the task must hold the method-to-run and pointers necessary for the return delivery.
This method will be another proxy (e.g. non_void_with_param_returned) that in turn, queues the result. This decouples the scheduler from the recipient of the results; eventually the thread working on that task list will reach the "results task" and will run that.
So you have a callback, the invocation of which queues a message?
How does the object and method address get in the task object? You may well ask and this was (some of) the reason for my initial response.
A by-product of working on "active objects" is a set of classes/templates that constitute a little thread-toolkit. This toolkit should facillitate the design and implementation of pretty much any snarling, thread-beast; if that is what you need.
The "damn" part of my response stems from the fact that I believe the "Method Request" model is not viable as a model of execution for the thread toolkit. It is simply wrong and bending it to this task is a deadend.
I don't understand why you think this. I think the active object wrapper indicates that you can use the method request model to encapsulate the interactions between the threads. There's no reason why it can't be the interface layer on top of a message passing system, provided that the result does yield simpler interfaces.
In signal processing the equivalent to "Method Request" is "send". This primitive takes an object to send and the address of the destination (e.g. an active<object>);
send( int_results, calling_object )
These calls are made from within the methods that you already have working, i.e. the non-proxy _real_ methods.
The trick with "send" is that it can be coded to populate the "task" with all the appropriate object and member pointers so that the receiving thread knows where it came from. Pretty typical SDL
What is SDL? I parse it a Simple Directmedia Library...
classes will look like;
<snipped>
I really hope this helps because I can see the inductive leap required to get over the chasm of despair.
Yes, this demonstrates what you're doing quite clearly. But, it also demonstrates the weakness that the logic is switch-based, which is kind of what C++ was invented to circumvent... If you can bind the code-to-be-excuted to the content of the message, then the need to inspect the message and make a decision is removed, and this is an advantage you could derive from a method request model. I do now understand your separation of threads from objects.
I only have one more esoteric observation to make. The "Method Request" model of execution is nice and familiar to us. It works brilliantly - mostly. Return addresses are managed automagically for us. But return addresses on a CPU stack are pretty meaningless when it comes to inter-thread communication. With the "Method Request" model we are trying to "call" across thread boundaries - IMHO thats just wrong.
I can't agree with this. The proxy objects in the active object wrapper demonstrate one way to pass call information between threads - I don't see why the return information cannot be managed in the same way... Of course, you can't return to an arbitrary place in the execution - method addressses would have to be used.
With a bunch more scaffolding this is what my reactive_object code looks like;
int db_interface::transition( machine_state<READY>, typed_bind<interface_open> & ) { client.insert( sender() );
send( status, sender() );
return READY; }
This seems very nice, although it seems to be more about the state machine code than the communicating objects.
Apologies if this is all badly presented. I have a huge body of code from which the ActiveObject portion would be impossible to remove. A major reason for starting or contributing to this thread is that I think my existing code desparately needs boostifying and the best way (or even a good way) is beyond me. Hence our messages.
I understnad what you're doing now. What are the drawbacks you want to address in your code?
Cheers, Scott
ps: the sample code from mark blewett looks very promising?
Yes. Although from my point of view, it has the same drawback with switching on messages that you have. I wonder if the queue of messages in the servant class could be a queue of fully-bound function calls, generated by proxy objects which describe interfaces? (Yes, I am quite enamoured of that idea :)) Matt.