
Hi, I have been working on a small library that has become reasonably useful and possibly of interest to someone else. It's also become fairly large. I am quite interested in this library getting "boosted" but even given that there is substance to the library its scope is a bit of a problem; its quite large. It was started as a project with requirements very similar to those associated with the ActiveObject pattern; http://citeseer.nj.nec.com/lavender96active.html (reference from J. Garland) and takes many cues from the concepts and primitives found in SDL; http://www.sdl-forum.org/ Its possible to characterize this library as the basic building blocks for clean, robust multi-threading <ahem>. It could also be characterized as a subset of TAO, i.e. CORBA. While its a very small subset <sheepish grin>, maybe these comments gives scale to the scope issue. A breakdown of the incidental technologies tackled by this library follows; * multi-threading building block classes * network representation of structured data (variants) * saving and loading of network data (persistence) * interactive machines (inter-thread messaging) * stateless and stateful machine representation * code generation of network data and machine skeletons * message forwarding (distributed messaging) * transparent remote machines (proxies for inter-process messaging) * support for multiple encodings, e.g. binary, text, XML... To flesh this list out into something less opaque, a set of file fragments follows. These are the result of applying the library to the test case pushed around in the recent thread "Simple Active Object". They are necessarily abbreviated; // --------------------------------- // db_server.tms (the schema) // record configuration { // Persistent portion of the db_server string data_source integer maximum_workers integer maximum_clients } record open {} // Messages between the server and its clients record close {} record select { string sql_statement } record busy {} state INTIAL, // Pre-defined READY, // Normal operation OVERLOADED, // All workers busy OUT_OF_SERVICE // Something went wrong // Define the messages expected in the // different states transition INITIAL void // Standard startup transition READY open, // Another client connecting close, // Client closing configuration, // Reconfiguration select // An SQL select statement .. // --------------------------------- // db_server.h (auto-generated header) // .. #define db_server_configuration_hash 0x03493ac9 #define db_server_open_hash 0x7a6ffa00 #define db_server_close_hash 0x1093ac66 #define db_server_select_hash 0x004410ac #define db_server_busy_hash 0x74529711 struct typed03493ac9 { .. string &data_source; long &maximum_workers; long &maximum_clients; .. }; struct db_server { .. enum { INITIAL, READY, OVERLOADED, OUT_OF_SERVICE }; typedef typed03493ac9 configuration; typedef typed7a6ffa00 open; typedef typed1093ac66 close; typedef typed004410ac select; typedef typed74529711 busy; virtual int transition( typed_state<INITIAL> ) = 0; // void message virtual int transition( typed_state<READY>, typed_bind<open> & ) = 0; virtual int transition( typed_state<READY>, typed_bind<close> & ) = 0; virtual int transition( typed_state<READY>, typed_bind<configuration> & ) = 0; virtual int transition( typed_state<READY>, typed_bind<select> & ) = 0; int machine( typed_word & ); // The auto-generated switch statements .. }; .. // --------------------------------- // my_server.cpp (application declaration of db_server) // #include "db_server.h" class my_server : public state_machine<db_server> { typed_memory_folder home; db_server configuration; address_group client; virtual int transition( typed_state<INITIAL> ); virtual int transition( typed_state<READY>, typed_bind<open> & ); .. }; // my_server.cpp (application definition of db_server) // my_server::my_server() : home( "configuration\\my_server" ) { try // Persistence { load( home, configuration ); // Recover previous image } catch( ... ) { // Not found. Set factory defaults configuration.data_source = ""; configuration.maximum_workers = 4; configuration.maximum_clients = 100; save( home, configuration ); } } int my_server::transition( typed_state<INITIAL> ) { if( data_source.empty() ) { return OUT_OF_SERVICE; } if( ... ) // Attempt to connect to RDBMS { return READY; } return OUT_OF_SERVICE; } int my_server::transition( typed_state<READY>, typed_bind<open> &s ) { client.insert( sender() ); reply( configuration ); } .. int my_server::transition( typed_state<READY>, typed_bind<select> &s ) { if( ... ) // Find an idle worker { // Submit request to worker .. return READY; } reply( busy() ); return READY; } Hopefully these fragments have been enough to sketch out the intent of the library and where it currently is "at". As a bunch of materials, it is a .lib, headers and a .exe (the schema parser+generator) There are (serious) pretentions to platform independence but current materials are for Windows. I am very happy to work towards a boosted version of a subset of this work cos basically it seems too large to be a prospect otherwise. This subset would be in the area of mutli-threading building block classes, i.e. an "alternate threading model". However, after the recent exchange of related and interesting messages, I felt compelled to "come clean" with some background. So, to Matthew and Mark. Are you interested in dicsussing the possible implementation of; * simple active objects (completion of current alternate threading model) * simple reactive objects (completion of current with two-way calling of methods) * something else? Cheers, Scott

