[tahoe-dev] [tahoe-lafs] #839: Copying directories containing caps from the future

James A. Donald jamesd at echeque.com
Tue Nov 24 08:09:13 UTC 2009

Zooko Wilcox-O'Hearn wrote:
> On Monday, 2009-11-23, at 17:51 , James A. Donald wrote:
>> As always, I recommend Microsoft's MIDL/com as a example of general 
>> purpose, future proof, protocol negotiation for binary complied 
>> objects.  Microsoft has been the technology leader in this field and 
>> is worthy of imitation.
> Huh, that's interesting.  Could you summarize for us the engineering 
> lessons, or point to some source which does?

Unfortunately this, and the assemblies that are a continuation of it in 
new technology, is generally described in rather too many alarmingly fat 
and densely written books, which are probably sitting unread on your 
bookshelf and threatening to cause it to collapse.

So, brutally oversimplifying, and sacrificing accuracy to focus on 
protocol negotiation, as it was in old days, (it has since become more 
complex, and at the same time arguably considerably more restrictive, 
though others might disagree.  Maybe I am old fogy who longs for the 
good old days of assembly)

IDL, interface description language describes the  object interfaces of 
of your object class.  An IDL file can be compiled into a C++ header and 
skeleton code file, and into everything needed to make the object 
accessible from c++ and several scripting languages.

Compilation of a single idl file generates the header files for both 
sides, for the caller and the callee, guaranteeing that they are 
equivalent, though for various reasons they cannot be identical.

The object class receives a long probabilistically globally unique 
identifier, and a human readable name that need not be unique, and when 
installed on a computer, it will receive a local name unique to that 
computer and global to all processes on that computer.  Similarly for 
each of the interfaces, which also get globally unique indentifiers and 
so forth.  To be useful, an object supports a few standard interfaces 
that almost all objects support, and one or more special interfaces 
unique to that particular class of object, which do the particular stuff 
that the class was created for.  So any useful object supports at least 
two interfaces, and often an alarmingly large number of interfaces.

When a program, compiled at one time by one person, talks to an object, 
compiled at another time by another person, it uses the protocol 
negotiation interface, which all such objects support, to ask if the 
object supports the interface it wants.

What is supposed to happen, though there is no enforcement of this, and 
probably cannot be enforcement of this, is that if the object and the 
program both recognize the interface globally unique indentifier, then 
the interface was on both sides was supposedly compiled from 
corresponding header files generated by the idl, and are supposedly 
guaranteed to be able to understand each other correctly.

Conversely, if there is a problem, it fails right at the beginning, with 
  the relatively usable error message that it cannot get an interface of 
the desired type.

Typically what happens is you (the program) get a starting object 
somehow, and then you ask for an interface that you understand, and if 
you get that interface you use it to ask for another object, rinse and 
repeat until you get from the object you have to the object you really 
want and the interface you really want.  In C++ this results in an 
alarmingly large pile of boilerplate resource management code and object 
lifetime and ownership issues, which issues do not directly correspond 
to the issues likely to be encountered with capabilities.  In script 
languages, memory management magically takes care of these.

If you want to extend an existing type of object, and not break existing 
code, you add another interface, which often differs from the previous 
interface by just a single additional function.  There is very little 
overhead in supporting numerous slightly different interfaces, only one 
of which is likely to be actually used at any run time.  Old code will 
ask for the old interface, and newer code will ask for the newer interface.

More information about the tahoe-dev mailing list