README.lcr 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. Live Component Replacement
  2. --------------------------
  3. All software is composed of components, which contain multiple software classes.
  4. Components generally depend upon other components and sometimes classes from
  5. other components.
  6. Some components of openais are the evt service, the ckpt service, the clm
  7. service, the totem protocol, and others. If a defect is found in any of
  8. these components, the entire ais executive must be stopped, replaced, and
  9. restarted.
  10. The lcr code formalizes the concept of components into dynamic libraries. A
  11. component may have multiple classes. Each class (the lcr code uses the word
  12. interface) may have multiple functions within the class. Each interface may
  13. depend upon other interfaces, and those interfaces are then loaded prior to the
  14. requested interface being referenced.
  15. A list of shared objects is scanned each time an interface is requested to
  16. load via the following interface:
  17. int lcr_ifact_reference (
  18. void **handle,
  19. char *iface_name,
  20. int version,
  21. void **interface,
  22. void *context);
  23. The iface_name is the name of the interface, the version is the version,
  24. the void **interface is the list of functions returned once the interface
  25. has been dynamically loaded and referenced, and context is passed to the
  26. constructor and destructor.
  27. The interface is loaded, the interface constructor is called, and the list
  28. of interfaces is returned back to the caller.
  29. First the list of interfaces is described in an iface_list data structure:
  30. struct iface_list iface_list = {
  31. .iface1_func1 = iface1_func1,
  32. .iface1_func2 = iface1_func2,
  33. .iface1_func3 = iface1_func3,
  34. };
  35. iface1_func1 is a simple function call.
  36. Then the lcr_iface data structure is defined for the c file:
  37. struct lcr_iface iface1_ver0 = {
  38. .name = "iface1",
  39. .version = 0,
  40. .versions_replace = 0,
  41. .versions_replace_count = 0,
  42. .dependencies = 0,
  43. .dependency_count = 0,
  44. .constructor = iface1_constructor,
  45. .destructor = iface1_destructor,
  46. .interfaces = (void **)&iface_list,
  47. };
  48. The name and version fields provide naming and versioning. The constructor
  49. and destructor functions execute at reference and release times. Finally
  50. the .interfaces type describes the list of functions used for the interface.
  51. Next, an lcr_comp must be described:
  52. struct lcr_comp test_comp = {
  53. .iface_count = 2,
  54. .ifaces = lcr_ifaces
  55. };
  56. the iface count describes the number of interfaces within the component,
  57. and lcr_ifaces is an array of pointers to lcr_iface data types.
  58. The final step is to export a function which tells the LCR referencing code
  59. about all of this static data that is setup:
  60. extern int lcr_comp_get (struct lcr_comp **component)
  61. {
  62. lcr_ifaces[0] = iface1_ver0;
  63. lcr_ifaces[1] = iface1_ver1;
  64. *component = &test_comp;
  65. printf ("in lcr_comp_get for test component, address %p\n", &test_comp);
  66. return (0);
  67. }
  68. Now the component can be referenced and used in another application.
  69. int main ()
  70. {
  71. .....
  72. lcr_ifact_reference (
  73. &ifact_handle_ver0,
  74. "iface1",
  75. 0, /* version 0 */
  76. (void **)&iface_ver0,
  77. (void *)0xdeadbeef);
  78. iface_ver0->func1();
  79. iface_ver0->func2();
  80. iface_ver0->func3();
  81. }
  82. See libtest for a sample component and test.c for an example program which
  83. exercises the component.
  84. On startup, a thread is created which listens for requests from the "uic"
  85. application. These requests are then processed by the lcr service which
  86. would execute a live replacement.
  87. There is alot of stuff which isn't done, and if you want to try out this code,
  88. you will have to modify the path to the dynamic library that is loaded.