On Tue, 2 Mar 2004 11:49:50 +1300, scott wrote
I have been working on a small library that has become reasonably useful and possibly of interest to someone else. It's also become fairly large.
I am quite interested in this library getting "boosted" but even given that there is substance to the library its scope is a bit of a problem; its quite large. It was started as
In general, large libraries are a problem in boost -- for lots of reasons. I'd encourage you to break things down into useable pieces and focus on getting the most useful parts boostified. If it is really large, it will be a long road...
...snip.... A breakdown of the incidental technologies tackled by this library follows;
* multi-threading building block classes
Yes, you'all have been discussing some interesting possible extensions for AO and such. Sorry I haven't been able to keep up with all of it. Anyway, these would be a nice contribution in my view.
* network representation of structured data (variants)
How different from boost.Variant?
* saving and loading of network data (persistence)
Robert Ramey has done a huge amount of work on this -- have you checked it out? This library has been through one review cycle and I believe Robert has now addressed all the big concerns. My sense is that his library is the 'one' for persistence.
* interactive machines (inter-thread messaging)
Another needed extension of boost.threads all would agree.
* stateless and stateful machine representation
How does this contrast with the boost.fsm (finite state machine) implementation in the boost-sandbox by Andreas Huber? I think the project has been dormant for awhile although I notice the docs page was update in Feb 2004. Anyway, it is quite interesting.
* code generation of network data and machine skeletons
Not sure this would really be appropriate for a boost library...
* message forwarding (distributed messaging) * transparent remote machines (proxies for inter-process messaging)
Are you talking about multi-cast messaging, publish-subscribe, method invocation, or what?
* support for multiple encodings, e.g. binary, text, XML...
Also covered by the persistence library.
...snip example...
I am very happy to work towards a boosted version of a subset of this work cos basically it seems too large to be a prospect
Agree.
otherwise. This subset would be in the area of mutli-threading building block classes, i.e. an "alternate threading model". However, after the recent exchange of related and interesting messages, I felt compelled to "come clean" with some background.
Hmm, hope I'm not jumping in in the middle without context. In any case, I'm agreeing with the need to focus. Jeff

"Jeff Garland" <jeff@crystalclearsoftware.com> wrote
* stateless and stateful machine representation
How does this contrast with the boost.fsm (finite state machine) implementation in the boost-sandbox by Andreas Huber? I think the project has been dormant for awhile although I notice the docs page was update in Feb 2004. Anyway, it is quite interesting.
Work on FSM is in progress. It only looks dormant. /Pavel

Jeff Garland <jeff <at> crystalclearsoftware.com> writes:
How does this contrast with the boost.fsm (finite state machine) implementation in the boost-sandbox by Andreas Huber? I think the project has been dormant for awhile although I notice the docs page was update in Feb 2004.
I've just stopped announcing intermediate versions on the boost list. Otherwise the project has been as active as a one man spare-time-only project can be. I think I'll have a complete release (code, examples, tutorial, reference, etc.) by mid-March at the latest. I will then make an announcement in all relevant news groups. If feedback is as I hope then I'll ask for a formal review... Regards, Andreas

