README 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. /* $TOG: README /main/4 1999/08/30 10:44:07 mgreess $ */
  2. 1.8 10/27/92
  3. Copyright (c) 1992 by Sun Microsystems, Inc.
  4. TOOLTALK IMPLEMENTATION OVERVIEW
  5. This document presents a roadmap to understanding the implementation
  6. of the main message-passing features of ToolTalk 1.0.1. It does not
  7. aim to describe the details of the algorithms used. In order to find
  8. these out it is necessary to read the source code as well as the
  9. comments. This document should give the reader an overall picture of
  10. how all the various objects that implement message-passing fit
  11. together as well as familiarity with where to find the code that
  12. implements a particular feature. Finally some naming conventions used
  13. throughout the code are given.
  14. ********** Please update this document as the code is changed **********
  15. MEMORY MANAGEMENT
  16. The only memory management policy used througout the code is
  17. reference-counting. This is an automatic sort of memory management
  18. since objects are "magically" deleted when there are no longer
  19. references to them. This functionality is implemented by way of
  20. pointer classes that behave just like normal pointers except that they
  21. maintain a reference count in the object they point to. It is
  22. important *not* to mix normal pointers with counted pointers.
  23. MIXING POINTERS
  24. You should never use a C pointer with refcounted objects (i.e., those
  25. inheriting from _Tt_object (actually, from _Tt_new; I have no idea why
  26. _Tt_new and _Tt_object are different)). You should always use
  27. refcounting pointers ("ptrs") with _Tt_objects. The danger is as
  28. follows:
  29. _Tt_object *evilRef;
  30. {
  31. evilRef = new _Tt_object;
  32. //
  33. // refCount is now zero, but evilRef is pointing at our
  34. // object!
  35. //
  36. ...
  37. _Tt_object_ptr goodRef = evilRef;
  38. //
  39. // refCount is now 1
  40. //
  41. ...
  42. //
  43. // goodRef goes out of scope.
  44. // goodRef::~_Tt_object_ptr() decrements the refCount
  45. // to zero, and deletes our object because the
  46. // refCount is now zero.
  47. //
  48. }
  49. int foo = evilRef->dataMember; // core dump
  50. If you need a static pointer to a _Tt_object, you cannot have a static
  51. _Tt_object_ptr, because static C++ instances aren't allowed. But you
  52. don't want to have a static _Tt_object *, because then you have to
  53. eternally worry about never showing it to a refcounting pointer (which
  54. would try to delete it when it was done with it).
  55. The best thing to do is have a static _Tt_object_ptr *:
  56. static _Tt_object_ptr *ppGlobalObj;
  57. ppGlobalObj = new _Tt_object_ptr;
  58. *ppGlobalObj = new _Tt_object;
  59. Now you can use *ppGlobalObj wherever you would have used your static
  60. _Tt_object_ptr. The _Tt_object you allocated is safely refcounted, so
  61. you can let refcounting pointers do whatever they want with it.
  62. When it's time to clean up, you just
  63. delete ppGlobalObj;
  64. This is a call to ppGlobalObj->~_Tt_object_ptr(), which decrements the
  65. refcount of your object, and *optionally* deletes it if the refcount
  66. is zero. This way, you don't delete your object out from under anyone
  67. who still has a reference to it.
  68. REFCOUNTING INSIDE CONSTRUCTORS
  69. Inside a constructor, never assign the 'this' pointer of a refcounted
  70. object to an automatic refcounting pointer. Inside the constructor,
  71. the refcount is still zero. Assigning 'this' into a refcounting
  72. pointer will increment the refcount to 1. But before the constructor
  73. returns, the automatic refcounting pointer on the stack will be
  74. destructed. The destructor will decrement the object's refcount back
  75. to zero, and therefore delete the object -- before the constructor
  76. even returns!
  77. _Tt_foo::_Tt_foo()
  78. {
  79. // On entry, _Tt_foo::_refcount_ == 0
  80. _Tt_foo_ptr evilRef = this;
  81. // Now, _Tt_foo::_refcount_ == 1
  82. ...
  83. // On exit, evilRef->~_Tt_foo_ptr() will be called.
  84. // It will decrement the refcount to zero, and
  85. // then delete this object under construction!
  86. }
  87. Also, be sure not to pass the 'this' pointer to any routine that might
  88. hold a temporary reference to the object while the routine runs.
  89. (Here, "hold a temporary reference to" means "increment the refcount
  90. and then decrement it".) If you must pass the 'this' pointer anywhere
  91. from within the constructor, cast it to const first so that the
  92. compiler will protect you from any routine with an intention of
  93. modifying its refcount. If you absolutely must pass the 'this'
  94. pointer to a routine that might only temporarily reference it, then
  95. manually increment the refcount before doing so, and then manually
  96. decrement the refcount before returning from the constructor
  97. CYCLICAL REFERENCES
  98. Avoid creating data structures that permit cyclical references.
  99. A single reference cycle can cause a massive memory leak.
  100. COMMENT CONVENTIONS
  101. Throughout the code, any comments preceded by XXX: denote notes to the
  102. reader of problems or suggestions for the code they describe.
  103. DESCRIPTION OF OBJECT CLASSES
  104. This section presents all the object classes used to implement the
  105. message-passing portion of ToolTalk along with a brief description of
  106. what each class represents and in which files it can be found. Before
  107. describing the classes we need to mention some important naming
  108. conventions as well as some general comments about client/server
  109. conventions.
  110. Many of the object classes described below have client-side and
  111. server-side implementations. For example, a client-side version of a
  112. ToolTalk message has methods to send the message to the server. On the
  113. server-side there is a corresponding _Tt_message that processes the
  114. new message. In the 1.0 version of ToolTalk, these methods were
  115. roughly coded as:
  116. void _Tt_some_object::
  117. sample_method(...)
  118. {
  119. if (_tt_mp->in_server()) {
  120. ... do server-specific actions ...
  121. } else {
  122. ... do client-specific actions ...
  123. }
  124. }
  125. where the "in_server" method for the _Tt_mp class returns 1 if the
  126. environment is in server mode (which is true if the method is
  127. executing on behalf of ttsession). The problem with this scheme is
  128. that the library was excessively big because the code to implement the
  129. server, ttsession, was contained in the library even though it wasn't
  130. needed for the clients.
  131. Because of this, the 1.0.1 version split up this method in one of two
  132. ways. The first method is to create two subclasses of the object. One
  133. of the subclasses, named with a "_c_" infix, represents the
  134. client-side state and methods for the object. The other subclass,
  135. named with a "_s_" infix, represents the server-side state and methods
  136. for the object. Each of these subclasses then contains the
  137. corresponding method which now doesn't need the conditional test. The
  138. example above then becomes:
  139. void _Tt_c_some_object::
  140. sample_method(...)
  141. {
  142. ... do client-specific actions ...
  143. }
  144. void _Tt_s_some_object::
  145. sample_method(...)
  146. {
  147. ... do server-specific actions ...
  148. }
  149. The other mechanism is to still have one object class but name the
  150. object with a "c_" prefix for the client-specific method, and an "s_"
  151. prefix for the server-specific method.
  152. In the 4/93 version of ToolTalk, more classes were split up so that
  153. no references to server-only classes would appear in client code.
  154. As part of this, the client-to-server XDR methods were slightly
  155. changed. You will see (in mp_rpc_implement.C) that apparently
  156. the server uses a XDR function to decode the arguments of some
  157. RPCs which is different from the encoding XDR function. This
  158. seemingly violates the central dogma of XDR, but it really isn't
  159. as bad as it looks. What is happpening is that we have class
  160. hierarchies like:
  161. _Tt_pattern
  162. |
  163. ------------------
  164. | |
  165. _Tt_s_pattern _Tt_c_pattern
  166. Only _Tt_pattern has an XDR method -- that is, the data that appears
  167. on the wire is only the common data. A client would create a _Tt_c_pattern
  168. and XDR it out; the server then XDR's it in as a _Tt_s_pattern, but
  169. the _Tt_pattern::XDR routine does all the work and the only difference
  170. is the virtual function table (and any private _Tt_s_pattern data,
  171. which would be initialized by the _Tt_s_pattern constructor.)
  172. The following classes are related to the main message-passing
  173. functionality in ToolTalk. Details on what methods they implement and
  174. precise algorithms are in the source code along with the comments
  175. throughout the code.
  176. Class: _Tt_arg
  177. File: tt/lib/mp/mp_arg.C (client/server methods)
  178. tt/lib/mp/mp_s_arg.C (server-only methods)
  179. This class represents an argument to a message or pattern. Its methods
  180. implement matching arguments with other arguments and constructing and
  181. updating arguments.
  182. Class: _Tt_auth
  183. File: tt/lib/mp/mp_auth.C (client/server methods)
  184. tt/lib/mp/mp_auth_functions.C (utility functions copied from libICE)
  185. This class maintains the authorization level being used by the server
  186. (cookie, des, unix, none). In the case of the cookie authorization
  187. scheme, this class also is responsible for generating the cookie and
  188. writing it to and reading it from the authority file.
  189. Class: _Tt_desktop
  190. File: tt/lib/mp/mp_desktop.C
  191. This class represents "desktop" sessions. Currently this means X11
  192. server sessions but the methods reflect an interface that is largely
  193. independent of X11. As a result, all X11-dependent code is isolated in
  194. this one module.
  195. Class: _Tt_c_message (subclass of _Tt_message)
  196. File: tt/lib/mp/mp_c_message.C
  197. This class represents client-only view of ToolTalk messages. It
  198. contains methods for sending messages to the ttsession server.
  199. Class: _Tt_c_procid (subclass of _Tt_procid)
  200. File: tt/lib/mp/mp_c_procid.C
  201. This class implements client-only methods needed to reply to messages
  202. and to retrieve new messages for the ToolTalk client represented by
  203. this class.
  204. Class: _Tt_file
  205. File: tt/lib/mp/mp_file.C (server/client methods)
  206. tt/lib/mp/mp_s_file.C (server-only methods)
  207. This class represents file objects. The functionality implemented is
  208. for querying for specs contained in the file, joining and quitting
  209. file scopes, and queuing and de-queueing messages on file objects.
  210. Class: _Tt_message
  211. File: tt/lib/mp/mp_message.C
  212. This class represents a ToolTalk message. This class represents
  213. methods that are common to both clients and ttsession. Its subclasses,
  214. _Tt_s_message and _Tt_c_message described below implement methods
  215. specific to client manipulation and server manipulation respectively.
  216. The code is structured so that _Tt_message objects contain the methods
  217. to do delivery to other clients.
  218. Class: _Tt_mp
  219. File: tt/lib/mp/mp_mp.C
  220. This class represents the global state needed by the message-passing
  221. objects. In particular, this object contains many object caches that
  222. are needed by the system as well as holds references to some important
  223. objects such as the default session object.
  224. Class: _Tt_node
  225. File: tt/lib/mp/mp_node.C
  226. This class represents a ToolTalk spec. Its methods create/destroy
  227. specs in a database and add properties to an existing spec.
  228. Class: _Tt_observer
  229. File: tt/lib/mp/mp_observer.C
  230. This class is a very simple class that basically just stores some
  231. message fields that can change for static observers of a message. It
  232. is used only by the _Tt_s_message class. This class is mainly used as
  233. to hold the information necessary to honor static observer "promises"
  234. for message disposition processing.
  235. Class: _Tt_otype
  236. File: tt/lib/mp/mp_otype.C
  237. This class implements methods needed to deal with otype definitions.
  238. In general the operations needed are for setting and returning the
  239. observer, inherited, and handler signatures for this otype definition
  240. as well as printing out the otype definition which, in addition to
  241. debugging, is used to print out the definition for storage under the
  242. Classing Engine and also for dumping out compiled type databases in
  243. source format.
  244. Class: _Tt_pattern
  245. File: tt/lib/mp/mp_pattern.C (server/client methods)
  246. tt/lib/mp/mp_s_pattern.C (server-only methods)
  247. This class represents a ToolTalk pattern. Client-side methods
  248. implement adding/deleting fields to the pattern and
  249. registering/unregistering the pattern by invoking the proper rpc
  250. routines on the server. Server-side methods implement the appropiate
  251. actions for registering/unregistering patterns as well as matching
  252. patterns to messages.
  253. Class: _Tt_procid
  254. File: tt/lib/mp/mp_procid.C
  255. This class represents a ToolTalk client. It represents all of the
  256. methods and data necessary for sending a message to a ToolTalk client.
  257. Its subclasses, _Tt_s_procid and _Tt_c_procid, implement the needed
  258. server-only and client-only methods.
  259. Class: _Tt_ptype
  260. File: tt/lib/mp/mp_ptype.C
  261. This class implements methods needed to deal with ptype definitions
  262. and with starting new instances of ptypes which is functionality
  263. needed to implement the start disposition options for ToolTalk
  264. messages. Also, as with _Tt_otype objects, printing methods are also
  265. defined that are used for storage in type databases and dumping out
  266. ptype definitions in source format.
  267. Class: _Tt_rpc_client
  268. File: tt/lib/mp/mp_rpc_client.C
  269. This class represents a client rpc connection. The methods implemented
  270. are basically wrappers around the rpc interfaces with the important
  271. difference that the api to this object is the same regardless of
  272. whether tli rpc or non-tli rpc is used. The methods for this object
  273. are ifdefed to use tli rpc or not.
  274. Class: _Tt_rpc_server
  275. File: tt/lib/mp/mp_rpc_server.C
  276. This class represents an rpc server. The methods implemented are
  277. wrappers around the rpc server interfaces with the difference that
  278. both tli and non-tli rpc is supported by ifdefing the implementation
  279. code for the methods to select which rpc interface to use.
  280. Class: _Tt_s_message (subclass of _Tt_message)
  281. File: tt/lib/mp/mp_s_message.C
  282. This class represents a ToolTalk message with some specialized methods
  283. that are specific to server-side manipulation of messages. In
  284. particular this class implements methods to dispatch a message (ie.
  285. match the message against static patterns), and deliver the message to
  286. ToolTalk clients with patterns that match it. There are also methods
  287. to implement the reliability for messages that don't match any active
  288. client's patterns.
  289. Class: _Tt_s_mp
  290. File: tt/lib/mp/mp_s_mp.C
  291. This class represents the global server-only state needed by the
  292. message-passing objects. It contains object caches that are relevant
  293. to the server module as well as the ptypes and otypes that were read
  294. in from the type database.
  295. Class: _Tt_s_procid (subclass of _Tt_procid)
  296. File: tt/lib/mp/mp_s_procid.C
  297. This class implements server-only methods needed to send messages to
  298. ToolTalk clients and also methods which process replies to previously
  299. sent messages.
  300. Class: _Tt_session
  301. File: tt/lib/mp/mp_session.C (server/client methods)
  302. tt/lib/mp/mp_s_session.C (server-only methods)
  303. This class represents a ToolTalk session. It has methods that apply in
  304. client-side and server-side environments. The main functionality
  305. required is establishing ToolTalk sessions, advertising the addressing
  306. information to contact the session, and methods for connecting to a
  307. session given its addressing information and auto-starting a session
  308. if necessary.
  309. Class: _Tt_signature
  310. File: tt/lib/mp/mp_signature.C
  311. This class represents a ToolTalk signature which can be either an
  312. otype or ptype signature. The main methods for this object allow one
  313. to create a signature, match the signature against an operation name
  314. and a list of arguments, and match the signature against relevant
  315. message fields.
  316. Class: _Tt_stream_socket
  317. File: tt/lib/mp/mp_stream_socket.C
  318. This class represents a stream connection. Its methods are ifdefed
  319. depending on whether TCP sockets are to be used or TLI streams.
  320. Class: _Tt_typedb
  321. File: tt/lib/mp/mp_typedb.C
  322. This class represents the ToolTalk type database. It has methods for
  323. reading and writing the database in either a native xdr format or to
  324. the Classing Engine. Important Note: since the typedb on disk is
  325. a table_ptr and not just a table, it's possible to have a null
  326. table and a non-null _ptr, which if xdr-decoded will crash the
  327. _Tt_object_table xdr method, because the default constructor
  328. for that class tries to decode a null table.
  329. Class: _Tt_global
  330. File: tt/lib/util/tt_global_env.C
  331. This class is where any global information that is not specific to
  332. message-passing is kept. In particular any global flags or caches are
  333. kept in this object. This class also keeps the number representing the
  334. current xdr version to be used by all xdr methods.
  335. Class: _Tt_host
  336. File: tt/lib/util/tt_host.C
  337. This class packages up methods for mapping host addresses to host
  338. names and viceversa.
  339. Class: _Tt_xdr_version
  340. File: tt/lib/util/tt_xdr_version.C
  341. This class provides a mechanism for temporarily setting the default
  342. xdr version. It sets the version to a given number in the constructor
  343. and then resets the default to the previous value in the destructor.
  344. Class: _Tt_new_ptr
  345. File: tt/lib/util/tt_new_ptr.C
  346. Generic version of a pointer class. This implements the
  347. reference-counting machinery. See declare_ptr_to and implement_ptr_to
  348. in tt/lib/util/tt_ptr.h to see how a specialized pointer class is
  349. derived from this generic class.
  350. Class: _Tt_object_list
  351. File: tt/lib/util/tt_object_list.C
  352. Generic version of a list class. See declare_list_of and
  353. implement_list_of in tt/lib/util/tt_list.h to see how a specialized
  354. list class is derived from the generic one.
  355. Class: _Tt_object_table
  356. File: tt/lib/util/tt_object_table.C
  357. Generic version of a table class. See declare_table_of and
  358. implement_table_of in tt/lib/util/tt_table.h to see how a specialized
  359. list class is derived from the generic one. Important note: unfortunately
  360. you can crash this method by trying to de-xdr on online db because
  361. the default constructor for that class tries to decode a null table.
  362. FINDING ONE'S WAY AROUND
  363. The rich functionality offered by ToolTalk is implemented partly in
  364. the client library, partly in the server (which itself is implemented
  365. by objects contained in a server library). Thus it isn't always
  366. trivial to find which code implements a certain feature. A good
  367. heuristic to use is to decide whether the particular feature is likely
  368. to be implemented on the client side or server side. If it is likely a
  369. client-side feature then it is accessible through one of the tooltalk
  370. api calls. These are all implemented in the tt/lib/api/c directory
  371. where the files are named api_<noun> where <noun> is the name of the
  372. entity being operated on by the api call. For example,
  373. tt_pattern_create can be found in "api_pattern.C". The api calls that
  374. don't operate on a particular entity are found in "api_mp.C". For
  375. example, tt_open and tt_fd can be found there.
  376. Once the code for the api is located, the way the feature is
  377. implemented can be traced through the code. Occasionally the api call
  378. may interact with the server-side code. This is usually in the form of
  379. an api call such as:
  380. ...
  381. rstatus = call(TT_RPC_JOIN_SESSION,
  382. (xdrproc_t)tt_xdr_procid,
  383. (char *)&procid,
  384. (xdrproc_t)xdr_int,
  385. (char *)&status);
  386. ...
  387. This will cause an rpc stub to be invoked which then invokes the
  388. appropiate methods on the server side. All the rpc stubs are
  389. implemented in tt/lib/mp/mp_rpc_implement.C. Furthermore, the naming
  390. scheme for these stubs is to add an underscore to the front of the
  391. enum used to make the call on the client side and then turn all the
  392. letters into lower case. In the example above, one would then look for
  393. the "_tt_rpc_join_session" function in tt/lib/mp/mp_rpc_implement.C.
  394. The details of how the call is mapped to this rpc stub and what
  395. processing goes on before the rpc stub is invoked can be found in the
  396. _tt_service_rpc function which does the actual rpc dispatching.
  397. Since most of the functionality is initiated by an api call (the
  398. exception being the initializiation of the server itself), this
  399. strategy usually succeeds in finding the code one is looking for.
  400. We now list some guides into the code implementing some of the major
  401. features in ToolTalk. For each piece of functionality some important
  402. methods and/or files are listed which represent the main code that
  403. implements the given functionality. Looking at the code for the given
  404. methods and their associated comments should give a good idea as to
  405. how the functionality is implemented.
  406. ********** Please add to this list **********
  407. - RPC REQUEST HANDLING
  408. (client) _Tt_session::call - single method that all other methods use
  409. when they want to invoke an rpc call.
  410. (server) tt/lib/mp/mp_rpc_implement.C contains all of the rpc stubs
  411. that get invoked on the server side in response to an rpc request from
  412. a client. The dispatch function in this file "_tt_service_rpc" does
  413. the actual dispatching of the rpc request (_tt_service_rpc is actually
  414. invoked by the rpc function svc_getreqset which is called from
  415. _Tt_s_mp::main_loop by calling _Tt_rpc_server::run).
  416. Looking at the various rpc stubs in mp_rpc_implement.C is an
  417. excellent way of navigating the code to find out how each particular
  418. rpc call is used. In particular, a good strategy for finding out how
  419. an api call is implemented is by looking at the definition of the api
  420. call and tracing through the code until _Tt_session::call invocations
  421. are found. Using the rpc procedure number passed into the
  422. _Tt_session::call method one can then look in mp_rpc_implement.C to
  423. see what happens on the server side.
  424. - NULL MESSAGE SENDING/RECEIVING LOOP
  425. This loop consists of a client sending a request message to ttsession
  426. when no patterns match the message. The message gets failed and
  427. returned to the sender. Understanding the code involved in this loop
  428. means that one understands the basic low-level mechanism by which the
  429. messages sent to and received from ttsession. The major methods
  430. involved here are:
  431. (client) _Tt_c_message::dispatch - send message to ttsession
  432. (server) _Tt_s_message::dispatch - match message with static patterns.
  433. (server) _Tt_s_message::deliver - match message with dynamic patterns.
  434. (server) _Tt_s_procid::add_message - add a message to procid's message
  435. queue.
  436. (server) _Tt_s_procid::signal_new_message - signal a procid that it has
  437. a new message.
  438. (client) _Tt_c_procid::next_message - get next message from ttsession
  439. (server) _Tt_s_procid::next_message - return next message from ttsession
  440. - DISPATCHING AND DELIVERING A MESSAGE
  441. (server) _Tt_s_message::dispatch
  442. (server) _Tt_s_message::deliver
  443. - STARTING A NEW PTYPE
  444. (server) _Tt_s_message::handle_no_recipients
  445. (server) _Tt_s_message::change_state
  446. (server) _Tt_ptype::start
  447. - PROCESSING THE REPLY TO A MESSAGE
  448. (client) _Tt_c_procid::update_msg
  449. (server) _Tt_s_procid::update_msg
  450. (server) _Tt_message::update_msg
  451. (server) _Tt_s_message::change_state
  452. - HONORING START AND QUEUE RELIABILITY OPTIONS
  453. _Tt_s_message::deliver
  454. _Tt_s_message::handle_no_recipients
  455. For file-scope messages, queueing is actually handled on the client
  456. side. For more details look in:
  457. _Tt_c_message::c_dispatch
  458. _Tt_file::q_message
  459. _Tt_file::dq_message
  460. _Tt_file::c_join
  461. - READING IN CLASSING ENGINE DATABASES
  462. _Tt_typedb::init_ce
  463. - ADDING/MERGING NEW TYPES TO A TYPE DATABASE
  464. _Tt_typedb::begin_write
  465. _Tt_typedb::end_write
  466. _Tt_typedb::insert_ptype
  467. _Tt_typedb::insert_otype
  468. - DECLARING A PTYPE
  469. _tt_rpc_declare_ptype
  470. _Tt_s_procid::declare_ptype
  471. - DETECTING PTYPE LAUNCH FAILURE
  472. sig_handler (in tt/bin/ttsession/mp_server.C)
  473. notify_launch_failure (in tt/bin/ttsession/mp_server.C)
  474. _Tt_ptype::launch_failed
  475. - AUTO-STARTING A SESSION
  476. tt_open (tt/lib/api/c/api_mp.C)
  477. _Tt_mp::init
  478. _Tt_session::init
  479. _Tt_session::c_init
  480. - ESTABLISHING RPC CONNECTION TO THE SERVER
  481. _Tt_session::client_session_init - client-side processing
  482. _Tt_s_mp::main_loop - unix and network rpc connection
  483. _Tt_session::u_rpc_init - unix socket rpc connection
  484. - XDR/RPC VERSIONING SCHEME
  485. _tt_service_rpc (tt/lib/mp/mp_rpc_implement.C)
  486. _Tt_xdr_version (tt/lib/util/tt_xdr_version)
  487. _Tt_global::set_xdr_version (tt/lib/util/tt_global_env.C)
  488. _Tt_global::xdr_version (tt/lib/util/tt_global_env.C)
  489. - TRACE/DEBUG/ERROR OUTPUT
  490. For trace output in ttsession and in slib, use the _Tt_trace
  491. class.
  492. For debug output in the old dm code, do it according to the
  493. $TT_DM_DEBUG level. No other module has a similar debug output
  494. facility.
  495. When an error is detected in the client library and a Tt_status
  496. other than TT_ERR_INTERNAL is going to be passed up through
  497. the API to diagnose it, then the client library should not
  498. emit any message anywhere. That's the job of the application using
  499. libtt.
  500. _tt_syslog( 0, LOG_ERR, ) should be used in the client library when:
  501. - a TT_ERR_INTERNAL (bug) arises and we want to diagnose what happened;
  502. - a partial failure of an API call occurs, but the API call is still
  503. considered to have succeeded. For example, when tt_message_send()
  504. for a file-scoped message cannot contact one of the interested
  505. sessions.
  506. The daemons (ttsession and dbserver) should pass either 0 or stderr
  507. to _tt_syslog(), depending on whether they are in daemon mode or not.
  508. In CDE, certain parts (tt_type_comp, ttrm et al.) of ToolTalk are
  509. likely to be run from tools that have stderr aimed at /dev/null.
  510. These parts of ToolTalk should never write to stderr directly, nor
  511. call perror(), nc_perror(), t_error(), etc. Instead, they should pass
  512. stderr to _tt_syslog(), and use strerror() (or %m), nc_strerror(),
  513. t_strerror(), etc. _tt_syslog() will prefix, route, suppress, and
  514. multiplex the output appropriately. For example, in CDE we will
  515. probably multiplex our error output onto ~/.dt/errorlog. For
  516. suppression, _tt_syslog() obeys _tt_global->silent.
  517. No output should include un-internationalized English. The output
  518. should include only ToolTalk-ese and catgets() strings. (ToolTalk-ese
  519. can be C/C++ use of the ToolTalk API, or the ToolTalk types language.)
  520. All modules that call catgets() should include "util/tt_gettext.h", so
  521. that they are really calling _tt_catgets() instead of the one in
  522. /usr/lib. This lets us map catgets() to something else on platforms
  523. where it is not supported.
  524. It is OK to write normal output to stdout.
  525. ASSIGNING NEW CATGETS MESSAGE IDS
  526. When you code up a new call to catgets(), choose your message set out
  527. of util/tt_gettext.h, and use -1 as the message id. Then follow this
  528. procedure to update the message catalog:
  529. 0. Make sure your source file(s) is(are) checked in; ttgenmsg will
  530. refuse to work on checked-out files.
  531. 0a. Make sure /home/tooltalk/tools/bin is in your PATH
  532. 1. Check out SUNW_TOOLTALK.msg and SUNW_TOOLTALK.sets
  533. 2. Run "make msgs" from the top of the tree.
  534. 2a. Run msgfix which will sort and clean up "msgs" into "msgs.fixed"
  535. 3. Check in SUNW_TOOLTALK.sets (which now has been updated).
  536. 4. Copy "msgs.fixed" to SUNW_TOOLTALK.msg and check it in.
  537. 5. Check in your updated source files.
  538. Note to source customers: ttgenmsg depends on genmsg, an internal
  539. SunSoft tool, and so ttgenmsg is not included in the ToolTalk source
  540. distribution. If you add any new catgets() messages, you will have to
  541. manually assign message ids and update the message catalog.
  542. Note to ToolTalk developers: ttgenmsg and genmsg are in
  543. /home/tooltalk/tools/bin.
  544. THREADING ISSUES
  545. - Locking granularity:
  546. ToolTalk API calls acquire a global lock which they hold as long
  547. as they are doing operations that can't block. The original
  548. intention was to drop the locks around RPC calls and re-acquire
  549. them immediately after returning from such calls. This proved to
  550. be unworkable because it resulted in crashes in the RPC library.
  551. As of the time of this writing, locks are held around RPC calls,
  552. which introduces the danger of a blocking call causing a deadlock
  553. in the entire TT library, since only one thread is actually
  554. manipulating TT structures at any particular time in a process.
  555. - ttsession threading
  556. Currently ttsession only uses a thread for registering as a client
  557. of itself. This is an atomic operation and its success or failure
  558. doesn't have a significant effect on ttsession's ability to serve
  559. client processes. ttsession tracing won't work until the
  560. thread completes successfully.
  561. - ALL thread-specific storage should be from malloc calls, NEVER local
  562. storage. Also, all storage obtained from tt_malloc-type calls is
  563. thread-specific.
  564. - Calling tt_message_receive and receiving the same message simultaneously
  565. in different threads causes the message object to be updated from under
  566. the calling code. This happens, for instance, when one thread has a
  567. handle pattern registered and another has an observe pattern registered,
  568. and they both match the same message. The biggest danger here is
  569. if one thread deletes a message while another thread is accessing
  570. data from the message. It is up to the client program to regulate
  571. access to TT message data.