Boost logo

Boost :

From: Matthew Vogt (mvogt_at_[hidden])
Date: 2004-03-01 18:00:44


scott <scottw <at> qbik.com> writes:

> I should be careful here that I'm not just adding confusion. In this
> context "Method Request" and "synchronous method call" are used to
> refer to the same thing. A model of execution involving (typically)
> use of a machine stack and pointer to implement auto "jump and return"
> behaviour.
>

Yes, I realise I've also been confusing things here. There are two different
aspects to a 'method request': the C++ syntax for requesting the act, and
the underlying machine code generated to perform the act. What I want to
see here is the former retained through overloading of operator(), while
transparently transforming the code generated into something that works
across thread boundaries.

> Servant code (i.e. the callbacks is executed in response to the
> de-queueing of messages. If such a callback was to make a "Method
> Request" to another active object, how does your model of execution
> cope with this? In the SDL world the callback typically terminates
> and you enter a "waiting for the next message" state (just like a
> GUI message pump). That next message is hopefully the results of your
> previous request, but could be many things including error messages.
>

Yes, I envisage things in the same way. Although with the exception that
I want the messages to be automatically routed to a function that can deal
with them, rather than having to go through a message inspection switch.
In this way, there is no 'next message' in a sequential sense - the next
message that arrives in the object's queue will go to its pre-defined
destination, and when the response you're referring to arrives, it too will
go its own destination.

> The closest thing to a "return address" in this model is the active
> object that sends a message, i.e. every message sent is augmented with
> who the sender was. In the ActiveObject (pattern) model the return
> address is the address of the next machine instruction after the
> Method Request.
>

Yes. Although, the sender could bind a return address into the call in this
model also - it would have to be the address of a method in the sender. This
would allow the automatic routing that I think is preferable to messages.
This model is still working by passing messages, mind, but the messages have
extra data with them to skip the dispatch processing.

> What were you going to do with that? Continue execution? But you would
> be forced to wait for the async return of results. Do you have some way
> of suspending the current callback and allowing others to run? Then when
> the current response arrives, resuming execution at that machine code
> address? Of that particular execution frame (there may be multiple
> pending instances)?
>

I'm not suggesting anything other than a message queue wait loop.

> > 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...
>
> Erm, yes. Admirable but for some strange reason they havent removed the
> keyword yet. Until they do I will exploit the efficiencies therein.
> Have I shown you my collection of "goto"s yet?
>

I'm not referring to inherent harmful-ness, just that switching to dispatch
messages is more cumbersome and error-prone that binding the dispatch address
into the message. Provided your syntax makes the binding clean and easy, of
course.

> In my particular circumstance there is _no way_ to implement
> this switch as a compile-time activity (even though I so wanted to).
> The major reason is that I (well actually a scheduler) must dispatch
> the message to a callback based on a runtime integer.
>
> Integer? Small, set of known possible value? Well switch will do for
> the moment
>

I must be missing something here. I can't see why you must have

client: send message 5 to server
server: if (message == 5) perform function

instead of:

client: send message 5 to server.handler_for(5)
server: perform function

which can be made equivalent to the semantically easier:

client: invoke "service" on server
server: perform function

Obviously this is a trivialisation, but I don't see what I'm missing.

> > 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.
> >
>
> Yes see were you are coming from. Suspect that our directions and
> understandings separate around "model of execution" (machine call
> vs SDL send) and that this is another symptom. If you can make it
> work then I think I can see that the result would be "more intuitive".
>

Yes. I hope I've cleared up my understanding of the model of execution?

> Thank you. That could be the best (unintentional) compliment I could
> hope for. If you have other code that accepts an inbound object,
> remembers who sent it and responds with an object containing the lastest
> status - and all across thread boundaries - and a reviewers response is
> essentially "where has the comms gone"; then my work here is done
>

Not unintentional :) But, as I see it, you have removed the comms *mechanism*
from visibility. To go one step further would be to model the comms purely
as method requests (in the sense of operator() ), and remove the comms
existence from visibility...

> > I understnad what you're doing now. What are the drawbacks
> > you want to
> > address in your code?
>
> Thanks for the question. I will roll the response into a new subject.
> I think.

I look forward to seeing your next message.

Matt


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk