POA support in PyORBit



I have added support for creating servants with POA in PyORBit now.  I 
decided on using POA rather than a custom object adaptor for two 
reasons: (1) that's what the example code I found used (Martin's 
guile-gobject and the previous orbit bindings), and (2) that's what the 
Python language mapping documents.

With some bad hacks, I have even managed to get in process C and Python 
code to communicate with each other (I can get C code to call Python 
servants which in turn call a C servant, or vice versa).  Here is a 
description of what I do:

   1. I create a custom PortableServer_ClassInfo struct for each
      interface I will create a servant for.  I don't call
      ORBit_register_classinfo(), so as to not screw up the C servants.
       The class id in the classinfo struct is left as zero.
   2. The classinfo struct specifies a "small_relay_call" that looks up
      the method to call by name, and returns a generic call marshaller
      that can call the Python method.
   3. The vepv for the servant has length 2.  The first entry is the
      standard base epv, while the second is an epv that is as large as
      the largest epv required by the interface, or any of its bases.
       The second epv is left blank.
   4. I create a vepvmap designed to map all class ids to vepv index 1
      (the empty epv).  This bit is a hack, since if the highest class
      id overruns my vepvmap, then bad things will probably happen.
       Currently I am using a 512 entry vepvmap (which isn't that much
      memory, as it can be shared by all Python servants).
   5. When creating a Python servant, I set its classinfo to the custom
      classinfo struct, and the vepv to the fake vepv for the interface.

With this setup, the "fast locals" branch in the stubs never activates 
for Python servants.  Consider this expression in the stub:
  (_ORBIT_epv = (POA_PyORBit_TestCall__epv *) ORBIT_STUB_GetEpv(_obj, 
PyORBit_TestCall__classid))->op1)

The ORBIT_STUB_GetEpv() macro will look up the class id in the vepvmap 
(which will return 1 for any class id), and then get that epv from the 
vepv.  It then looks up the operation in the epv, which will be a NULL 
pointer, as the dummy epv had been initialised to zero.

So the fast local branch of the stub gets skipped, and 
ORBit_small_invoke_stub_n() gets called, which in turn calls my Python stub.

What I would like to know is if there is a better way to do this without 
writing a new object adaptor.  What I have at the moment works fairly 
well, but if it is possible to clean this up a little, I wouldn't mind 
doing so.

James.

-- 
Email: james@daa.com.au              | Linux.conf.au   http://linux.conf.au/
WWW:   http://www.daa.com.au/~james/ | Jan 22-25   Perth, Western Australia. 






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]