On Tue, 2 Mar 2004 13:54:13 +0000 (UTC), Andreas Huber wrote
Jeff Garland <jeff <at> crystalclearsoftware.com> writes:
How does this contrast with the boost.fsm (finite state machine) implementation in the boost-sandbox by Andreas Huber? I think the project has been dormant for awhile although I notice the docs page was update in Feb 2004.
I've just stopped announcing intermediate versions on the boost list. Otherwise the project has been as active as a one man spare- time-only project can be.
Great, I'm glad to hear it. And, believe me, I understand why these sorts of projects take time...
I think I'll have a complete release (code, examples, tutorial, reference, etc.) by mid-March at the latest. I will then make an announcement in all relevant news groups. If feedback is as I hope then I'll ask for a formal review...
Super. I was looking at some of the docs and examples last night. Anyway, looks like things are progressing well to me :-) Jeff

[mailto:boost-bounces@lists.boost.org]On Behalf Of Jeff Garland Sent: Tuesday, March 02, 2004 4:14 PM
In general, large libraries are a problem in boost -- for lots of reasons. I'd encourage you to break things down into useable pieces and focus on getting the most useful parts boostified. If it is really large, it will be a long road...
Ah. Another long and winding road.
* network representation of structured data (variants)
How different from boost.Variant?
Significantly. Boost version I understand to be a template that brings much compile-time checking to the world of discriminated union containers. Very nice. My variant implements something like an interpreter's type system; complete with symbols tables and type codes. The variant's type system has builtin types, e.g. void, integer, time, float and list, but arbitrarily structured types can also be constructed. e.g.; typed_word word( list_type() ); // Ctor builtin list type typed_memory &memory = word; // Get underlying vector symbol_table table; // Symbolic info memory.push_back( "" ); // Build the memory version memory.push_back( 4 ); memory.push_back( 2 ); // Build the symbol info table.push_back( typed_symbol( "data_source", string_hash ) ); table.push_back( typed_symbol( "maximum_clients", integer_hash ) ); table.push_back( typed_symbol( "maximum_workers", integer_hash ) ); word.make( typed_record( "configuration", table ) ); // New type with unique discriminator The call to the "make" method installs all kinds of type-system information into some supporting data structures. That info is used in all sorts of places - serialization, diagnostics and error handling. This may sound like a computationally intensive variant but it isnt. Perfomance o/hs are the same as for any other discriminated union, it just allows the creation of new discriminators. Resorting to the symbolic info is on a "where it would be really cool to know" basis. Note: direct use of make is non-existent in clients of the wider library. Code such as that shown is auto-generated from the schema. Considered both boost.variant and boost.any. Failed to kickstart. BTW: The discriminator is a stable hash value derived from a name mangling of the symbol table and hashing (weinberger) of resultant string
* saving and loading of network data (persistence)
Robert Ramey has done a huge amount of work on this -- have you checked it out? This library has been through one review cycle and I believe Robert has now addressed all the big concerns. My sense is that his library is the 'one' for persistence.
Did check this also. My understanding at the time was that it was a facillity driven by the C++ class info, i.e. the locus of control was the C++ type system (perfectly valid and correct of course :-). Most obviously, my locus of control is the "variant type system". This is something of a simplification; maybe boost.serialization could have been used. I think it is at least reasonable to say that it would have complicated the wider library. At the time I looked I admit that I was somewhat overloaded.
* stateless and stateful machine representation
How does this contrast with the boost.fsm (finite state machine) implementation in the boost-sandbox by Andreas Huber? I think the project has been dormant for awhile although I notice the docs page was update in Feb 2004. Anyway, it is quite interesting.
Looked at the ability to generate state machines from mpl::lists and was involved in some exchanges with Andreas re: his sandbox work. There were couple of reasons I did not incorporate these, neither of which preclude their introduction later on. At the time both my library and Andreas library were work-in-progress. Andreas work is much more formal - something that I would love to benefit from at a later date. The transition_table example using mpl was very interesting. As my state machines are typically driven by schema-generated "events" (i.e. variant hash values) it was pretty easy to extend the generator to accept an FSM (informal) that could refer to the events conveniently. The output of the generator could have been mpl-based. Seemed too cute though; a generator outputting an MPL representation that generated the state machine at compile time. I could just about imagine the eyebrows raised for that one.
* message forwarding (distributed messaging) * transparent remote machines (proxies for inter-process messaging)
Are you talking about multi-cast messaging, publish-subscribe, method invocation, or what?
A reasonable first take on my library is that it implements the ActiveObject pattern. It allows software objects to be implemented that can exchange messages asynchronously. Message forwarding and proxy machines allow the software objects involved in an exchange of messages to be distributed over separate processes and machines.
Hmm, hope I'm not jumping in in the middle without context. In any case, I'm agreeing with the need to focus.
No worries. Cheers, Scott

