Next: , Previous: The EnhancedString Module, Up: Ex-DB Design



4.5 The Active Object Wrapper

The active object wrapper that MOZ uses is one of the more complicated pieces of code in the MOZ, as well as the piece that may seem oddest to users of other object oriented langauges. Also, it is the largest piece of ex-db code.

The active object wrapper is actually a procedure that is passed an object. It returns an object record with full capabilities. An object record consists of a wrapper procedure, the objects Oz name, and a capability set. All the wrapper procedure does is pass its one argument to a port (an Oz port, not a TCP/IP port).

It's what's at the other end of that port that's interesting. A thread is created to process the stuff passed in the port. Note that this means that each object has exactly one thread associated with it, and this thread is the only one that ever gets to affect the object directly. This make things much easier as far as multi-threading issues go, as no locking needs to be done within object methods.

This wrapper also gives insultion: no-one ever sees the object directly except this thread, and this is what allows the capability security system to work.

Also, the thread can do other processing besides just calling the method it has been passed. The most important part of this processing is capability processing. Basically, what's passed to the port is not the method name, it's a record with an Oz name for a label. This label is used to key a dictionary, and if a method name associated with it is found, that method is called, if not, an error is returned. For more information, see See Capability Implementation.

Another, much cooler, thing that the wrapper thread does is handle upgrade requests. upgrade is a virtual method, in that it is called just like any other method in the wrapper, using an Oz name capability, but it doesn't exist in the object, rather it exists in the wrapper. An upgrade call takes a class name and actually swaps out the object it's wrapping for one of that class! It calls toRecord and fromRecord to make sure information is preserved, and lets the Storage object know the new class name. Then it just goes back to processing the port like nothing happened, and from the point of view of every other object in the mud, nothing did!

There are a couple of other miscellaneous things the wrapper does. In particular, it inserts capability information into a toRecord call and extracts it from a fromRecord call.

When a new object is created, the capability dictionary is built using the class's methodList feature, with the addition of the special capability 'upgrade', and a bunch of new Oz names. In many cases, these are then overwritten by a fromRecord call.

The object itself will often need to know about its wrapper and capabilities, so that it can inform other objects. This is handled by a method on every object in the MOZ called activeObjectInform, which takes those two pieces of information as arguments, generally to store on attributes. This method is called every time wrapper information is changed.

The Storage object is also informed of this information at the same time.

See General Class Issues.