On Wed, 3 Mar 2004 13:00:30 +1300, scott wrote
* network representation of structured data (variants)
How different from boost.Variant?
Significantly. Boost version I understand to be a template that brings much compile-time checking to the world of discriminated union containers. Very nice.
My variant implements something like an interpreter's type system; complete with symbols tables and type codes. The variant's type system has builtin types, e.g. void, integer, time, float and list, but arbitrarily structured types can also be constructed.
So you are able to build new types at runtime? Doesn't sound like it below....
...snip example...
I have to say the code snippets aren't helping my understanding much :-(
The call to the "make" method installs all kinds of type-system information into some supporting data structures. That info is used in all sorts of places - serialization, diagnostics and error handling. This may sound like a computationally intensive variant but it isnt. Perfomance o/hs are the same as for any other discriminated union, it just allows the creation of new discriminators. Resorting to the symbolic info is on a "where it would be really cool to know" basis.
It sounds like a runtime reflection engine to support things like factory functions?
Note: direct use of make is non-existent in clients of the wider library. Code such as that shown is auto-generated from the schema.
Sounds more and more like a kind of reflection...
Considered both boost.variant and boost.any. Failed to kickstart.
Because they were limited by the ability to provide a factory function? Full type reflection info? What was the essential limitation...
* saving and loading of network data (persistence)
Robert Ramey has done a huge amount of work on this -- have you checked it
Did check this also. My understanding at the time was that it was a facillity driven by the C++ class info, i.e. the locus of control was the C++ type system (perfectly valid and correct of course :-).
Most obviously, my locus of control is the "variant type system". This is something of a simplification; maybe boost.serialization could have been used. I think it is at least reasonable to say that it would have complicated the wider library.
Well, I'm sure the serialization library could be adapted to your case if you have full type information.
At the time I looked I admit that I was somewhat overloaded.
Fair enough.
* stateless and stateful machine representation
How does this contrast with the boost.fsm (finite state machine) implementation in the boost-sandbox by Andreas Huber? I
Looked at the ability to generate state machines from mpl::lists and was involved in some exchanges with Andreas re: his sandbox work. There were couple of reasons I did not incorporate these, neither of which preclude their introduction later on. At the time both my library and Andreas library were work-in-progress. Andreas work is much more formal - something that I would love to benefit from at a later date. The transition_table example using mpl was very interesting. As my state machines are typically driven by schema-generated "events" (i.e. variant hash values) it was pretty easy to extend the generator to accept an FSM (informal) that could refer to the events conveniently. The output of the generator could have been mpl-based. Seemed too cute though; a generator outputting an MPL representation that generated the state machine at compile time. I could just about imagine the eyebrows raised for that one.
Ok...
* message forwarding (distributed messaging) * transparent remote machines (proxies for inter-process messaging)
Are you talking about multi-cast messaging, publish-subscribe, method invocation, or what?
A reasonable first take on my library is that it implements the ActiveObject pattern. It allows software objects to be implemented that can exchange messages asynchronously
Message forwarding and proxy machines allow the software objects involved in an exchange of messages to be distributed over separate processes and machines.
Ok. Well there is obviously some sort of networking infrastructure including a event dispatching as well. Again, these are items that are needed in boost, have had prior work (in the sandbox), but aren't ready for primetime yet. The bottom line for me is that your 'library' seems like alot of libraries that are tightly stitched together with a fairly narrow scope. I suspect they would be very difficult to boostify since they can't be pulled apart easily. Not saying that it isn't a useful framework and I'm not trying to discourage you, but at first blush it doesn't seem like a good fit with Boost 'out of the box'. I for one am much more interested in minimalist components that can be put together flexably into larger components b/c most of the 'all-in-one' frameworks usually are problematic to integrate into larger solutions. Anyway, I'm still interested in a basic Active Object on top of the thread library :-) Jeff

[mailto:boost-bounces@lists.boost.org]On Behalf Of Jeff Garland Sent: Wednesday, March 03, 2004 2:25 PM To: boost@lists.boost.org Subject: RE: [boost] [Threads] Reactive Objects
My variant implements something like an interpreter's type system; complete with symbols tables and type codes. The variant's type system has builtin types, e.g. void, integer, time, float and list, but arbitrarily structured types can also be constructed.
So you are able to build new types at runtime? Doesn't sound like it below....
...snip example...
I have to say the code snippets aren't helping my understanding much :-(
Yes, I can understand that. Probably too much ground to cover here and its not helping the degree of focus. So I'll return to the Active Object topic.
Anyway, I'm still interested in a basic Active Object on top of the thread library :-)
Exactly, Scott

Jeff Garland <jeff <at> crystalclearsoftware.com> writes:
A reasonable first take on my library is that it implements the ActiveObject pattern. It allows software objects to be implemented that can exchange messages asynchronously
Message forwarding and proxy machines allow the software objects involved in an exchange of messages to be distributed over separate processes and machines.
Ok. Well there is obviously some sort of networking infrastructure including a event dispatching as well. Again, these are items that are needed in boost, have had prior work (in the sandbox), but aren't ready for primetime yet.
This in particular seems to be a big stretch of scope. I think it would be brave to try to put network-transparent messaging into boost.threads, without first going through an inter-thread messaging stage. The network-related code in the sandbox does look promising, even if it hasn't had much obvious development in recent times. Getting networking into boost as a subset of an object communication library would seem to be putting the cart before the horse, given the general applicability of networking code. Anyone care to comment on the general status of the network code in the sandbox?
The bottom line for me is that your 'library' seems like alot of libraries that are tightly stitched together with a fairly narrow scope. I suspect they would be very difficult to boostify since they can't be pulled apart easily. Not saying that it isn't a useful framework and I'm not trying to discourage you, but at first blush it doesn't seem like a good fit with Boost 'out of the box'. I for one am much more interested in minimalist components that can be put together flexably into larger components b/c most of the 'all-in-one' frameworks usually are problematic to integrate into larger solutions.
Well, if the layers of the larger library are cleanly separated, the parts that deal specifically with threads, and with inter-context messaging should be fairly independent of the state machines, code generators and message objects layered on top of them?
Anyway, I'm still interested in a basic Active Object on top of the thread library
What aspect are you interested in? The pattern, as per Schmidt? I don't think there's a lot of detail in that, it would be interesting to know what boost could offer. Otherwise, Scott and I have been discussing interactions based purely on message passing between objects, utilising a separation between 'servant' and 'scheduler' that is reminiscent of the active object pattern (also, the guarantee of only one thread active in a single object's bounds is similar). Is this more like what you're interested in? Matt

[mailto:boost-bounces@lists.boost.org]On Behalf Of Matthew Vogt
Ok. Well there is obviously some sort of networking infrastructure including a event dispatching as well. Again, these are items that are needed in boost, have had prior work (in the sandbox), but aren't ready for primetime yet.
This in particular seems to be a big stretch of scope. I think it would be brave to try to put network-transparent messaging into boost.threads, without first going through an inter-thread messaging stage.
Works for me. <snip>
Otherwise, Scott and I have been discussing interactions based purely on message passing between objects, utilising a separation between 'servant' and 'scheduler' that is reminiscent of the active object
Yep. And the following is pasted in from the other thread; thought I would try to pull it all together. Apologies for loss of indentation.
Anyway, I think some reasonably clean syntax can be found to bind both the arguments and the return address into the function call, provided that the return address is a method in the invoking object.
Well, after some fiddling, the best I can manage is: class SomeClass { public: std::string value(int id) { return "foo"; } } class ThatServant : public reactive<ThatServant>, private SomeClass { public: ThatServant() : getValue(&ThatServant::value, this) {} method<std::string (int)> getValue; }; class ThisServant : public reactive<ThisServant> { public: void findAndStoreValue(ThisServant& other, int id) { (return_to(&ThisServant::storeValue, this)) = other.getValue(int); } private: void storeValue(std::string value) { ... } } Got that. I have to leave it up to you. We seem to have worked through one major area of conceptualizing; schedulers and servants. These take a big whip to the business of taming threads. We are now at the point of deciding how these beasts will communicate amongst themselves. Is it to be "method-based" or "message-based"? I can see that your baby will sing but so does messaging. If we can agree on something here then we would have a complete target for something built on boost.thread, i.e. there are no other "areas"? Cheers, Scott

scott <scottw <at> qbik.com> writes:
Got that. I have to leave it up to you. We seem to have worked through one major area of conceptualizing; schedulers and servants. These take a big whip to the business of taming threads. We are now at the point of deciding how these beasts will communicate amongst themselves. Is it to be "method-based" or "message-based"? I can see that your baby will sing but so does messaging.
Method-based can be layered above messages, if the messages support the concept of having their dispatch addresses potentially pre-bound. The scheduler of the message-driven system can do something like: message m = dequeue(); if (m.dispatch_bound()) { m.dispatch(); } else { servant->dispatch(m); } where the unbound case calls a function that switches based on the message code or content. Then all the proxies need to do to yield a method-based interface is bind the address into the message before queueing.
If we can agree on something here then we would have a complete target for something built on boost.thread, i.e. there are no other "areas"?
I think messaging between thread contexts is a useful target.
Cheers, Scott
Matt

[mailto:boost-bounces@lists.boost.org]On Behalf Of Matthew Vogt
themselves. Is it
to be "method-based" or "message-based"? I can see that your baby will sing but so does messaging.
Method-based can be layered above messages, if the messages support the concept of having their dispatch addresses potentially pre-bound.
Yes. Nice acknowledgement of what has been staring us in the face.
The scheduler of the message-driven system can do something like:
message m = dequeue(); if (m.dispatch_bound()) { m.dispatch(); } else { servant->dispatch(m); }
where the unbound case calls a function that switches based on the message code or content.
Understand why you present this code and can see that it will deliver. Here is a question though; if we acknowledge that we are sending messages at a moment when we know what "method" we wish to call (terminology chosen for your benefit :-), couldnt we decide to send specific messages? By this I mean a different C++ type for each "method". If we also said that the callback always had the same name (e.g. process_message) then - do we not have enough to perform some compile-time dispatch trickery? struct db_open { }; struct db_select { }; .. my_db_server::process_message( db_select & ) { } Using some (pretty low-order) template trickery I think it would also be possible to default to a sane member in the event that the target machine did not declare the member with a matching signature; my_db_server::process_message( unknown_message ) { } I think the queue of messages would remain the same - type independent. Selection of the member pointer would just be happening automatically, through overloading, at the call site. I suggest this warily. It breaks the design goal I had with previous work and precludes implementation of some of the "edgy-er" active objects already discussed. But it seems damn nice if we have no such targets? To further scuttle my own suggestion :-( anything along these lines would require the sender knowing the complete type of the receiver. A design constraint I find truly distasteful. I leave those notes in, due to bloody-minded sense of completeness.
Then all the proxies need to do to yield a method-based interface is bind the address into the message before queueing.
Read and re-read this cos I was determined to not be suggesting something that you already had :-) My best guess is that I have introduced a third form of dispatch, where m.dispatch_bound() would evaluate true?
If we can agree on something here then we would have a complete target for something built on boost.thread, i.e. there are no other "areas"?
I think messaging between thread contexts is a useful target.
Wonderful. I think I might knock out a list of requirements next. Something to drive a first draft implementation. I can post this if you are interested. Cheers, Scott ps: Thoughts I have for the implementation are currently the combination of your work and Mark's. It doesnt bother me who tackles what, if anything. I will plod the long and winding road ;-)

[mailto:boost-bounces@lists.boost.org]On Behalf Of scott Sent: Thursday, March 04, 2004 1:04 PM To: boost@lists.boost.org Subject: RE: [boost] Re: [Threads] Reactive Objects
Responding to myself and
[mailto:boost-bounces@lists.boost.org]On Behalf Of Matthew Vogt
Matthew.
Then all the proxies need to do to yield a method-based interface is bind the address into the message before queueing.
Read and re-read this cos I was determined to not be suggesting something that you already had :-) My best guess is that I have introduced a third form of dispatch, where m.dispatch_bound() would evaluate true?
If we can agree on something here then we would have a complete target for something built on boost.thread, i.e. there are no other "areas"?
I think messaging between thread contexts is a useful target.
Hmmmm. Unfortunately I have run headlong into a nice, gnarly area. Thought I should visit this with you before going to the next step. If reactive objects are intended as a technique for management of threads then syntax, conventions and idioms of usage are going to be important (of course). We hadn't tackled this to any great extent, for the reactive object library. I am specifically referring to how reactive objects are to be "addressed". On first consideration it can seem to be a non-issue; the address of the recepient is the address that I am holding in this variable "db_server". The picture I have is complicated by the nature of the beast we are trying to tame; i.e. threads. I believe we have the goal of instantiating objects that are C++ representations of threads. This is not new. What _is_ possibly new (and different to the current boost::threads) is that there is an equivalence between the life of the C++ object and its thread. If the thread terminates then naturally the associated C++ object should no longer be "of the ActiveWorld". void getting_started() { my_db_server server; db_open open; server.send( open ); // <--- !!! } At the point of initiating the transmission of "open" to "server" there is no guarantee that the object still exists. At least I/we have suggested such things in recent discussions. The example code is a bad example with the automatic scope of "server" to further highlight the slight tangle that this issue creates. There is a lot of background behind the following, but rather than taking anyone on a confusing stroll through the possibillities, here is what I would propose; // Example intended to show technique rather than // final packaging. typedef unsigned long reactive_address; reactive_address server = reactive_create<db_server>(); void window::on_create() { send( db_open(), server ); } Essentially, machine addresses are verboten. They cannot be trusted. So instead there is some kind of "id", or "handle" that is the only mechanism by which a reactive object may be referred to. Code behind "reactive_create" would need to maintain a map of the pointers that we would otherwise have used. This map would be maintained in a thread-safe manner and on dtor of an object the associated map entry should be removed. The send primitive needs to perform (thread-safe) lookups. Where a message is sent to an object no longer in the map, the message falls on the floor. Ta, Scott ps: matt - you may notice that this implies type info of recipient is gone :-(
participants (5)
-
Andreas Huber
-
Jeff Garland
-
Matthew Vogt
-
Pavel Vozenilek
-
scott