Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6646 lines
205 KiB

  1. //
  2. // Object Manager
  3. //
  4. #ifndef _H_OM
  5. #define _H_OM
  6. #include <gdc.h>
  7. #include <ast120.h>
  8. //
  9. //
  10. // CONSTANTS
  11. //
  12. //
  13. //
  14. // Function Profiles (apps)
  15. //
  16. #define OMFP_FIRST 0
  17. typedef enum
  18. {
  19. OMFP_AL = OMFP_FIRST,
  20. OMFP_OM,
  21. OMFP_WB, // For old whiteboard
  22. OMFP_MAX
  23. }
  24. OMFP;
  25. //
  26. // These are the corresponding strings (part of the protocol)
  27. //
  28. #define AL_FP_NAME "APP-LOAD-1.0"
  29. #define OM_FP_NAME "OMCONTROL-1.0"
  30. #define WB_FP_NAME "WHITEBOARD-1.0"
  31. //
  32. // ObMan clients
  33. //
  34. #define OMCLI_FIRST 0
  35. typedef enum
  36. {
  37. OMCLI_AL = OMCLI_FIRST,
  38. OMCLI_WB,
  39. OMCLI_MAX
  40. }
  41. OMCLI;
  42. //
  43. // ObMan workset groups
  44. //
  45. #define OMWSG_FIRST 0
  46. typedef enum
  47. {
  48. OMWSG_OM = OMWSG_FIRST,
  49. OMWSG_AL,
  50. OMWSG_WB,
  51. OMWSG_MAX,
  52. OMWSG_MAXPERCLIENT
  53. }
  54. OMWSG;
  55. //
  56. // These are the corresponding strings (part of the protocol)
  57. //
  58. #define OMC_WSG_NAME "OBMANCONTROL"
  59. #define AL_WSG_NAME "APP-LOADER"
  60. #define WB_WSG_NAME "WHITEBOARD"
  61. //
  62. // Specify this in place of a valid Domain handle to create/move a workset
  63. // group outside of any calls:
  64. //
  65. #define OM_NO_CALL NET_INVALID_DOMAIN_ID
  66. //
  67. //
  68. // SYSTEM LIMITS
  69. //
  70. // These are limits imposed by the architecture/design of the system.
  71. //
  72. //
  73. //
  74. // Workset group names
  75. //
  76. // Workset groups names are null-terminated strings, up to 32 characters
  77. // long (including the NULL character). They are intended to be
  78. // human-readable names, and must contain only ASCII characters between
  79. // 0x2C and 0x5B. This range includes all uppercase characters, all digits
  80. // and certain punctuation marks.
  81. //
  82. #define OM_MAX_WSGROUP_NAME_LEN 32
  83. //
  84. // Function Profile names
  85. //
  86. // Function profile names must be no longer than 16 characters (including
  87. // the NULL character). The range of characters allowable is the same as
  88. // for workset group names.
  89. //
  90. #define OM_MAX_FP_NAME_LEN 16
  91. //
  92. // Maximum number of changes allowed to a workset
  93. //
  94. // Each time a workset is changed, we increment its "generation number",
  95. // which is used in resequencing operations. The largest size for an
  96. // integer is 32 bits, so the maximum generation number using a convenient
  97. // type is 2^32-1.
  98. //
  99. //
  100. #define OM_MAX_GENERATION_NUMBER 0xffffffff
  101. //
  102. // Maximum size of an object
  103. //
  104. // This derives from the maximum size of a huge memory block under Windows
  105. // (16MB less 64KB):
  106. //
  107. #define OM_MAX_OBJECT_SIZE ((UINT) (0x1000000 - 0x10000))
  108. //
  109. // Maximum update size of an object
  110. //
  111. // This derives from the necessity to send updates atomically in one
  112. // network packet (see SFR 990)
  113. //
  114. #define OM_MAX_UPDATE_SIZE ((UINT) (0x00001f00))
  115. //
  116. // Maximum number of worksets per workset group
  117. //
  118. // This derives from the desire to make workset IDs 8-bit quantities so
  119. // that they can fit in DC-Groupware events with a workset group handle and
  120. // an object ID:
  121. //
  122. // Note: this value must be at most 255 so that certain ObMan for-loops
  123. // don't cycle for ever.
  124. //
  125. #define OM_MAX_WORKSETS_PER_WSGROUP 255
  126. //
  127. // Maximum number of workset groups per Domain
  128. //
  129. // This derives from the use of the ObManControl workset group: it has one
  130. // control workset and then one workset for each workset group in the
  131. // Domain, so there can only be this many workset groups in a Domain:
  132. //
  133. // Note: this number must be at most one less that
  134. // OM_MAX_WORKSETS_PER_WSGROUP
  135. //
  136. #define OM_MAX_WSGROUPS_PER_DOMAIN 64
  137. //
  138. // Special WSGROUPID for OMC:
  139. //
  140. #define WSGROUPID_OMC 0
  141. //
  142. //
  143. // RETURN CODES
  144. //
  145. // Return codes are defined relative to the OM_BASE_RC base
  146. //
  147. //
  148. enum
  149. {
  150. OM_RC_NO_MORE_HANDLES = OM_BASE_RC,
  151. OM_RC_WORKSET_DOESNT_EXIST,
  152. OM_RC_WORKSET_EXHAUSTED,
  153. OM_RC_OBJECT_DELETED,
  154. OM_RC_BAD_OBJECT_ID,
  155. OM_RC_NO_SUCH_OBJECT,
  156. OM_RC_WORKSET_LOCKED,
  157. OM_RC_TOO_MANY_CLIENTS,
  158. OM_RC_TOO_MANY_WSGROUPS,
  159. OM_RC_ALREADY_REGISTERED ,
  160. OM_RC_CANNOT_MOVE_WSGROUP,
  161. OM_RC_LOCAL_WSGROUP,
  162. OM_RC_ALREADY_IN_CALL,
  163. OM_RC_NOT_ATTACHED,
  164. OM_RC_WORKSET_ALREADY_OPEN,
  165. OM_RC_OUT_OF_RESOURCES,
  166. OM_RC_NETWORK_ERROR,
  167. OM_RC_TIMED_OUT,
  168. OM_RC_NO_PRIMARY,
  169. OM_RC_WSGROUP_NOT_FOUND,
  170. OM_RC_WORKSET_NOT_FOUND,
  171. OM_RC_OBJECT_NOT_FOUND,
  172. OM_RC_WORKSET_LOCK_GRANTED,
  173. OM_RC_SPOILED,
  174. OM_RC_RECEIVE_CB_NOT_FOUND,
  175. OM_RC_OBJECT_PENDING_DELETE,
  176. OM_RC_NO_NODES_READY,
  177. OM_RC_BOUNCED
  178. };
  179. //
  180. // Setting defaults
  181. //
  182. #define OM_LOCK_RETRY_COUNT_DFLT 10
  183. #define OM_LOCK_RETRY_DELAY_DFLT 1000
  184. #define OM_REGISTER_RETRY_COUNT_DFLT 40
  185. #define OM_REGISTER_RETRY_DELAY_DFLT 5000
  186. //
  187. // This is the number of bytes we zero at the start of each object
  188. // allocated. It must be less than DCMEM_MAX_SIZE, since ObjectAlloc
  189. // assumes that this many bytes at the start of an object are all in the
  190. // same segment.
  191. //
  192. #define OM_ZERO_OBJECT_SIZE 0x400
  193. //
  194. // EVENTS
  195. // Public then Internal
  196. //
  197. enum
  198. {
  199. OM_OUT_OF_RESOURCES_IND = OM_BASE_EVENT,
  200. OM_WSGROUP_REGISTER_CON,
  201. OM_WSGROUP_MOVE_CON,
  202. OM_WSGROUP_MOVE_IND,
  203. OM_WORKSET_OPEN_CON,
  204. OM_WORKSET_NEW_IND,
  205. OM_WORKSET_LOCK_CON,
  206. OM_WORKSET_UNLOCK_IND,
  207. OM_WORKSET_CLEAR_IND,
  208. OM_WORKSET_CLEARED_IND,
  209. OM_OBJECT_ADD_IND,
  210. OM_OBJECT_MOVE_IND,
  211. OM_OBJECT_DELETE_IND,
  212. OM_OBJECT_REPLACE_IND,
  213. OM_OBJECT_UPDATE_IND,
  214. OM_OBJECT_LOCK_CON,
  215. OM_OBJECT_UNLOCK_IND,
  216. OM_OBJECT_DELETED_IND,
  217. OM_OBJECT_REPLACED_IND,
  218. OM_OBJECT_UPDATED_IND,
  219. OM_PERSON_JOINED_IND,
  220. OM_PERSON_LEFT_IND,
  221. OM_PERSON_DATA_CHANGED_IND,
  222. OMINT_EVENT_LOCK_TIMEOUT,
  223. OMINT_EVENT_SEND_QUEUE,
  224. OMINT_EVENT_PROCESS_MESSAGE,
  225. OMINT_EVENT_WSGROUP_REGISTER,
  226. OMINT_EVENT_WSGROUP_MOVE,
  227. OMINT_EVENT_WSGROUP_REGISTER_CONT,
  228. OMINT_EVENT_WSGROUP_DEREGISTER,
  229. OMINT_EVENT_WSGROUP_DISCARD
  230. };
  231. //
  232. // Data transmission constants:
  233. //
  234. #define OM_NET_MAX_TRANSFER_SIZE 60000
  235. //
  236. // These constants identify the types of network buffer pools we use:
  237. //
  238. #define OM_NET_OWN_RECEIVE_POOL 1
  239. #define OM_NET_OMC_RECEIVE_POOL 2
  240. #define OM_NET_WSG_RECEIVE_POOL 3
  241. #define OM_NET_SEND_POOL 4
  242. //
  243. // These constants are the sizes of the receive pools for each priority and
  244. // for each type of channel we join:
  245. //
  246. #define OM_NET_RECEIVE_POOL_SIZE 0x00002000
  247. #define OM_NET_OWN_RECEIVE_POOL_TOP OM_NET_RECEIVE_POOL_SIZE
  248. #define OM_NET_OWN_RECEIVE_POOL_HIGH OM_NET_RECEIVE_POOL_SIZE
  249. #define OM_NET_OWN_RECEIVE_POOL_MEDIUM OM_NET_RECEIVE_POOL_SIZE
  250. #define OM_NET_OWN_RECEIVE_POOL_LOW OM_NET_RECEIVE_POOL_SIZE
  251. #define OM_NET_OMC_RECEIVE_POOL_TOP OM_NET_RECEIVE_POOL_SIZE
  252. #define OM_NET_OMC_RECEIVE_POOL_HIGH OM_NET_RECEIVE_POOL_SIZE
  253. #define OM_NET_OMC_RECEIVE_POOL_MEDIUM OM_NET_RECEIVE_POOL_SIZE
  254. #define OM_NET_OMC_RECEIVE_POOL_LOW OM_NET_RECEIVE_POOL_SIZE
  255. #define OM_NET_WSG_RECEIVE_POOL_TOP OM_NET_RECEIVE_POOL_SIZE
  256. #define OM_NET_WSG_RECEIVE_POOL_HIGH OM_NET_RECEIVE_POOL_SIZE
  257. #define OM_NET_WSG_RECEIVE_POOL_MEDIUM OM_NET_RECEIVE_POOL_SIZE
  258. #define OM_NET_WSG_RECEIVE_POOL_LOW OM_NET_RECEIVE_POOL_SIZE
  259. #define OM_NET_SEND_POOL_SIZE 0x00004000
  260. #define OM_NET_SEND_POOL_TOP OM_NET_SEND_POOL_SIZE
  261. #define OM_NET_SEND_POOL_HIGH OM_NET_SEND_POOL_SIZE
  262. #define OM_NET_SEND_POOL_MEDIUM OM_NET_SEND_POOL_SIZE
  263. #define OM_NET_SEND_POOL_LOW OM_NET_SEND_POOL_SIZE
  264. //
  265. // These constants are used to decide what priority to send data transfers
  266. // at when a Client has specified OBMAN_CHOOSES_PRIORITY for the workset:
  267. //
  268. #define OM_NET_HIGH_PRI_THRESHOLD 0x0100
  269. #define OM_NET_MED_PRI_THRESHOLD 0x1000
  270. #define OM_CHECKPOINT_WORKSET OM_MAX_WORKSETS_PER_WSGROUP
  271. //
  272. //
  273. // DATA STRUCTURES
  274. //
  275. // This section defines the main data structures of the ObMan API.
  276. //
  277. //
  278. typedef struct tagOM_CLIENT * POM_CLIENT;
  279. typedef struct tagOM_PRIMARY * POM_PRIMARY;
  280. // Client objects are record pointers
  281. typedef struct tagOM_OBJECT * POM_OBJECT;
  282. typedef struct tagOM_WSGROUP * POM_WSGROUP;
  283. typedef struct tagOM_DOMAIN * POM_DOMAIN;
  284. //
  285. // ObMan correlators
  286. //
  287. typedef WORD OM_CORRELATOR;
  288. //
  289. // Workset ID
  290. //
  291. // Within a workset group, worksets are identified by an 8-bit ID.
  292. //
  293. typedef BYTE OM_WSGROUP_HANDLE;
  294. typedef BYTE OM_WORKSET_ID;
  295. typedef OM_WORKSET_ID * POM_WORKSET_ID;
  296. //
  297. // Object structure
  298. //
  299. // Objects and object pointers are defined as follows:
  300. //
  301. typedef struct tagOM_OBJECTDATA
  302. {
  303. TSHR_UINT32 length; // length of the data field
  304. BYTE data[1]; // object data, uninterpreted by ObMan;
  305. // in reality, not 1 byte but <length>
  306. // bytes long
  307. }
  308. OM_OBJECTDATA;
  309. typedef OM_OBJECTDATA * POM_OBJECTDATA;
  310. typedef POM_OBJECTDATA * PPOM_OBJECTDATA;
  311. //
  312. // Note that the maximum permitted size of an object, INCLUDING the
  313. // <length> field, is 16MB less 64KB.
  314. //
  315. void __inline ValidateObjectData(POM_OBJECTDATA pData)
  316. {
  317. ASSERT(!IsBadWritePtr(pData, sizeof(OM_OBJECTDATA)));
  318. ASSERT((pData->length > 0) && (pData->length < OM_MAX_OBJECT_SIZE));
  319. }
  320. //
  321. // Object IDs
  322. //
  323. // Internally, object IDs are a combination of a network ID and a four-byte
  324. // sequence counter:
  325. //
  326. typedef struct tagOM_OBJECT_ID
  327. {
  328. TSHR_UINT32 sequence;
  329. NET_UID creator; // MCS user ID of node which created it
  330. WORD pad1;
  331. } OM_OBJECT_ID;
  332. typedef OM_OBJECT_ID * POM_OBJECT_ID;
  333. //
  334. // Partitioning of the first parameter on an event for INDICATION events
  335. //
  336. typedef struct tagOM_EVENT_DATA16
  337. {
  338. OM_WSGROUP_HANDLE hWSGroup;
  339. OM_WORKSET_ID worksetID;
  340. }
  341. OM_EVENT_DATA16;
  342. typedef OM_EVENT_DATA16 * POM_EVENT_DATA16;
  343. //
  344. // Partitioning of the second parameter on an event for CONFIRM events
  345. //
  346. typedef struct tagOM_EVENT_DATA32
  347. {
  348. WORD result;
  349. OM_CORRELATOR correlator;
  350. }
  351. OM_EVENT_DATA32;
  352. typedef OM_EVENT_DATA32 * POM_EVENT_DATA32;
  353. //
  354. //
  355. // OBMANCONTROL
  356. //
  357. // This section describes the ObManControl Function Profile, as used by the
  358. // Object Manager.
  359. //
  360. //
  361. //
  362. //
  363. // DESCRIPTION
  364. //
  365. // In addition to the purely local records of workset groups, all instances
  366. // of ObMan attached to a given Domain jointly maintain a control workset
  367. // group containing
  368. //
  369. // - one workset (workset #0) listing the name, Function Profile, ID
  370. // and MCS channel of each of the "standard" workset groups in
  371. // the Domain, as well as the MCS user IDs of all the instances of ObMan
  372. // in the Domain
  373. //
  374. // - one "registration workset" per workset group (worksets #1-#255)
  375. // listing the MCS user IDs of the instances of ObMan which have one or
  376. // more local Clients registered with the workset group.
  377. //
  378. // Creating a new workset group in a Domain causes ObMan to
  379. //
  380. // - add a new identification object to workset #0 and
  381. //
  382. // - create a new registration workset
  383. //
  384. // Registering with a workset group causes ObMan to
  385. //
  386. // - add a registration object to the appropriate registration workset.
  387. //
  388. //
  389. //
  390. // USAGE
  391. //
  392. // ObMan Clients can register with the ObManControl workset group, and then
  393. // open and examine the contents of workset #0 to discover the names and
  394. // Function Profiles of all the workset groups existing in a Domain.
  395. //
  396. // ObMan Clients must not attempt to lock or change the contents of this
  397. // workset group in any way.
  398. //
  399. //
  400. //
  401. //
  402. // OBJECT DEFINITIONS
  403. //
  404. // This section provides the definitions for the objects contained in the
  405. // worksets of the ObManControl workset group.
  406. //
  407. //
  408. typedef BYTE OM_WSGROUP_ID;
  409. typedef OM_WSGROUP_ID * POM_WSGROUP_ID;
  410. //
  411. //
  412. // WORKSET GROUP IDENTIFICATION OBJECT
  413. //
  414. // This structure identifies a workset within a Domain. Objects of this
  415. // form reside in workset #0 of ObManControl, known as the INFO workset.
  416. //
  417. //
  418. #define OM_INFO_WORKSET ((OM_WORKSET_ID) 0)
  419. //
  420. // NET PROTOCOL
  421. //
  422. typedef struct
  423. {
  424. TSHR_UINT32 length; // size of this structure, less four
  425. // bytes (for length field itself)
  426. DC_ID_STAMP idStamp; // == OM_WSGINFO_ID_STAMP
  427. NET_CHANNEL_ID channelID; // workset group's MCS channel
  428. NET_UID creator; // NET user ID of instance of ObMan
  429. // which created workset group
  430. OM_WSGROUP_ID wsGroupID; // Domain-unique ID
  431. BYTE pad1;
  432. WORD pad2;
  433. char functionProfile[ OM_MAX_FP_NAME_LEN ];
  434. // function profile
  435. char wsGroupName[ OM_MAX_WSGROUP_NAME_LEN ];
  436. // Client-supplied name
  437. }
  438. OM_WSGROUP_INFO;
  439. typedef OM_WSGROUP_INFO * POM_WSGROUP_INFO;
  440. #define OM_WSGINFO_ID_STAMP DC_MAKE_ID_STAMP('O', 'M', 'W', 'I')
  441. void __inline ValidateObjectDataWSGINFO(POM_WSGROUP_INFO pInfoObj)
  442. {
  443. ValidateObjectData((POM_OBJECTDATA)pInfoObj);
  444. ASSERT(pInfoObj->idStamp == OM_WSGINFO_ID_STAMP);
  445. }
  446. //
  447. //
  448. // WORKSET GROUP REGISTRATION OBJECTS
  449. //
  450. // This structure identifies a node's usage of a workset group. These
  451. // objects can reside in any ObManControl workset.
  452. //
  453. // In the case of workset #0, these objects identify a node's usage of the
  454. // ObManControl workset group itself. Since all instances of ObMan in a
  455. // Domain are use the ObManControl workset group, the registration objects
  456. // in workset #0 form a complete list of all the instances of ObMan in a
  457. // Domain.
  458. //
  459. //
  460. //
  461. // NET PROTOCOL
  462. //
  463. typedef struct
  464. {
  465. TSHR_UINT32 length; // size of this structure, less four
  466. // bytes (for length field itself)
  467. DC_ID_STAMP idStamp; // == OM_WSGREGREC_ID_STAMP
  468. NET_UID userID; // user ID of ObMan to which the
  469. // object relates
  470. TSHR_UINT16 status; // see below for status values
  471. TSHR_PERSON_DATA personData;
  472. }
  473. OM_WSGROUP_REG_REC;
  474. typedef OM_WSGROUP_REG_REC * POM_WSGROUP_REG_REC;
  475. #define OM_WSGREGREC_ID_STAMP DC_MAKE_ID_STAMP('O', 'M', 'R', 'R')
  476. void __inline ValidateObjectDataWSGREGREC(POM_WSGROUP_REG_REC pRegObject)
  477. {
  478. ValidateObjectData((POM_OBJECTDATA)pRegObject);
  479. ASSERT(pRegObject->idStamp == OM_WSGREGREC_ID_STAMP);
  480. }
  481. //
  482. // Value for <status> field:
  483. //
  484. #define CATCHING_UP 1
  485. #define READY_TO_SEND 2
  486. //
  487. //
  488. // LATE JOINER PROTOCOL
  489. //
  490. // If a Client registers with a workset group which already exists
  491. // elsewhere in the Domain, that Client is considered a late joiner for
  492. // that workset group. The protocol for bringing late joiners up to date
  493. // is as follows (except where explicitly stated, "ObMan" means "the local
  494. // instance of ObMan"):
  495. //
  496. // OVERVIEW
  497. //
  498. // A late-joiner node asks another "helper" node for a copy of the workset
  499. // group. The helper node broadcasts a low-priority sweep message to all
  500. // other nodes in the call and when it has received their replies, sends
  501. // what it believes to be the current copy of the workset to the
  502. // late-joiner.
  503. //
  504. // DETAILS
  505. //
  506. // At the local node, ObMan
  507. //
  508. // 1. locks the ObManControl workset group (one effect of this is that no
  509. // other ObMan in the Domain will discard any workset groups it has
  510. // local copies of)
  511. //
  512. // 2. examines the ObManControl workset group to determine
  513. //
  514. // - the MCS channel ID for the workset group
  515. //
  516. // - the MCS user ID of an instance of ObMan which has a copy of the
  517. // workset group
  518. //
  519. // 3. requests to join the workset group channel
  520. //
  521. // 4. waits for the join to succeed
  522. //
  523. // 5. sends an OMNET_WSGROUP_SEND_REQ at high priority on the user ID
  524. // channel of that instance of ObMan, known as the "helper"
  525. //
  526. // 6. broadcasts an OMNET_WORKSET_UNLOCK message at low priority to unlock
  527. // the ObManControl workset group (on the ObManControl channel)
  528. //
  529. // At the helper node, ObMan
  530. //
  531. // 7. receives the OMNET_WSGROUP_SEND_REQ
  532. //
  533. // 8. marks its copy of the workset group as non-discardable
  534. //
  535. // 9. examines the ObManControl workset to determine the MCS user IDs
  536. // of the remote instances of ObMan which already have copies
  537. // of the workset group
  538. //
  539. // 10. broadcasts an OMNET_WSGROUP_SWEEP_REQ message on the workset group
  540. // channel at high priority
  541. //
  542. // At each of the nodes queried in step 10, ObMan
  543. //
  544. // 11. receives the OMNET_WSGROUP_SWEEP_REQ
  545. //
  546. // 12. sends an OMNET_WSGROUP_SWEEP_REPLY message to the helper node at
  547. // low priority
  548. //
  549. // Back at the helper node, ObMan
  550. //
  551. // 13. records each OMNET_WSGROUP_SWEEP_REPLY until all have been
  552. // received*
  553. //
  554. // 14. sends one OMNET_WORKSET_NEW message for each workset in the workset
  555. // group (on the late-joiners single-member channel)
  556. //
  557. // 15. sends an OMNET_OBJECT_ADD message for each object in each workset,
  558. // again on the late-joiner's single member channel
  559. //
  560. // 16. sends an OMNET_WSGROUP_SEND_COMPLETE to the late-joiner; this
  561. // message serves as a back marker for the late-joiner so that it
  562. // knows when it has caught up with the state of the workset group as
  563. // it was when it joined
  564. //
  565. // ASSUMPTIONS
  566. //
  567. // This protocol relies on the following assumptions:
  568. //
  569. // - The helper node receives the OMNET_WSGROUP_SEND_REQ message before
  570. // the OMNET_WORKSET_UNLOCK message (as otherwise there is a window
  571. // where its copy of the workset group may be discarded).
  572. //
  573. // This assumption is based on the fact that low-priority MCS data does
  574. // not overtake high priority MCS data sent from the same node EVEN ON
  575. // DIFFERENT CHANNELS.
  576. //
  577. // If this assumption proves invalid then either
  578. //
  579. // - the OMNET_WSGROUP_SEND_REQ message must be acknowledged before the
  580. // late joiner can unlock the ObManControl workset, or
  581. //
  582. // - the OMNET_WSGROUP_SEND_REQ must be sent on the ObManControl
  583. // broadcast channel, with an extra field indicating the node for which
  584. // it is intended.
  585. //
  586. // - Any data received at the helper node after stage 14 begins is
  587. // forwarded by MCS to the late-joiner.
  588. //
  589. // This assumption is based on the fact that the late-joiner is marked
  590. // at the helper's MCS system as joined to the relevant channel before
  591. // stage 14 begins. MCS guarantees that once a NET_CHANNEL_JOIN_IND has
  592. // been received locally, the MCS system at every other node in the
  593. // Domain is aware that the late-joiner has joined the channel.
  594. //
  595. // Note that in R1.1, the helper node will discover, at step 9, that there
  596. // are no other nodes in the Domain. Therefore, steps 10-13 are eliminated
  597. // i.e. the helper sends its copy of the workset as soon as it receives
  598. // the request from the late-joiner.
  599. //
  600. // This is a major simplification and the code to implement these steps is
  601. // not to be included in R1.1.
  602. //
  603. // * The glib "until all have been received" condition is actually
  604. // difficult to implement since nodes may disappear while the helper is
  605. // waiting. The solution to this is deferred to R2.0 (but see section on
  606. // locking for suggested implementation).
  607. //
  608. //
  609. //
  610. //
  611. // WORKSET LOCKING PROTOCOL
  612. //
  613. // In what follows, the "state" refers to the lock state of the workset, as
  614. // stored in the workset record.
  615. //
  616. // At the locking node, ObMan does the following:
  617. //
  618. // 1. if the state is LOCK_GRANTED, post FAILURE then quit
  619. //
  620. // 2. examine the workset in ObManControl which corresponds to the
  621. // workset group containing the workset to be locked, to determine the
  622. // IDs of the other nodes which are in using the workset group (at most
  623. // 1 node in R1.1); put these IDs in a list of "expected respondents"
  624. // (Note: do not include own ID in this list)
  625. //
  626. // 3. if this list is empty, we have succeeded so post SUCCESS and quit
  627. //
  628. // 4. else broadcast an OMNET_WORKSET_LOCK_REQ message on the workset
  629. // group channel (i.e. to each of these nodes)
  630. //
  631. // 5. set the workset state to LOCKING and post a delayed
  632. // OMINT_EVENT_LOCK_TIMEOUT event
  633. //
  634. // At the other node(s), ObMan does the following:
  635. //
  636. // 6. receive the OMNET_WORKSET_LOCK_REQ message from the locking node
  637. //
  638. // 7. examine its current workset state
  639. //
  640. // 8. if it is LOCK_REQUESTED and the MCS user ID of the locking node is
  641. // less than that of the current node, goto DENY
  642. //
  643. // 9. else, goto GRANT
  644. //
  645. // DENY:
  646. //
  647. // 10. send an OMNET_WORKSET_LOCK_DENY message to the locking node
  648. //
  649. // GRANT:
  650. //
  651. // 11. if the state if LOCKING, then we are giving the lock to a higher
  652. // "priority" ObMan even though we wanted it ourselves, so post
  653. // FAILURE
  654. // locally (continue to 12)
  655. //
  656. // 12. set the state to LOCK_GRANTED
  657. //
  658. // 13. send an OMNET_WORKSET_LOCK_GRANT message to the locking node
  659. //
  660. // Back at the locking node, one of the following happens:
  661. //
  662. // ObMan receives an OMNET_WORKSET_LOCK_GRANT message
  663. //
  664. // it then deletes the ID of the node which sent it from the list of
  665. // expected respondents
  666. //
  667. // if this list is now empty, all nodes have replied so post SUCCESS
  668. // to Client
  669. //
  670. // OR
  671. //
  672. // ObMan receives an OMNET_WORKSET_LOCK_DENY message
  673. //
  674. // if the state is LOCKING, set it to READY, post FAILURE and quit
  675. //
  676. // if the state is anything else, this reply has come too late
  677. // (we've timed out) so ignore it
  678. //
  679. // OR
  680. //
  681. // ObMan receives the OMINT_EVENT_LOCK_TIMEOUT event
  682. //
  683. // if the state is not LOCKING, the lock has succeeded so ignore the
  684. // timeout
  685. //
  686. // otherwise, ObMan checks the ObManControl workset as in step 2 to
  687. // see if any nodes still on the expected respondents list have in
  688. // fact disappeared; if so post SUCCESS
  689. //
  690. // else post FAILURE.
  691. //
  692. //
  693. //
  694. // The state machine for the locking process is as follows (R1.1 version):
  695. //
  696. // |---------+-----------+---------+--------------|
  697. // |UNLOCKED | LOCKING | LOCKED | LOCK_GRANTED |
  698. // | 1 | 2 | 3 | 4 |
  699. // |---------+-----------+---------+--------------|
  700. // WorksetLock() |broadcast| FAIL | FAIL | FAIL |
  701. // |LOCK_REQ,| | | |
  702. // | ->2 | | | |
  703. // |---------+-----------+---------+--------------|
  704. // WorksetUnlock() | X |broadcast UNLOCK, ->1| X |
  705. // |---------+-----------+---------+--------------|
  706. // OMNET_WORKSET_LOCK_REQ |reply |compare |reply | - |
  707. // |GRANT, |MCS IDs: |DENY | |
  708. // | ->4 |if we're | | (in R1.1, |
  709. // | |greater, | | this should |
  710. // | |reply DENY | | be an error) |
  711. // | |else reply | | |
  712. // | |GRANT, ->4 | | |
  713. // |---------+-----------+---------+--------------|
  714. // OMNET_WORKSET_LOCK_GRANT| - |SUCCESS, | - | - |
  715. // | | ->3 | | |
  716. // |---------+-----------+---------+--------------|
  717. // OMNET_WORKSET_LOCK_DENY | - |FAIL, ->1 | X | - |
  718. // | | | | |
  719. // |---------+-----------+---------+--------------|
  720. // OMINT_EVENT_LOCK_TIMEOUT | - |if other | - | - |
  721. // | |box gone, | | |
  722. // | |SUCCESS, | | |
  723. // | |->3, else | | |
  724. // | |FAIL, ->1 | | |
  725. // |---------+-----------+---------+--------------|
  726. // OMNET_WORKSET_UNLOCK | - | - | X | ->1 |
  727. // |---------+-----------+---------+--------------|
  728. //
  729. //
  730. // where 'X' indicates an error condition and '-' indicates that the event
  731. // or message is ignored.
  732. //
  733. //
  734. //
  735. //
  736. // NOTES FOR R2.0 WORKSET LOCKING
  737. //
  738. // 1. If A tries to lock a workset and B grants the lock but C denies it,
  739. // B will think that A has the lock. A has to broadcast an unlock,
  740. // or else B has to realise that the conflict will be resolved in
  741. // favour of C over A.
  742. //
  743. //
  744. //
  745. //
  746. // DATA PROPAGATION and FLOW NOTIFICATION PROTOCOL
  747. //
  748. // When a local Client adds an object to a workset, or replaces or updates
  749. // an existing object in a workset, ObMan broadcasts an appropriate
  750. // OMNET_... message on the workset group channel.
  751. //
  752. // This header message identifies the object and the type of operation to
  753. // be performed. It also includes a correlator value and the total size of
  754. // the data to be sent in the following data packets.
  755. //
  756. // After sending the header, ObMan broadcasts one or more
  757. // OMNET_GENERIC_DATA packets on the same channel. These packets, which
  758. // are of arbitrary size, all contain the same correlator value as was
  759. // included in the header packet.
  760. //
  761. // No sequence numbers are included as MCS guarantees that data packets
  762. // sent at the same priority on the same channel from the same node will
  763. // arrive at all other nodes in the sequence in which they were sent.
  764. //
  765. // It is the responsibility of the receiving node to detect when all data
  766. // packets have arrived and then to insert, update or replace the object in
  767. // the local copy of the workset.
  768. //
  769. // In addition, the receiving node, on receipt of EACH data packet sends a
  770. // data acknowledgment message (OMNET_DATA_ACK) to the sending node (on its
  771. // single-user channel), indicating the number of bytes received in that
  772. // data packet.
  773. //
  774. //
  775. //
  776. //
  777. // STANDARD OPERATION BROADCAST PROTOCOL
  778. //
  779. // When a local Client deletes or moves an object in a workset, or clears
  780. // or creates a workset, ObMan broadcasts a single uncorrelated operation
  781. // packet on the workset group channel.
  782. //
  783. // It is the responsibility of the receiving node to implement the
  784. // operation locally.
  785. //
  786. //
  787. //
  788. //
  789. // OPERATION SEQUENCING AND RESEQUENCING
  790. //
  791. // In order to consistently sequence operations which may arrive in
  792. // different sequences at different nodes, each operation carries with it
  793. // enough information for ObMan to reconstruct the workset, at each node,
  794. // as if all the operations on it had arrived in the same sequence.
  795. //
  796. // To do this, all operations are assigned a sequence stamp before being
  797. // broadcast. When ObMan receives an operation from the network, it
  798. // compares its stamp to various stamps it maintains locally. Whether and
  799. // how to perform the operation locally is determined on the basis of these
  800. // comparisons, according to the rules defined below.
  801. //
  802. //
  803. //
  804. //
  805. // SEQUENCE STAMPS AND THE WORKSET GENERATION NUMBER
  806. //
  807. // The sequencing order must be a globally consistent method of ordering
  808. // events ("global" here refers to geographical distribution of all nodes
  809. // operating on a given workset; it is not necessary that events be
  810. // sequenced across different worksets, since operations on separate
  811. // worksets can never interfere).
  812. //
  813. // We define an ObMan sequence stamp to be a combination of the workset
  814. // generation number and the node id.
  815. //
  816. // The node ID is the user ID allocated by the MCS subsystem to the ObMan
  817. // task and is therefore unique within a Domain.
  818. //
  819. // The workset generation number
  820. //
  821. // - is set to zero when the workset is created
  822. //
  823. // - is incremented each time ObMan performs an operation on behalf
  824. // of a local Client
  825. //
  826. // - is, whenever an operation arrives from the network, set to the
  827. // greater of its existing local value and the value in the
  828. // operation's sequence stamp.
  829. //
  830. // The ordering of sequence stamps is defined as follows (notation: stampX
  831. // = wsetGenX.nodeX):
  832. //
  833. // - if wsetGen1 < wsetGen2, then stamp1 < ("is lower than") stamp2
  834. //
  835. // - elsif wsetGen1 = wsetGen2, then
  836. //
  837. // - if node1 < node2, then stamp1 < stamp2
  838. //
  839. // - else stamp2 < stamp1.
  840. //
  841. // For the purposes of sequencing the different types of operations, ObMan
  842. // maintains
  843. //
  844. // - one sequence stamp per workset:
  845. //
  846. // - the last 'time' it was cleared (the clear stamp)
  847. //
  848. // - four sequence stamps per object:
  849. //
  850. // - the 'time' the object was added (the addition stamp)
  851. //
  852. // - the 'time' the object was last moved (the position stamp)
  853. //
  854. // - the 'time' the object was last updated (the update stamp)
  855. //
  856. // - the 'time' the object was last replace (the replace stamp; in
  857. // reality, only one of the update/replace stamps is required for
  858. // sequencing but both are needed for optimum spoiling).
  859. //
  860. // The initial values of the position, update and replace stamps are set to
  861. // the value of the addition stamp.
  862. //
  863. // The initial value of the clear stamp is set to <0.ID> where ID is the ID
  864. // of the node which created the workset.
  865. //
  866. // In addition, each object has a position field (either FIRST or LAST in
  867. // R1.1) which indicates where the object was most recently positioned i.e.
  868. // it is set when the object is added and then each time the object is
  869. // moved within the workset.
  870. //
  871. //
  872. //
  873. //
  874. // SEQUENCING PROTOCOLS
  875. //
  876. // The treatment of each type of operation is now considered in turn.
  877. //
  878. // 1. Operations on unknown objects or worksets
  879. //
  880. // ObMan may at any time receive operations on objects or worksets which do
  881. // not exist locally. These operations may be on objects or worksets which
  882. //
  883. // - this node has not yet heard of, or
  884. //
  885. // - have been deleted.
  886. //
  887. // Operations on the first kind need to be delayed and reprocessed at a
  888. // later time. Operations on the second kind can be thrown away (note that
  889. // there are no workset operations of this kind as once opened, worksets
  890. // are never deleted in the lifetime of the workset group).
  891. //
  892. // To differentiate between the two, ObMan keeps a record of deleted
  893. // objects. When an operation on a deleted object arrives, it is
  894. // discarded. When an operation arrives for an object which is not in
  895. // either the active object list or the deleted object list, ObMan bounces
  896. // the event from the network layer back to its event loop, with a suitable
  897. // delay, and attempts to process it later.
  898. //
  899. // For simplicity, the deleted object list is implemented by flagging
  900. // deleted objects as such and leaving them in the main list of objects
  901. // (i.e. the workset), rather than moving them to a separate list. The
  902. // object data is, however, discarded; only the object record needs to be
  903. // kept.
  904. //
  905. // Events from the network layer referring to operations on unknown
  906. // worksets are automatically bounced back onto ObMan's event queue.
  907. //
  908. // 2. Adding an object
  909. //
  910. // If ObMan receives an Add operation for an object which it has already
  911. // added to a workset (i.e. the object IDs are the same), it discards the
  912. // operation.
  913. //
  914. // This normally will not happen since each object is added by only one
  915. // node, and no node adds an object with the same ID twice.
  916. //
  917. // However, while a late-joiner is catching up with the contents of a
  918. // workset, it is possible that it will receive notification of a
  919. // particular object from both
  920. //
  921. // - the node which added the object
  922. //
  923. // - the helper node which is sending it the entire workset
  924. // contents.
  925. //
  926. // Therefore, the late-joiner checks object IDs as they arrive and discards
  927. // them if they have already been received. Note that since the
  928. // positioning algorithm presented below will position each occurrence of
  929. // the object in adjacent positions, checking for ID clashes is a simple
  930. // matter, performed after the correct position has been found.
  931. //
  932. // 3. Positioning (adding or moving) an object in a workset
  933. //
  934. // The desired sequence of objects in a workset is defined to be one
  935. // whereby
  936. //
  937. // - all the objects which were positioned at the start of a workset (FIRST
  938. // objects) are before all the objects which were positioned at the end
  939. // of a workset (LAST objects)
  940. //
  941. // - the position stamps of all the FIRST objects decrease monotonically
  942. // from the start of the workset forward
  943. //
  944. // - the position stamps of all the LAST objects decrease monotonically
  945. // from the end of the workset backward.
  946. //
  947. // Accordingly, the protocol when positioning an object at the start of a
  948. // workset is as follows (instructions for end-of-workset positioning in
  949. // brackets):
  950. //
  951. // ObMan searches forward (back) from the start (end) of the workset until
  952. // if finds an object which either
  953. //
  954. // - is not a FIRST (LAST) object, or
  955. //
  956. // - has a lower (lower) position stamp
  957. //
  958. // ObMan inserts the new/moved object before (after) this object.
  959. //
  960. // 4. Clearing a workset
  961. //
  962. // On receiving a Clear operation, ObMan searches through the workset and
  963. // deletes all objects which have an addition stamp lower than the clear
  964. // operation's stamp.
  965. //
  966. // On receiving an addition to a workset, ObMan discards the operation if
  967. // its stamp is lower than the workset's clear stamp.
  968. //
  969. // 5. Updating an object
  970. //
  971. // On receiving an Update operation, ObMan compares its stamp with the
  972. // object's update and replace stamps. If the operation's stamp is higher
  973. // than both, the operation is performed; otherwise, the operation is
  974. // discarded (since an Update is superceded either by a later Replace or by
  975. // a later Update).
  976. //
  977. // 6. Replacing an object
  978. //
  979. // On receiving a Replace operation, ObMan compares its stamp with the
  980. // object's replace stamp. If the operation's stamp is higher, the
  981. // operation is performed; otherwise, the operation is discarded (since a
  982. // Replace is superceded by a later Replace but not by a later Update).
  983. //
  984. // 7. Deleting an object
  985. //
  986. // By definition, a Delete is the last operation that should be performed
  987. // on an object. Delete operations are therefore processed immediately by
  988. // setting the <deleted> flag in the object record to TRUE.
  989. //
  990. //
  991. //
  992. //
  993. // OPERATION RESEQUENCING - SUMMARY
  994. //
  995. // In summary, therefore,
  996. //
  997. // - all object operations are discarded if object found on the deleted
  998. // object queue
  999. //
  1000. // - Add operations are discarded if they refer to an existing object.
  1001. //
  1002. // - Add/Clear operations are requeued if the workset is not present
  1003. // locally
  1004. //
  1005. // - Update/Replace/Move/Delete operations are requeued if the object or
  1006. // workset is not present locally
  1007. //
  1008. // - Update operations are discarded if an Update or a Replace with a later
  1009. // sequence stamp has already been received.
  1010. //
  1011. // - Replace operations are discarded if a Replace with a later sequence
  1012. // stamp has already been received.
  1013. //
  1014. // By default, all operations are performed.
  1015. //
  1016. //
  1017. //
  1018. //
  1019. // OBJECT IDS
  1020. //
  1021. // Object IDs are structures which identify an object within a workset.
  1022. // For a given workset, they are unique throughout the Domain.
  1023. //
  1024. // To ensure uniqueness, the MCS user ID is used as a (two-byte) prefix to
  1025. // a four-byte sequence number generated locally, on a per workset basis.
  1026. //
  1027. // Workset groups can exist independently of a Domain, and therefore
  1028. // potentially before ObMan has been allocated an MCS user ID. When
  1029. // allocating object IDs in this situation, ObMan uses zero (0) as the
  1030. // prefix to the sequence number.
  1031. //
  1032. // If that workset group is subsequently moved into a Domain, for all
  1033. // subsequent ID allocations ObMan uses its MCS user ID for that Domain as
  1034. // the prefix. Other instances of ObMan may also start adding objects to
  1035. // the worksets in the group at this point, and they too use their MCS user
  1036. // IDs as the object ID prefix. Uniqueness is preserved by the MCS
  1037. // guarantee that zero is never a valid user ID, so no post-share generated
  1038. // ID can conflict with a pre-share generated ID.
  1039. //
  1040. //
  1041. //
  1042. //
  1043. // SEQUENCE STAMPS
  1044. //
  1045. // Sequence stamps define a Domain-wide ordering for operations. They are
  1046. // used to correctly execute operations which may arrive at a node in an
  1047. // indeterminate order.
  1048. //
  1049. //
  1050. typedef struct tagOM_SEQUENCE_STAMP
  1051. {
  1052. TSHR_UINT32 genNumber; // the workset generation number
  1053. // which was current when the
  1054. // stamp was issued
  1055. NET_UID userID; // the MCS user ID for ObMan at
  1056. // the node which issued it
  1057. WORD pad1;
  1058. } OM_SEQUENCE_STAMP;
  1059. typedef OM_SEQUENCE_STAMP * POM_SEQUENCE_STAMP;
  1060. //
  1061. //
  1062. // OBJECT POSITION STAMPS
  1063. //
  1064. // When an object is added to or moved within a workset, it is important to
  1065. // know where it has been added. Therefore, Add and Move operations
  1066. // include within them a position field, with the following type:
  1067. //
  1068. //
  1069. typedef BYTE OM_POSITION;
  1070. //
  1071. // Possible values for an OM_POSITION variable:
  1072. //
  1073. #define LAST 1
  1074. #define FIRST 2
  1075. #define BEFORE 3
  1076. #define AFTER 4
  1077. //
  1078. //
  1079. // SEQUENCE STAMP MANIPULATION
  1080. //
  1081. // These macro manipulate sequence stamps.
  1082. //
  1083. //
  1084. //
  1085. //
  1086. // STAMP_IS_LOWER(stamp1, stamp2)
  1087. //
  1088. // This macro compares one sequence stamp with another. It evaluates to
  1089. // TRUE if the first stamp is lower than the second.
  1090. //
  1091. //
  1092. #define STAMP_IS_LOWER(stamp1, stamp2) \
  1093. \
  1094. (((stamp1).genNumber < (stamp2).genNumber) ? \
  1095. TRUE : \
  1096. (((stamp1).genNumber == (stamp2).genNumber) \
  1097. && \
  1098. ((stamp1).userID < (stamp2).userID)))
  1099. //
  1100. //
  1101. // SET_NULL_SEQ_STAMP(stamp)
  1102. //
  1103. // This macro sets the sequence stamp <stamp> to NULL.
  1104. //
  1105. //
  1106. #define SET_NULL_SEQ_STAMP(stamp) \
  1107. \
  1108. (stamp).userID = 0; \
  1109. (stamp).genNumber = 0
  1110. //
  1111. //
  1112. // SEQ_STAMP_IS_NULL(stamp)
  1113. //
  1114. // This macro evaluates to TRUE if the sequence stamp <stamp> is a NULL
  1115. // sequence stamp.
  1116. //
  1117. //
  1118. #define SEQ_STAMP_IS_NULL(stamp) \
  1119. \
  1120. ((stamp.userID == 0) && (stamp.genNumber == 0))
  1121. //
  1122. //
  1123. // COPY_SEQ_STAMP(stamp1, stamp2)
  1124. //
  1125. // This macro sets the value of the first sequence stamp to that of the
  1126. // second.
  1127. //
  1128. //
  1129. #define COPY_SEQ_STAMP(stamp1, stamp2) \
  1130. \
  1131. (stamp1).userID = (stamp2).userID; \
  1132. (stamp1).genNumber = (stamp2).genNumber
  1133. //
  1134. //
  1135. // MESSAGE FORMATS
  1136. //
  1137. // This section describes the formats of the messages sent between
  1138. // different instances of ObMan.
  1139. //
  1140. // The names of these messages are prefixed OMNET_...
  1141. //
  1142. // These events have the following format:
  1143. //
  1144. // typedef struct
  1145. // {
  1146. // OMNET_PKT_HEADER header;
  1147. // :
  1148. // : [various event specific fields]
  1149. // :
  1150. //
  1151. // } OMNET_...
  1152. //
  1153. // The OMNET_PKT_HEADER type is defined below.
  1154. //
  1155. //
  1156. typedef TSHR_UINT16 OMNET_MESSAGE_TYPE;
  1157. typedef struct tagOMNET_PKT_HEADER
  1158. {
  1159. NET_UID sender; // MCS user ID of sender
  1160. OMNET_MESSAGE_TYPE messageType; // == OMNET_...
  1161. }
  1162. OMNET_PKT_HEADER;
  1163. typedef OMNET_PKT_HEADER * POMNET_PKT_HEADER;
  1164. //
  1165. // Possible values for a OMNET_MESSAGE_TYPE variable:
  1166. //
  1167. #define OMNET_NULL_MESSAGE ((OMNET_MESSAGE_TYPE) 0x00)
  1168. #define OMNET_HELLO ((OMNET_MESSAGE_TYPE) 0x0A)
  1169. #define OMNET_WELCOME ((OMNET_MESSAGE_TYPE) 0x0B)
  1170. #define OMNET_LOCK_REQ ((OMNET_MESSAGE_TYPE) 0x15)
  1171. #define OMNET_LOCK_GRANT ((OMNET_MESSAGE_TYPE) 0x16)
  1172. #define OMNET_LOCK_DENY ((OMNET_MESSAGE_TYPE) 0x17)
  1173. #define OMNET_UNLOCK ((OMNET_MESSAGE_TYPE) 0x18)
  1174. #define OMNET_LOCK_NOTIFY ((OMNET_MESSAGE_TYPE) 0x19)
  1175. #define OMNET_WSGROUP_SEND_REQ ((OMNET_MESSAGE_TYPE) 0x1E)
  1176. #define OMNET_WSGROUP_SEND_MIDWAY ((OMNET_MESSAGE_TYPE) 0x1F)
  1177. #define OMNET_WSGROUP_SEND_COMPLETE ((OMNET_MESSAGE_TYPE) 0x20)
  1178. #define OMNET_WSGROUP_SEND_DENY ((OMNET_MESSAGE_TYPE) 0x21)
  1179. #define OMNET_WORKSET_CLEAR ((OMNET_MESSAGE_TYPE) 0x28)
  1180. #define OMNET_WORKSET_NEW ((OMNET_MESSAGE_TYPE) 0x29)
  1181. #define OMNET_WORKSET_CATCHUP ((OMNET_MESSAGE_TYPE) 0x30)
  1182. #define OMNET_OBJECT_ADD ((OMNET_MESSAGE_TYPE) 0x32)
  1183. #define OMNET_OBJECT_CATCHUP ((OMNET_MESSAGE_TYPE) 0x33)
  1184. #define OMNET_OBJECT_REPLACE ((OMNET_MESSAGE_TYPE) 0x34)
  1185. #define OMNET_OBJECT_UPDATE ((OMNET_MESSAGE_TYPE) 0x35)
  1186. #define OMNET_OBJECT_DELETE ((OMNET_MESSAGE_TYPE) 0x36)
  1187. #define OMNET_OBJECT_MOVE ((OMNET_MESSAGE_TYPE) 0x37)
  1188. #define OMNET_MORE_DATA ((OMNET_MESSAGE_TYPE) 0x46)
  1189. //
  1190. //
  1191. // GENERIC OPERATION PACKET
  1192. //
  1193. // ObMan uses this structure for the following messages:
  1194. //
  1195. // OMNET_MORE_DATA uses first 1 field (4 bytes), plus data
  1196. //
  1197. // OMNET_WORKSET_NEW } use first 7 fields (24 bytes)
  1198. // OMNET_WORKSET_CATCHUP }
  1199. //
  1200. // OMNET_WORKSET_CLEAR uses first 6 fields (16 bytes);
  1201. // doesn't use <position), <flags>
  1202. //
  1203. // OMNET_OBJECT_MOVE uses first 7 fields (24 bytes);
  1204. // doesn't use <flags>
  1205. //
  1206. // OMNET_OBJECT_DELETE uses first 7 fields (24 bytes);
  1207. // doesn't use <position), <flags>
  1208. //
  1209. // OMNET_OBJECT_REPLACE } use first 8 fields (28 bytes), plus
  1210. // OMNET_OBEJCT_UPDATE } data; don't use <position), <flags>
  1211. //
  1212. // OMNET_OBJECT_ADD uses first 9 fields (32 bytes), plus
  1213. // data; doesn't use <flags>
  1214. //
  1215. // OMNET_OBJECT_CATCHUP uses all 12 fields (56 bytes), plus
  1216. // data
  1217. //
  1218. //
  1219. typedef struct tagOMNET_OPERATION_PKT
  1220. {
  1221. OMNET_PKT_HEADER header;
  1222. OM_WSGROUP_ID wsGroupID;
  1223. OM_WORKSET_ID worksetID;
  1224. BYTE position; // <position> for Add/Move/Catchup
  1225. BYTE flags; // <flags> for ObjectCatchUp
  1226. //
  1227. // Note: for WORKSET_NEW/CATCHUP messages, the two bytes occupied by
  1228. // the <position> and <flags> fields hold a NET_PRIORITY value.
  1229. //
  1230. OM_SEQUENCE_STAMP seqStamp; // operation sequence stamp
  1231. // (== addStamp for ObjectCatchUp,
  1232. // curr stamp for WorksetCatchUp)
  1233. OM_OBJECT_ID objectID;
  1234. //
  1235. // Note: for WORKSET_NEW/CATCHUP messages, the first byte occupied
  1236. // by the <objectID> field holds a BOOL indicating whether the
  1237. // workset is persistent.
  1238. //
  1239. TSHR_UINT32 totalSize; // total size of transfer
  1240. TSHR_UINT32 updateSize;
  1241. OM_SEQUENCE_STAMP positionStamp;
  1242. OM_SEQUENCE_STAMP replaceStamp;
  1243. OM_SEQUENCE_STAMP updateStamp;
  1244. }
  1245. OMNET_OPERATION_PKT;
  1246. typedef OMNET_OPERATION_PKT * POMNET_OPERATION_PKT;
  1247. #define OMNET_MORE_DATA_SIZE 4
  1248. #define OMNET_WORKSET_NEW_SIZE 24
  1249. #define OMNET_WORKSET_CATCHUP_SIZE 24
  1250. #define OMNET_WORKSET_CLEAR_SIZE 16
  1251. #define OMNET_OBJECT_MOVE_SIZE 24
  1252. #define OMNET_OBJECT_DELETE_SIZE 24
  1253. #define OMNET_OBJECT_REPLACE_SIZE 28
  1254. #define OMNET_OBJECT_UPDATE_SIZE 28
  1255. #define OMNET_OBJECT_ADD_SIZE 32
  1256. #define OMNET_OBJECT_CATCHUP_SIZE 56
  1257. //
  1258. // These define the sizes of the packets we used in R1.1: we must only send
  1259. // packets of this size to R1.1 systems.
  1260. //
  1261. //
  1262. //
  1263. // HELLO/WELCOME MESSAGE
  1264. //
  1265. // When ObMan attaches to a Domain that contains an outgoing call, it
  1266. // broadcasts an OMNET_WELCOME message on the well-known ObManControl
  1267. // channel.
  1268. //
  1269. // When ObMan attaches to a Domain that contains an incoming call, it
  1270. // broadcasts an OMNET_HELLO message on the well-known ObManControl
  1271. // channel.
  1272. //
  1273. // When ObMan receives a HELLO message, it replies with a WELCOME message,
  1274. // just as if it had just joined the call.
  1275. //
  1276. // This allows each late-joining ObMan in the call to discover the user ID
  1277. // of each of the other instances of ObMan.
  1278. //
  1279. // A late-joining ObMan uses this information by asking one of the nodes
  1280. // which WELCOMEd it for a copy of the ObManControl workset group.
  1281. //
  1282. // HELLO/WELCOME packets are NEVER compressed.
  1283. //
  1284. // WELCOME and HELLO messages have the following format:
  1285. //
  1286. //
  1287. typedef struct tagOMNET_JOINER_PKT
  1288. {
  1289. OMNET_PKT_HEADER header;
  1290. TSHR_UINT32 capsLen; // == 4 in this version.
  1291. TSHR_UINT32 compressionCaps; // bitwise OR of OM_CAPS_ bits
  1292. }
  1293. OMNET_JOINER_PKT;
  1294. typedef OMNET_JOINER_PKT * POMNET_JOINER_PKT;
  1295. //
  1296. // The actual compression type used in any given packet is specified as the
  1297. // first byte of the packet (before the header and other structures
  1298. // specified in this file). The compression type is the numeric value of
  1299. // the bit position corresponding to the compression capability. For
  1300. // example, if XYZ compression has a capability value of 0x8, then packets
  1301. // compressed with XYZ will have 3 in their first byte.
  1302. //
  1303. // '0' is never valid as an OM_PROT_... compression type (which is why bit
  1304. // 1 is not used as an OM_CAPS_... flag).
  1305. //
  1306. #define OM_PROT_PKW_COMPRESSED 0x01
  1307. #define OM_PROT_NOT_COMPRESSED 0x02
  1308. //
  1309. // Values for compressionCaps. These must be separate bits, since they may
  1310. // be ORed together if a node supports multiple compression types.
  1311. //
  1312. // Note that OM_CAPS_NO_COMPRESSION is always supported.
  1313. //
  1314. // Bit 1 is not used.
  1315. //
  1316. #define OM_CAPS_PKW_COMPRESSION 0x0002
  1317. #define OM_CAPS_NO_COMPRESSION 0x0004
  1318. //
  1319. //
  1320. // LATE-JOINER PROTOCOL - WORKSET GROUP SEND REQUEST/SEND COMPLETE
  1321. //
  1322. // The SEND_REQUEST message is sent when ObMan has "late-joined" a
  1323. // particular workset group and would like another node to send it the
  1324. // current contents.
  1325. //
  1326. // The message is sent to an arbitrary "helper" node (known to have a copy
  1327. // of the workset group) on its single-user channel.
  1328. //
  1329. // The recipient responds by flushing the relevant channel (in R1.1, a
  1330. // no-op; in R2.0, perform a WORKSET_CHECKPOINT) and then sending the
  1331. // contents of the workset.
  1332. //
  1333. // When the WORKSET_CATCHUP messages have been sent, we send a
  1334. // WSGROUP_SEND_MIDWAY message to let the late joiner know that it now
  1335. // knows about all the worksets which are currently in use (otherwise, it
  1336. // might create a workset already in use which happened to be locked on the
  1337. // sending machine add then an object to it.
  1338. //
  1339. // The SEND_MIDWAY message also containing the max sequence number
  1340. // previously used by the late joiner's ID in this workset group (to
  1341. // prevent re-use of object IDs).
  1342. //
  1343. // When the contents have been sent, i.e. after the last data packet of
  1344. // the last object in the last workset of the group, the helper sends a
  1345. // SEND_COMPLETE message.
  1346. //
  1347. // If the chosen helper node is not in a position to send the contents of
  1348. // the workset group, it must repsond with a SEND_DENY message, upon
  1349. // receipt of which the late joiner will choose someone else to catch up
  1350. // from.
  1351. //
  1352. // The SEND_REQUEST, SEND_MIDWAY, SEND_COMPLETE and SEND_DENY message
  1353. // packets have the following structure:
  1354. //
  1355. //
  1356. typedef struct tagOMNET_WSGROUP_SEND_PKT
  1357. {
  1358. OMNET_PKT_HEADER header;
  1359. OM_WSGROUP_ID wsGroupID;
  1360. BYTE pad1;
  1361. TSHR_UINT16 correlator; // Holds the catchup correlator
  1362. OM_OBJECT_ID objectID;
  1363. TSHR_UINT32 maxObjIDSeqUsed;
  1364. }
  1365. OMNET_WSGROUP_SEND_PKT;
  1366. typedef OMNET_WSGROUP_SEND_PKT * POMNET_WSGROUP_SEND_PKT;
  1367. //
  1368. //
  1369. // LOCKING PROTOCOL - LOCK PACKET
  1370. //
  1371. // When ObMan wants to lock a workset/object, it broadcasts one of these
  1372. // packets (with type == OMNET_LOCK_REQ).
  1373. //
  1374. // When ObMan receives one of these packets, it decides to deny or grant
  1375. // the lock to the sender, and replies with another packet of the same
  1376. // structure but with type == OMNET_LOCK_DENY or OMNET_LOCK_GRANT as
  1377. // appropriate.
  1378. //
  1379. // When ObMan wants to unlock a workste/object it has previously locked, it
  1380. // broadcasts one of these packets with type == OMNET_UNLOCK.
  1381. //
  1382. typedef struct tagOMNET_LOCK_PKT
  1383. {
  1384. OMNET_PKT_HEADER header;
  1385. OM_WSGROUP_ID wsGroupID;
  1386. OM_WORKSET_ID worksetID;
  1387. TSHR_UINT16 data1; // used as correlator for GRANT/DENY
  1388. // used to indicate who's got lock
  1389. // for NOTIFY
  1390. // lon: need to keep pLockReqCB field for backward compatability!
  1391. void * pLockReqCB; // R1.1 uses this to find the lock
  1392. // request CB
  1393. }
  1394. OMNET_LOCK_PKT;
  1395. typedef OMNET_LOCK_PKT * POMNET_LOCK_PKT;
  1396. //
  1397. //
  1398. // DATA STRUCTURES
  1399. //
  1400. //
  1401. //
  1402. //
  1403. // OPERATION TYPES
  1404. //
  1405. // This is the type defined for operations which Clients may perform on
  1406. // objects and worksets. Pending operation lists use this type.
  1407. //
  1408. //
  1409. typedef TSHR_UINT16 OM_OPERATION_TYPE;
  1410. //
  1411. // Possible values for a OM_OPERATION_TYPE variable:
  1412. //
  1413. #define NULL_OP ((OM_OPERATION_TYPE) 0)
  1414. #define WORKSET_CLEAR ((OM_OPERATION_TYPE) 1)
  1415. #define OBJECT_ADD ((OM_OPERATION_TYPE) 2)
  1416. #define OBJECT_MOVE ((OM_OPERATION_TYPE) 3)
  1417. #define OBJECT_DELETE ((OM_OPERATION_TYPE) 4)
  1418. #define OBJECT_REPLACE ((OM_OPERATION_TYPE) 5)
  1419. #define OBJECT_UPDATE ((OM_OPERATION_TYPE) 6)
  1420. //
  1421. //
  1422. // PENDING OPERATION LISTS
  1423. //
  1424. // When ObMan receives a request (either from a local Client or over the
  1425. // network) to delete, update or replace an object, or to clear a workset,
  1426. // it cannot perform the operation until the local Client has confirmed it.
  1427. // These operations are therefore put in a list and processed when the
  1428. // appropriate Confirm function is invoked.
  1429. //
  1430. // This list is hung off the workset record; its elements have the
  1431. // following format:
  1432. //
  1433. //
  1434. typedef struct tagOM_PENDING_OP
  1435. {
  1436. STRUCTURE_STAMP
  1437. BASEDLIST chain;
  1438. POM_OBJECT pObj; // NULL if a clear operation
  1439. POM_OBJECTDATA pData;
  1440. OM_SEQUENCE_STAMP seqStamp; // the sequence stamp which was
  1441. // current in the workset when the
  1442. // operation was invoked
  1443. OM_OPERATION_TYPE type; // == WORKSET_CLEAR, OBJECT_DELETE,
  1444. // OBJECT_UPDATE or OBJECT_REPLACE
  1445. WORD pad1;
  1446. }
  1447. OM_PENDING_OP;
  1448. typedef OM_PENDING_OP * POM_PENDING_OP;
  1449. //
  1450. //
  1451. // OBJECT RECORDS
  1452. //
  1453. // This structure holds information about a particular object,
  1454. //
  1455. typedef struct tagOM_OBJECT
  1456. {
  1457. STRUCTURE_STAMP
  1458. BASEDLIST chain;
  1459. OM_OBJECT_ID objectID; // Unique within domain
  1460. POM_OBJECTDATA pData; // Ptr to data
  1461. OM_SEQUENCE_STAMP addStamp; // the sequence stamps used
  1462. OM_SEQUENCE_STAMP positionStamp; OM_SEQUENCE_STAMP replaceStamp;
  1463. OM_SEQUENCE_STAMP updateStamp;
  1464. UINT updateSize; // size of (all) updates
  1465. BYTE flags; // defined below
  1466. OM_POSITION position; // either LAST or FIRST,
  1467. // indicating where the object
  1468. // was most recently placed
  1469. WORD pad1;
  1470. }
  1471. OM_OBJECT;
  1472. BOOL __inline ValidObject(POM_OBJECT pObj)
  1473. {
  1474. return(!IsBadWritePtr(pObj, sizeof(OM_OBJECT)));
  1475. }
  1476. void __inline ValidateObject(POM_OBJECT pObj)
  1477. {
  1478. ASSERT(ValidObject(pObj));
  1479. }
  1480. //
  1481. // Flags used:
  1482. //
  1483. #define DELETED 0x0001
  1484. #define PENDING_DELETE 0x0002
  1485. //
  1486. //
  1487. // UNUSED OBJECTS LISTS
  1488. //
  1489. // When a Client allocates an object using OM_ObjectAlloc, a reference to
  1490. // the memory allocated is stored in the Client's unused objects list for
  1491. // this workset group.
  1492. //
  1493. // The reference is removed when the Client either
  1494. //
  1495. // - discards the object using OM_ObjectDiscard, or
  1496. //
  1497. // - inserts the object in a workset with an Add, Update or Replace
  1498. // function.
  1499. //
  1500. // This list of objects (which is hung off the usage record) is checked
  1501. // when a workset is closed to discard any objects the Client didn't
  1502. // explicitly discard or use.
  1503. //
  1504. // The elements of the list have the following form:
  1505. //
  1506. //
  1507. typedef struct tagOM_OBJECTDATA_LIST
  1508. {
  1509. STRUCTURE_STAMP
  1510. BASEDLIST chain;
  1511. POM_OBJECTDATA pData;
  1512. UINT size; // Used to verify that Client hasn't grown size
  1513. OM_WORKSET_ID worksetID;
  1514. BYTE pad1;
  1515. WORD pad2;
  1516. }
  1517. OM_OBJECTDATA_LIST;
  1518. typedef OM_OBJECTDATA_LIST * POM_OBJECTDATA_LIST;
  1519. //
  1520. //
  1521. // OBJECTS-IN-USE LISTS
  1522. //
  1523. // When a Client reads an object using OM_ObjectRead, the use count of the
  1524. // chunk of memory containing the object is increased.
  1525. //
  1526. // The use count is deceremented again when the Client calls
  1527. // OM_ObjectRelease, but if the Client abends, or simply closes a workset
  1528. // without releasing the objects it has read, we still need to be able to
  1529. // free the memory.
  1530. //
  1531. // Therefore we keep a list, on a per-workset-group basis, of the objects
  1532. // that a Client is using. Objects (identified by handles) are added to
  1533. // the list when a Client calls OM_ObjectRead, and removed from the list
  1534. // when the Client calls OM_ObjectRelease.
  1535. //
  1536. // In addition, the list is checked when a workset is closed to release any
  1537. // handles the Client didn't release explicitly.
  1538. //
  1539. // Like the unused objects list, this list is hung off the usage record.
  1540. //
  1541. // The elements of these lists have the following form:
  1542. //
  1543. //
  1544. typedef struct tagOM_OBJECT_LIST
  1545. {
  1546. STRUCTURE_STAMP
  1547. BASEDLIST chain;
  1548. POM_OBJECT pObj;
  1549. OM_WORKSET_ID worksetID; // the ID of the workset
  1550. BYTE pad1;
  1551. WORD pad2;
  1552. }
  1553. OM_OBJECT_LIST;
  1554. typedef OM_OBJECT_LIST * POM_OBJECT_LIST;
  1555. //
  1556. //
  1557. // NODE LIST STRUCTURES
  1558. //
  1559. // When requesting locks etc. from other nodes in a Domain, ObMan keeps a
  1560. // list of remote nodes which it expects a reply from. A node is
  1561. // identified by the MCS user ID of the instance of ObMan running on that
  1562. // node.
  1563. //
  1564. // The elements of these lists have the folllowing form:
  1565. //
  1566. //
  1567. typedef struct tagOM_NODE_LIST
  1568. {
  1569. STRUCTURE_STAMP
  1570. BASEDLIST chain;
  1571. NET_UID userID; // user ID of remote ObMan
  1572. WORD pad1;
  1573. }
  1574. OM_NODE_LIST;
  1575. typedef OM_NODE_LIST * POM_NODE_LIST;
  1576. //
  1577. //
  1578. // LOCK REQUEST CONTROL BLOCKS
  1579. //
  1580. // When ObMan is in the process of getting a lock for a workset or object
  1581. // it creates one of these structures to correlate the lock replies.
  1582. //
  1583. //
  1584. typedef struct tagOM_LOCK_REQ
  1585. {
  1586. STRUCTURE_STAMP
  1587. BASEDLIST chain;
  1588. PUT_CLIENT putTask; // task to notify on success
  1589. // or failure
  1590. OM_CORRELATOR correlator; // returned by WorksetLockReq
  1591. OM_WSGROUP_ID wsGroupID; // workset group and workset
  1592. OM_WORKSET_ID worksetID; // containing the lock
  1593. POM_WSGROUP pWSGroup;
  1594. BASEDLIST nodes; // MCS user IDs of nodes which
  1595. // haven't yet replies to req
  1596. // (an OM_NODE_LIST list)
  1597. WORD retriesToGo; // Decremented on each timeout
  1598. OM_WSGROUP_HANDLE hWSGroup;
  1599. BYTE type; // PRIMARY or SECONDARY
  1600. }
  1601. OM_LOCK_REQ;
  1602. typedef OM_LOCK_REQ * POM_LOCK_REQ;
  1603. #define LOCK_PRIMARY 0x01
  1604. #define LOCK_SECONDARY 0x02
  1605. //
  1606. //
  1607. // CLIENT LIST STRUCTURE
  1608. //
  1609. // The lists of Clients stored per workset group and per workset contain
  1610. // elements of this type. The <hWSGroup> field refers to the workset group
  1611. // handle by which the Client knows the workset group concerned.
  1612. //
  1613. //
  1614. typedef struct tagOM_CLIENT_LIST
  1615. {
  1616. STRUCTURE_STAMP
  1617. BASEDLIST chain;
  1618. PUT_CLIENT putTask; // the Client's putTask
  1619. WORD mode;
  1620. OM_WSGROUP_HANDLE hWSGroup;
  1621. BYTE pad1;
  1622. }
  1623. OM_CLIENT_LIST;
  1624. typedef OM_CLIENT_LIST * POM_CLIENT_LIST;
  1625. //
  1626. //
  1627. // WORKSET RECORDS
  1628. //
  1629. // This structure holds the state information for a workset. It resides at
  1630. // offset zero (0) in the huge memory block associated with this workset.
  1631. //
  1632. // ObMan allocates a workset record when a workset is created and discards
  1633. // it when the workset is discarded.
  1634. //
  1635. //
  1636. typedef struct tagOM_WORKSET
  1637. {
  1638. STRUCTURE_STAMP
  1639. UINT numObjects; // the current number of objects in
  1640. // workset (excluding the sentinels)
  1641. UINT genNumber; // current workset generation number
  1642. OM_SEQUENCE_STAMP clearStamp; // the clear stamp for the workset
  1643. NET_PRIORITY priority; // MCS priority for the workset
  1644. OM_WORKSET_ID worksetID;
  1645. BYTE lockState; // one of the values defined below
  1646. WORD lockCount; // LOCAL lock count
  1647. NET_UID lockedBy; // MCS user ID of node which has the
  1648. // lock, if any
  1649. BASEDLIST objects; // root of list of workset's objects
  1650. UINT bytesUnacked; // bytes still to be acked
  1651. BASEDLIST pendingOps; // root of list of operations which
  1652. // are pending for this workset
  1653. BASEDLIST clients; // root of list of Clients which
  1654. // have this workset open
  1655. BOOL fTemp;
  1656. }
  1657. OM_WORKSET;
  1658. typedef OM_WORKSET * POM_WORKSET;
  1659. void __inline ValidateWorkset(POM_WORKSET pWorkset)
  1660. {
  1661. ASSERT(!IsBadWritePtr(pWorkset, sizeof(OM_WORKSET)));
  1662. }
  1663. //
  1664. // Possible values for the <lockState> field above:
  1665. //
  1666. #define UNLOCKED 0x00
  1667. #define LOCKING 0x01
  1668. #define LOCKED 0x02
  1669. #define LOCK_GRANTED 0x03
  1670. //
  1671. //
  1672. // WORKSET GROUP RECORDS
  1673. //
  1674. // This structure holds information about a workset group.
  1675. //
  1676. // ObMan maintains one of these structures for each workset group with
  1677. // which one or more local Clients are registered.
  1678. //
  1679. // It will be discarded when the last local Client registered with the
  1680. // workset group deregisters from it.
  1681. //
  1682. //
  1683. typedef struct tagOM_WSGROUP
  1684. {
  1685. STRUCTURE_STAMP
  1686. BASEDLIST chain;
  1687. OMWSG wsg;
  1688. OMFP fpHandler;
  1689. NET_CHANNEL_ID channelID; // MCS channel ID used for WSG
  1690. OM_WSGROUP_ID wsGroupID; // workset group ID
  1691. BYTE state; // one of the values defined below
  1692. POM_OBJECT pObjReg; // Registration object in the OMC workset
  1693. BASEDLIST clients; // the Clients using the WSG
  1694. POM_DOMAIN pDomain;
  1695. NET_UID helperNode; // ID of the node we are catching up from.
  1696. WORD valid:1;
  1697. WORD toBeDiscarded:1;
  1698. UINT bytesUnacked; // sum of bytesUnacked field for each
  1699. // workset in the workset group
  1700. BYTE sendMidwCount; // # of SEND_MIDWAYs received
  1701. BYTE sendCompCount; // # of SEND_MIDWAYs received
  1702. OM_CORRELATOR catchupCorrelator; // Used to correlate SEND_REQUESTS
  1703. // to SEND_MIDWAYs and
  1704. // SEND_COMPLETEs.
  1705. POM_WORKSET apWorksets[ OM_MAX_WORKSETS_PER_WSGROUP + 1];
  1706. }
  1707. OM_WSGROUP;
  1708. void __inline ValidateWSGroup(POM_WSGROUP pWSGroup)
  1709. {
  1710. ASSERT(!IsBadWritePtr(pWSGroup, sizeof(OM_WSGROUP)));
  1711. }
  1712. //
  1713. // Workset group <state> values
  1714. //
  1715. #define INITIAL 0x00
  1716. #define LOCKING_OMC 0x01
  1717. #define PENDING_JOIN 0x02
  1718. #define PENDING_SEND_MIDWAY 0x03
  1719. #define PENDING_SEND_COMPLETE 0x04
  1720. #define WSGROUP_READY 0x05
  1721. //
  1722. //
  1723. // USAGE RECORDS
  1724. //
  1725. // A usage record identifies a Client's use of a particular workset group
  1726. // and holds state information about that usage.
  1727. //
  1728. // Usage records reside in the OMGLBOAL memory block at the offset (from
  1729. // the base) specified in the Client record.
  1730. //
  1731. //
  1732. typedef struct tagOM_USAGE_REC
  1733. {
  1734. STRUCTURE_STAMP
  1735. POM_WSGROUP pWSGroup; // Client pointer to workset group
  1736. BASEDLIST unusedObjects; // start sentinel in list of
  1737. // pointers to unused objects
  1738. BASEDLIST objectsInUse; // OM_OBJECT_LIST
  1739. BYTE mode;
  1740. BYTE flags;
  1741. BYTE worksetOpenFlags[(OM_MAX_WORKSETS_PER_WSGROUP + 7)/8];
  1742. // bitfield array of flags
  1743. // indicating the worksets the
  1744. // Client has open
  1745. }
  1746. OM_USAGE_REC;
  1747. typedef OM_USAGE_REC * POM_USAGE_REC;
  1748. __inline void ValidateUsageRec(POM_USAGE_REC pUsageRec)
  1749. {
  1750. ASSERT(!IsBadWritePtr(pUsageRec, sizeof(OM_USAGE_REC)));
  1751. }
  1752. //
  1753. // Values for flags:
  1754. //
  1755. #define ADDED_TO_WSGROUP_LIST 0x0002
  1756. #define PWSGROUP_IS_PREGCB 0x0004
  1757. //
  1758. //
  1759. // LOCK STACKS
  1760. //
  1761. // Clients must request and release object and workset locks in accordance
  1762. // with the Universal Locking Order as defined in the Functional Spec (in
  1763. // order to avoid deadlock).
  1764. //
  1765. // In order to detect lock order violations, ObMan maintains, for each
  1766. // Client, a stack of locks which the Client holds or has requested. This
  1767. // stack is implemented as a linked list, with the most recently acquired
  1768. // lock (which must, by definition, be the one latest in the Universal
  1769. // Locking Order) being the first element.
  1770. //
  1771. // A Client's lock stack is initialised when the Client registers with
  1772. // ObMan and discarded when the Client deregisters from ObMan. Lock stacks
  1773. // are hung off the Client record.
  1774. //
  1775. // Note that we need the store the object ID here, as opposed to the
  1776. // handle, since we must enforce the universal lock order across all nodes.
  1777. //
  1778. // Elements of lock stacks have the following form:
  1779. //
  1780. //
  1781. typedef struct tagOM_LOCK
  1782. {
  1783. STRUCTURE_STAMP
  1784. BASEDLIST chain;
  1785. POM_WSGROUP pWSGroup; // Client pointer to workset group
  1786. // needed to detect lock violations
  1787. OM_OBJECT_ID objectID; // the object ID is 0 if this is a
  1788. // workset lock (in R1.1, always).
  1789. OM_WORKSET_ID worksetID;
  1790. BYTE pad1;
  1791. WORD pad2;
  1792. }
  1793. OM_LOCK;
  1794. typedef OM_LOCK * POM_LOCK;
  1795. int __inline CompareLocks(POM_LOCK pLockFirst, POM_LOCK pLockSecond)
  1796. {
  1797. int result;
  1798. result = (pLockSecond->pWSGroup->wsg - pLockFirst->pWSGroup->wsg);
  1799. if (result == 0)
  1800. {
  1801. // Same WSG, so compare worksets
  1802. result = (pLockSecond->worksetID - pLockFirst->worksetID);
  1803. }
  1804. return(result);
  1805. }
  1806. //
  1807. //
  1808. // CLIENT RECORD
  1809. //
  1810. // ObMan maintains instance data for every registered Client. This
  1811. // structure, a Client record, holds the Client instance data.
  1812. //
  1813. // A Client's ObMan handle is a Client pointer to this structure.
  1814. //
  1815. // A Client's workset group handle is an index into the array of usage record
  1816. // ptrs.
  1817. //
  1818. // If the value of apUsageRecs is 0 or -1, x is not a valid workset
  1819. // group handle.
  1820. //
  1821. //
  1822. typedef struct tagOM_CLIENT
  1823. {
  1824. STRUCTURE_STAMP
  1825. PUT_CLIENT putTask;
  1826. BOOL exitProcReg:1;
  1827. BOOL hiddenHandlerReg:1;
  1828. BASEDLIST locks; // root of list of locks held
  1829. POM_USAGE_REC apUsageRecs[OMWSG_MAXPERCLIENT];
  1830. BOOL wsgValid[OMWSG_MAXPERCLIENT];
  1831. }
  1832. OM_CLIENT;
  1833. BOOL __inline ValidWSGroupHandle(POM_CLIENT pomClient, OM_WSGROUP_HANDLE hWSGroup)
  1834. {
  1835. return((hWSGroup != 0) &&
  1836. (pomClient->wsgValid[hWSGroup]) &&
  1837. (pomClient->apUsageRecs[hWSGroup] != NULL));
  1838. }
  1839. //
  1840. //
  1841. // DOMAIN RECORD
  1842. //
  1843. // This structure holds information about a Domain. We support two:
  1844. // * The current call
  1845. // * Limbo (no call) for cleanup after a call and maintenance of info
  1846. // across calls
  1847. //
  1848. typedef struct tagOM_DOMAIN
  1849. {
  1850. STRUCTURE_STAMP
  1851. BASEDLIST chain;
  1852. UINT callID; // MCS Domain Handle
  1853. NET_UID userID; // ObMan's MCS user ID and token ID
  1854. NET_TOKEN_ID tokenID; // for this domain
  1855. NET_CHANNEL_ID omcChannel; // ObMan's broadcast channel
  1856. BYTE state; // one of the values defined below
  1857. BYTE omchWSGroup; // ObMan's hWSGroup for this domain's
  1858. BOOL valid:1;
  1859. BOOL sendEventOutstanding:1;
  1860. UINT compressionCaps; // Domain-wide compression caps
  1861. BASEDLIST wsGroups; // root of list of workset groups
  1862. BASEDLIST pendingRegs; // root of list of pending workset
  1863. // group registration request
  1864. BASEDLIST pendingLocks; // root of list of pending
  1865. // lock requests
  1866. BASEDLIST receiveList; // root of list of control blocks
  1867. // for receives in progress
  1868. BASEDLIST bounceList; // root of list of control blocks
  1869. // for bounced messages
  1870. BASEDLIST helperCBs; // root of list of helper CBs for
  1871. // checkpoints in progress
  1872. BASEDLIST sendQueue[NET_NUM_PRIORITIES];
  1873. // array of roots of list of send
  1874. // queue instructions (by priority)
  1875. BOOL sendInProgress[NET_NUM_PRIORITIES];
  1876. // array of send-in-progress flags
  1877. }
  1878. OM_DOMAIN;
  1879. //
  1880. // Possible values for <state> field:
  1881. //
  1882. #define PENDING_ATTACH 0x01
  1883. #define PENDING_JOIN_OWN 0x02
  1884. #define PENDING_JOIN_OMC 0x03
  1885. #define PENDING_TOKEN_ASSIGN 0x04
  1886. #define PENDING_TOKEN_GRAB 0x05
  1887. #define PENDING_TOKEN_INHIBIT 0x06
  1888. #define PENDING_WELCOME 0x07
  1889. #define GETTING_OMC 0x08
  1890. #define DOMAIN_READY 0x09
  1891. //
  1892. //
  1893. // SHARED MEMORY STRUCTURE
  1894. //
  1895. // This structure holds various private (to ObMan) state information.
  1896. //
  1897. // The ObMan task allocates and initialises one instance of this structure
  1898. // when it initialises; it resides at the base of the OMGLOBAL memory
  1899. // block.
  1900. //
  1901. // It is discarded when the ObMan task terminates.
  1902. //
  1903. //
  1904. typedef struct tagOM_PRIMARY
  1905. {
  1906. STRUCTURE_STAMP
  1907. PUT_CLIENT putTask;
  1908. PMG_CLIENT pmgClient; // OM's network layer handle
  1909. PCM_CLIENT pcmClient; // OM's Call Manager handle
  1910. BASEDLIST domains; // Domains
  1911. OM_CLIENT clients[OMCLI_MAX]; // Secondaries
  1912. UINT objectIDsequence;
  1913. BOOL exitProcReg:1;
  1914. BOOL eventProcReg:1;
  1915. OM_CORRELATOR correlator;
  1916. WORD pad1;
  1917. LPBYTE pgdcWorkBuf;
  1918. BYTE compressBuffer[OM_NET_SEND_POOL_SIZE / 2];
  1919. }
  1920. OM_PRIMARY;
  1921. void __inline ValidateOMP(POM_PRIMARY pomPrimary)
  1922. {
  1923. ASSERT(!IsBadWritePtr(pomPrimary, sizeof(OM_PRIMARY)));
  1924. }
  1925. void __inline ValidateOMS(POM_CLIENT pomClient)
  1926. {
  1927. extern POM_PRIMARY g_pomPrimary;
  1928. ValidateOMP(g_pomPrimary);
  1929. ASSERT(!IsBadWritePtr(pomClient, sizeof(OM_CLIENT)));
  1930. ASSERT(pomClient < &(g_pomPrimary->clients[OMCLI_MAX]));
  1931. ASSERT(pomClient >= &(g_pomPrimary->clients[OMCLI_FIRST]));
  1932. }
  1933. //
  1934. //
  1935. // Workset group registration/move request control block
  1936. //
  1937. // This structure is used to pass the parameters of a workset group
  1938. // registration/move request to the ObMan task (from a Client task).
  1939. //
  1940. // Not all fields are used by both the registration and the move process.
  1941. //
  1942. // The <type> field is used to distinguish between a WSGroupMove and a
  1943. // WSGroupRegister.
  1944. //
  1945. //
  1946. typedef struct tagOM_WSGROUP_REG_CB
  1947. {
  1948. STRUCTURE_STAMP
  1949. BASEDLIST chain;
  1950. PUT_CLIENT putTask;
  1951. UINT callID;
  1952. OMWSG wsg;
  1953. OMFP fpHandler;
  1954. OM_CORRELATOR correlator;
  1955. OM_CORRELATOR lockCorrelator;
  1956. OM_CORRELATOR channelCorrelator;
  1957. WORD retryCount;
  1958. POM_USAGE_REC pUsageRec;
  1959. POM_WSGROUP pWSGroup;
  1960. POM_DOMAIN pDomain; // ObMan pointer to Domain record
  1961. BOOL valid;
  1962. OM_WSGROUP_HANDLE hWSGroup;
  1963. BYTE type; // REGISTER or MOVE
  1964. BYTE mode; // PRIMARY or SECONDARY
  1965. BYTE flags; // see below
  1966. }
  1967. OM_WSGROUP_REG_CB;
  1968. typedef OM_WSGROUP_REG_CB * POM_WSGROUP_REG_CB;
  1969. //
  1970. // Values for the <type> field:
  1971. //
  1972. #define WSGROUP_MOVE 0x01
  1973. #define WSGROUP_REGISTER 0x02
  1974. //
  1975. // Flags for the <flags> field:
  1976. //
  1977. #define BUMPED_CBS 0x0001 // indicates whether we bumped use
  1978. // counts of pWSGroup, pDomain
  1979. #define LOCKED_OMC 0x0002 // indicates whether we've locked
  1980. // ObManControl
  1981. //
  1982. // Values for the <mode> field (we use the flag macro because the values
  1983. // may be ORed together and so need to be bit-independent):
  1984. //
  1985. #define PRIMARY 0x0001
  1986. #define SECONDARY 0x0002
  1987. //
  1988. //
  1989. // HELPER CONTROL BLOCK
  1990. //
  1991. // When we receive a WSG_SEND_REQUEST from a remote node, we checkpoint the
  1992. // workset group requested. This is an asynchronous process (it's
  1993. // essentially getting a lock on a dummy workset), so we need to store the
  1994. // details of the remote node away somewhere. We do this using a help CB
  1995. // with the following structure:
  1996. //
  1997. //
  1998. typedef struct tagOM_HELPER_CB
  1999. {
  2000. STRUCTURE_STAMP
  2001. BASEDLIST chain;
  2002. NET_UID lateJoiner; // MCS user ID of late joiner
  2003. OM_CORRELATOR remoteCorrelator;
  2004. POM_WSGROUP pWSGroup; // pWSGroup is bumped during
  2005. // checkpoint
  2006. OM_CORRELATOR lockCorrelator; // returned by WorksetLockReq
  2007. // and recd in WORKSET_LOCK_CON
  2008. WORD pad1;
  2009. }
  2010. OM_HELPER_CB;
  2011. typedef OM_HELPER_CB * POM_HELPER_CB;
  2012. //
  2013. //
  2014. // THE SEND QUEUE
  2015. //
  2016. // For each Domain, and for each network priority, ObMan maintains a queue
  2017. // of message and data to be sent to the network. Clients, when executing
  2018. // API functions, cause instructions to be added to the tail of one of
  2019. // these queues.
  2020. //
  2021. // The ObMan task, in response to an OMINT_EVENT_SEND_QUEUE event, processes as
  2022. // many send queue operations as possible, giving up for a while when it
  2023. // runs out of network buffers.
  2024. //
  2025. // This is subject to the restriction that no operations are processed from
  2026. // one send queue when operations exist on a queue of higher priority in
  2027. // the same Domain.
  2028. //
  2029. // Instructions on the send queue have the following format:
  2030. //
  2031. //
  2032. typedef struct tagOM_SEND_INST
  2033. {
  2034. STRUCTURE_STAMP
  2035. BASEDLIST chain;
  2036. UINT callID; // the relevant Domain
  2037. NET_CHANNEL_ID channel; // the channel to send the event on
  2038. NET_PRIORITY priority; // priority to send event on
  2039. POM_WSGROUP pWSGroup;
  2040. POM_WORKSET pWorkset;
  2041. POMNET_PKT_HEADER pMessage;
  2042. POM_OBJECT pObj;
  2043. POM_OBJECTDATA pDataStart;
  2044. POM_OBJECTDATA pDataNext;
  2045. WORD messageSize; // length of message at pMessage
  2046. OMNET_MESSAGE_TYPE messageType; // == OMNET_OBJECT_ADD, etc.
  2047. UINT dataLeftToGo; // number of bytes of data left to
  2048. // be sent
  2049. UINT compressOrNot; // Some packets are never compressed
  2050. }
  2051. OM_SEND_INST;
  2052. typedef OM_SEND_INST * POM_SEND_INST;
  2053. //
  2054. //
  2055. // RECEIVE LIST
  2056. //
  2057. // ObMan maintains a list of structures holding information about data
  2058. // transfers (receives) which have begun but not finished. This is known
  2059. // as the receive list.
  2060. //
  2061. // When ObMan receives a header packet for an Add, Update or Replace
  2062. // operation, it adds an entry to the receive list. Subsequent data
  2063. // packets are then correlated with this entry, until the entire object has
  2064. // been received, at which point the Add/Update/Replace operation is
  2065. // carried out.
  2066. //
  2067. // The receive list is a linked list of entries with the following format:
  2068. //
  2069. //
  2070. typedef struct tagOM_RECEIVE_CB
  2071. {
  2072. STRUCTURE_STAMP
  2073. BASEDLIST chain;
  2074. POM_DOMAIN pDomain; // Domain record pointer
  2075. POMNET_OPERATION_PKT pHeader; // ObMan pointer to message header
  2076. void * pData; // ObMan pointer to the data that
  2077. // is being transferred
  2078. UINT bytesRecd; // total bytes received so far for
  2079. // this transfer
  2080. LPBYTE pCurrentPosition; // points to where next chunk
  2081. // of data should be copied
  2082. NET_PRIORITY priority; // priority of data transfer
  2083. NET_CHANNEL_ID channel;
  2084. }
  2085. OM_RECEIVE_CB;
  2086. typedef OM_RECEIVE_CB * POM_RECEIVE_CB;
  2087. //
  2088. // HANDLE <--> PTR CONVERSION ROUTINES
  2089. // Object, usage, domain, workset group, worksets
  2090. //
  2091. POM_WSGROUP __inline GetOMCWsgroup(POM_DOMAIN pDomain)
  2092. {
  2093. POM_WSGROUP pWSGroup;
  2094. pWSGroup = (POM_WSGROUP)COM_BasedListFirst(&(pDomain->wsGroups),
  2095. FIELD_OFFSET(OM_WSGROUP, chain));
  2096. ValidateWSGroup(pWSGroup);
  2097. return(pWSGroup);
  2098. }
  2099. POM_WORKSET __inline GetOMCWorkset(POM_DOMAIN pDomain, OM_WORKSET_ID worksetID)
  2100. {
  2101. POM_WSGROUP pWSGroup;
  2102. pWSGroup = GetOMCWsgroup(pDomain);
  2103. return(pWSGroup->apWorksets[worksetID]);
  2104. }
  2105. OM_CORRELATOR __inline NextCorrelator(POM_PRIMARY pomPrimary)
  2106. {
  2107. return(pomPrimary->correlator++);
  2108. }
  2109. void __inline UpdateWorksetGeneration(POM_WORKSET pWorkset, POMNET_OPERATION_PKT pPacket)
  2110. {
  2111. pWorkset->genNumber = max(pWorkset->genNumber, pPacket->seqStamp.genNumber) + 1;
  2112. }
  2113. //
  2114. //
  2115. // CHECK_WORKSET_NOT_EXHAUSTED(pWorkset)
  2116. //
  2117. // This macro checks that the specified workset is not exhausted. If it
  2118. // is, it calls DC_QUIT.
  2119. //
  2120. //
  2121. #define CHECK_WORKSET_NOT_EXHAUSTED(pWorkset) \
  2122. \
  2123. if (pWorkset->genNumber == OM_MAX_GENERATION_NUMBER) \
  2124. { \
  2125. WARNING_OUT(("Workset %hx exhausted", pWorkset->worksetID)); \
  2126. rc = OM_RC_WORKSET_EXHAUSTED; \
  2127. DC_QUIT; \
  2128. }
  2129. //
  2130. //
  2131. // CHECK_WORKSET_NOT_LOCKED(pWorkset)
  2132. //
  2133. // This macro checks that the specified workset is not locked. If it is,
  2134. // it calls DC_QUIT with an error.
  2135. //
  2136. //
  2137. #define CHECK_WORKSET_NOT_LOCKED(pWorkset) \
  2138. \
  2139. if (pWorkset->lockState == LOCK_GRANTED) \
  2140. { \
  2141. rc = OM_RC_WORKSET_LOCKED; \
  2142. WARNING_OUT(("Workset %hx locked - can't proceed", worksetID)); \
  2143. DC_QUIT; \
  2144. }
  2145. //
  2146. //
  2147. // OBJECT ID MANIPULATION
  2148. //
  2149. // These macros manipulate object IDs.
  2150. //
  2151. //
  2152. //
  2153. //
  2154. // OBJECT_ID_IS_NULL(objectID)
  2155. //
  2156. // This macro evaluates to TRUE if the supplied object ID is a null ID,
  2157. // and FALSE otherwise.
  2158. //
  2159. //
  2160. #define OBJECT_ID_IS_NULL(objectID) \
  2161. \
  2162. (((objectID).creator == 0) && ((objectID).sequence == 0))
  2163. //
  2164. //
  2165. // GET_NEXT_OBJECT_ID(objectID, pDomain, pWorkset)
  2166. //
  2167. // This macro allocates a new object ID for the workset specified by
  2168. // <pWorkset>. It copies the ID into the structure specified by
  2169. // <objectID>.
  2170. //
  2171. // The first field in the ID is ObMan's MCS user ID in the Domain to which
  2172. // the workset group <pWSGroup> belongs.
  2173. //
  2174. //
  2175. #define GET_NEXT_OBJECT_ID(objectID, pDomain, pomPrimary) \
  2176. (objectID).creator = pDomain->userID; \
  2177. (objectID).sequence = pomPrimary->objectIDsequence++; \
  2178. (objectID).pad1 = 0
  2179. //
  2180. //
  2181. // OBJECT_IDS_ARE_EQUAL(objectID1, objectID2)
  2182. //
  2183. // Evaluates to TRUE if the two object IDs are equal and FALSE otherwise.
  2184. //
  2185. //
  2186. #define OBJECT_IDS_ARE_EQUAL(objectID1, objectID2) \
  2187. \
  2188. (memcmp(&(objectID1), &(objectID2), sizeof(OM_OBJECT_ID)) == 0)
  2189. //
  2190. //
  2191. // SEQUENCE STAMP MANIPULATION
  2192. //
  2193. // These macro manipulate sequence stamps.
  2194. //
  2195. //
  2196. //
  2197. //
  2198. // GET_CURR_SEQ_STAMP(stamp, pWSGroup, pWorkset)
  2199. //
  2200. // This macro copies the current sequence stamp of the workset specified by
  2201. // <pWorkset> into the sequence stamp structure identified by <stamp>.
  2202. //
  2203. //
  2204. #define GET_CURR_SEQ_STAMP(stamp, pDomain, pWorkset) \
  2205. \
  2206. (stamp).userID = pDomain->userID; \
  2207. (stamp).genNumber = pWorkset->genNumber
  2208. //
  2209. // GenerateMessage(...)
  2210. //
  2211. // Allocates and initialises an OMNET_OPERATION_PKT of the specified type.
  2212. // Note that the <size> field is set to zero even if <messageType> is an
  2213. // add, update or replace. The QueueMessage function will set the size to
  2214. // the correct value when the message is queued.
  2215. //
  2216. UINT GenerateOpMessage( POM_WSGROUP pWSGroup,
  2217. OM_WORKSET_ID worksetID,
  2218. POM_OBJECT_ID pObjectID,
  2219. POM_OBJECTDATA pData,
  2220. OMNET_MESSAGE_TYPE messageType,
  2221. POMNET_OPERATION_PKT * ppPacket);
  2222. //
  2223. //
  2224. // QueueMessage(...)
  2225. //
  2226. // This function creates a send instruction for the specified message and
  2227. // places the instruction on the specified send queue for the specified
  2228. // Domain. It them sends an event to ObMan prompting it to examine the
  2229. // queue.
  2230. //
  2231. //
  2232. UINT QueueMessage(PUT_CLIENT putTask,
  2233. POM_DOMAIN pDomain,
  2234. NET_CHANNEL_ID channelID,
  2235. NET_PRIORITY priority,
  2236. POM_WSGROUP pWSGroup,
  2237. POM_WORKSET pWorkset,
  2238. POM_OBJECT pObjectRec,
  2239. POMNET_PKT_HEADER pPacket,
  2240. POM_OBJECTDATA pData,
  2241. BOOL compressOrNot);
  2242. //
  2243. // GetMessageSize(...)
  2244. //
  2245. UINT GetMessageSize(OMNET_MESSAGE_TYPE messageType);
  2246. //
  2247. // PreProcessMessage(...)
  2248. //
  2249. UINT PreProcessMessage(POM_DOMAIN pDomain,
  2250. OM_WSGROUP_ID wsGroupID,
  2251. OM_WORKSET_ID worksetID,
  2252. POM_OBJECT_ID pObjectID,
  2253. OMNET_MESSAGE_TYPE messageType,
  2254. POM_WSGROUP * ppWSGroup,
  2255. POM_WORKSET * ppWorkset,
  2256. POM_OBJECT * ppObjectRec);
  2257. //
  2258. //
  2259. // PurgeNonPersistent(...)
  2260. //
  2261. // Purges any objects added by <userID> from non-persistent worksets in the
  2262. // workset group identified by <wsGroupID> in the specified domain.
  2263. //
  2264. //
  2265. void PurgeNonPersistent(POM_PRIMARY pomPrimary,
  2266. POM_DOMAIN pDomain,
  2267. OM_WSGROUP_ID wsGroupID,
  2268. NET_UID userID);
  2269. //
  2270. // ProcessWorksetNew(...)
  2271. //
  2272. UINT ProcessWorksetNew(PUT_CLIENT putTask,
  2273. POMNET_OPERATION_PKT pPacket,
  2274. POM_WSGROUP pWSGroup);
  2275. //
  2276. // ProcessWorksetClear(...)
  2277. //
  2278. UINT ProcessWorksetClear(PUT_CLIENT putTask, POM_PRIMARY pomPrimary,
  2279. POMNET_OPERATION_PKT pPacket,
  2280. POM_WSGROUP pWSGroup,
  2281. POM_WORKSET pWorkset);
  2282. //
  2283. // ProcessObjectAdd(...)
  2284. //
  2285. UINT ProcessObjectAdd(PUT_CLIENT putTask,
  2286. POMNET_OPERATION_PKT pPacket,
  2287. POM_WSGROUP pWSGroup,
  2288. POM_WORKSET pWorkset,
  2289. POM_OBJECTDATA pData,
  2290. POM_OBJECT * ppObj);
  2291. //
  2292. // ProcessObjectMove(...)
  2293. //
  2294. void ProcessObjectMove(PUT_CLIENT putTask,
  2295. POMNET_OPERATION_PKT pPacket,
  2296. POM_WORKSET pWorkset,
  2297. POM_OBJECT pObjectRec);
  2298. //
  2299. // ProcessObjectDRU(...)
  2300. //
  2301. UINT ProcessObjectDRU(PUT_CLIENT putTask,
  2302. POMNET_OPERATION_PKT pPacket,
  2303. POM_WSGROUP pWSGroup,
  2304. POM_WORKSET pWorkset,
  2305. POM_OBJECT pObj,
  2306. POM_OBJECTDATA pData);
  2307. //
  2308. // ObjectAdd(...)
  2309. //
  2310. UINT ObjectAdd(PUT_CLIENT putTask, POM_PRIMARY pomPrimary,
  2311. POM_WSGROUP pWSGroup,
  2312. POM_WORKSET pWorkset,
  2313. POM_OBJECTDATA pData,
  2314. UINT updateSize,
  2315. OM_POSITION position,
  2316. OM_OBJECT_ID * pObjectID,
  2317. POM_OBJECT * ppObj);
  2318. //
  2319. // WSGroupEventPost(...)
  2320. //
  2321. // This function posts the specified event to all local Clients registered
  2322. // with the workset group. The <param2> parameter is the second parameter
  2323. // on the event to be posted.
  2324. //
  2325. //
  2326. UINT WSGroupEventPost(PUT_CLIENT putTaskFrom,
  2327. POM_WSGROUP pWSGroup,
  2328. BYTE target,
  2329. UINT event,
  2330. OM_WORKSET_ID worksetID,
  2331. UINT_PTR param2);
  2332. //
  2333. //
  2334. // This function is called by
  2335. //
  2336. // - OM_WorksetOpen, when a Client creates a new workset
  2337. //
  2338. // - ProcessLockRequest, when a lock request arrives for a workset we
  2339. // don't yet know about
  2340. //
  2341. // - xx, when an OMNET_WORKSET_NEW message arrives.
  2342. //
  2343. // It creates the local data structures for the workset and posts an event
  2344. // to all local Clients registered with the workset group.
  2345. //
  2346. //
  2347. //
  2348. //
  2349. // WorksetCreate(...)
  2350. //
  2351. // This function creates a new workset in the specified workset group.
  2352. //
  2353. // It calls GenerateMessage, ProcessWorksetNew and QueueMessage.
  2354. //
  2355. //
  2356. UINT WorksetCreate(PUT_CLIENT putTask,
  2357. POM_WSGROUP pWSGroup,
  2358. OM_WORKSET_ID worksetID,
  2359. BOOL fTemp,
  2360. NET_PRIORITY priority);
  2361. //
  2362. //
  2363. // WorksetEventPost(...)
  2364. //
  2365. // This function posts the specified event to all local Clients which have
  2366. // the workset open (at most 1 Client in R1.1).
  2367. //
  2368. // The <putTask> parameter is the putTask of the invoking task (and NOT
  2369. // the handle of the task to post the event to).
  2370. //
  2371. // The number of Clients the event was successfully posted to is returned
  2372. // in *pNumPosts, if pNumPosts is not NULL. A caller which wishes to
  2373. // ignore the number of events posted can pass in NULL as the pNumPosts
  2374. // parameter.
  2375. //
  2376. //
  2377. UINT WorksetEventPost(PUT_CLIENT putTask,
  2378. POM_WORKSET pWorkset,
  2379. BYTE target,
  2380. UINT event,
  2381. POM_OBJECT pObj);
  2382. //
  2383. // WorksetDoClear(...)
  2384. //
  2385. void WorksetDoClear(PUT_CLIENT putTask,
  2386. POM_WSGROUP pWSGroup,
  2387. POM_WORKSET pWorkset,
  2388. POM_PENDING_OP pPendingOp);
  2389. //
  2390. //
  2391. // ProcessLockRequest(...)
  2392. //
  2393. // This function is called when ObMan receives an OMNET_LOCK_REQ message
  2394. // from another node.
  2395. //
  2396. // If we
  2397. //
  2398. // - have the workset locked already, or
  2399. //
  2400. // - are trying to lock the workset and our MCS user ID is greater than the
  2401. // node which sent us the request,
  2402. //
  2403. // we deny the lock (i.e. send back a negative OMNET_LOCK_REPLY).
  2404. //
  2405. // In all other cases, we grant the lock (i.e. send back an affirmative
  2406. // OMNET_LOCK_REPLY).
  2407. //
  2408. // If we grant the lock to the remote node when we were trying to get it
  2409. // for ourselves, our attempt to lock the workset has failed so we call
  2410. // WorksetLockResult with a failure code.
  2411. //
  2412. //
  2413. void ProcessLockRequest(POM_PRIMARY pomPrimary,
  2414. POM_DOMAIN pDomain,
  2415. POMNET_LOCK_PKT pLockReqPkt);
  2416. //
  2417. //
  2418. // QueueLockReply(...)
  2419. //
  2420. // This function is called when we have decided to grant or deny a lock
  2421. // request received from another node. It queues the appropriate response
  2422. // on ObMan's send queue.
  2423. //
  2424. //
  2425. void QueueLockReply(POM_PRIMARY pomPrimary,
  2426. POM_DOMAIN pDomain,
  2427. OMNET_MESSAGE_TYPE result,
  2428. NET_CHANNEL_ID destination,
  2429. POMNET_LOCK_PKT pLockReqPkt);
  2430. //
  2431. //
  2432. // QueueLockNotify(...)
  2433. //
  2434. // Queues a LOCK_NOTIFY command on the broadcast channel for the workset
  2435. // group, indicating that we have granted the lock to the <locker>.
  2436. //
  2437. //
  2438. void QueueLockNotify(POM_PRIMARY pomPrimary,
  2439. POM_DOMAIN pDomain,
  2440. POM_WSGROUP pWSGroup,
  2441. POM_WORKSET pWorkset,
  2442. NET_UID locker);
  2443. //
  2444. //
  2445. // ProcessLockReply(...)
  2446. //
  2447. // This function is called when ObMan receives an OMNET_LOCK_GRANT or
  2448. // OMNET_LOCK_DENY message from another node, in response to an
  2449. // OMNET_LOCK_REQ message we sent out earlier.
  2450. //
  2451. // The function removes this node from the list of expected respondents for
  2452. // this lock (if it is in the list).
  2453. //
  2454. // If the list is now empty, the lock has succeeded so WorksetLockResult is
  2455. // called.
  2456. //
  2457. // Otherwise, nothing else happens for the moment.
  2458. //
  2459. //
  2460. void ProcessLockReply(POM_PRIMARY pomPrimary,
  2461. POM_DOMAIN pDomain,
  2462. NET_UID sender,
  2463. OM_CORRELATOR correlator,
  2464. OMNET_MESSAGE_TYPE replyType);
  2465. //
  2466. // PurgeLockRequests(...)
  2467. //
  2468. void PurgeLockRequests(POM_DOMAIN pDomain,
  2469. POM_WSGROUP pWSGroup);
  2470. //
  2471. //
  2472. // ProcessLockTimeout(...)
  2473. //
  2474. // This function is called when ObMan receives a lock timeout event. It
  2475. // checks to see if any of the nodes from whom we are still expecting lock
  2476. // replies have in fact gone away; if they have, it removes them from the
  2477. // list of expected respondents.
  2478. //
  2479. // If this list is now empty, the lock has succeeded and WorksetLockResult
  2480. // is called.
  2481. //
  2482. // If the list is not empty, then another delayed lock timeout event is
  2483. // posted to ObMan, unless we have already had the maximum number of
  2484. // timeouts for this lock, in which case the lock has failed and
  2485. // WorksetLockResult is called.
  2486. //
  2487. //
  2488. void ProcessLockTimeout(POM_PRIMARY pomPrimary,
  2489. UINT retriesToGo,
  2490. UINT callID);
  2491. //
  2492. //
  2493. // WorksetLockReq(...)
  2494. //
  2495. // This function is called
  2496. //
  2497. // - by OM_WorksetLockReq, when a Client wants to lock a workset
  2498. //
  2499. // - by LockObManControl, when ObMan wants to lock workset #0 in
  2500. // ObManControl.
  2501. //
  2502. // The function decides whether the lock can be granted or refused
  2503. // synchronously, and if so calls WorksetLockResult. If not, it posts an
  2504. // OMINT_EVENT_LOCK_REQ event to the ObMan task, which results in the
  2505. // ProcessLocalLockRequest function being called later.
  2506. //
  2507. // The <hWSGroup> parameter is the workset group handle which will be
  2508. // included in the eventual OM_WORKSET_LOCK_CON event. Its value is not
  2509. // used in the function; when this function is called in the ObMan task
  2510. // this value is set to zero (since the ObMan task doesn't use workset
  2511. // group handles).
  2512. //
  2513. // On successful completion, the <pCorrelator> parameter points to the
  2514. // correlator value which will be included in the eventual
  2515. // OM_WORKSET_LOCK_CON event.
  2516. //
  2517. //
  2518. void WorksetLockReq(PUT_CLIENT putTask, POM_PRIMARY pomPrimary,
  2519. POM_WSGROUP pWSGroup,
  2520. POM_WORKSET pWorkset,
  2521. OM_WSGROUP_HANDLE hWSGroup,
  2522. OM_CORRELATOR * pCorrelator);
  2523. //
  2524. //
  2525. // WorksetLockResult(...)
  2526. //
  2527. // This function is called when we have finished processing a request to
  2528. // obtain a workset lock. The function sets the workset state accordingly,
  2529. // posts an appropriate event to the task which requested the lock, and
  2530. // frees the lock request control block.
  2531. //
  2532. //
  2533. void WorksetLockResult(PUT_CLIENT putTask,
  2534. POM_LOCK_REQ * ppLockReq,
  2535. UINT result);
  2536. //
  2537. //
  2538. // BuildNodeList(...)
  2539. //
  2540. // This function builds a list of the remote nodes which are registered
  2541. // with the workset group referenced in the lock request CB passed in.
  2542. //
  2543. //
  2544. UINT BuildNodeList(POM_DOMAIN pDomain, POM_LOCK_REQ pLockReq);
  2545. //
  2546. //
  2547. // HandleMultLockReq(...)
  2548. //
  2549. // This function searches the global list of pending lock requests (stored
  2550. // in the root data structure) for any lock requests matching the Domain,
  2551. // workset group and workset specified.
  2552. //
  2553. //
  2554. void HandleMultLockReq(POM_PRIMARY pomPrimary,
  2555. POM_DOMAIN pDomain,
  2556. POM_WSGROUP pWSGroup,
  2557. POM_WORKSET pWorkset,
  2558. UINT result);
  2559. //
  2560. //
  2561. // FindLockReq(...)
  2562. //
  2563. // This function searches the global list of pending lock requests (stored
  2564. // in the root data structure) for a lock request that matches the Domain,
  2565. // workset group and workset specified.
  2566. //
  2567. // If found, a pointer to the lock request is returned in <ppLockReq>.
  2568. //
  2569. // It can search for a primary lock request if needed
  2570. //
  2571. //
  2572. void FindLockReq(POM_DOMAIN pDomain,
  2573. POM_WSGROUP pWSGroup,
  2574. POM_WORKSET pWorkset,
  2575. POM_LOCK_REQ * ppLockreq,
  2576. BYTE lockType);
  2577. //
  2578. // ReleaseAllNetLocks(...)
  2579. //
  2580. void ReleaseAllNetLocks(POM_PRIMARY pomPrimary,
  2581. POM_DOMAIN pDomain,
  2582. OM_WSGROUP_ID wsGroupID,
  2583. NET_UID userID);
  2584. //
  2585. //
  2586. // ProcessUnlock(...)
  2587. //
  2588. // This function is called when an OMNET_UNLOCK message is received from
  2589. // the network. The function is a wrapper which just derives a workset
  2590. // pointer and calls ProcessUnlock (above).
  2591. //
  2592. //
  2593. void ProcessUnlock(POM_PRIMARY pomPrimary,
  2594. POM_WORKSET pWorkset,
  2595. NET_UID sender);
  2596. //
  2597. // WorksetUnlock(...)
  2598. //
  2599. void WorksetUnlock(PUT_CLIENT putTask, POM_WSGROUP pWSGroup,
  2600. POM_WORKSET pWorkset);
  2601. //
  2602. // WorksetUnlockLocal(...)
  2603. //
  2604. void WorksetUnlockLocal(PUT_CLIENT putTask, POM_WORKSET pWorkset);
  2605. //
  2606. //
  2607. // ObjectDoDelete(...)
  2608. //
  2609. // This function deletes an object in a workset. It is called by
  2610. //
  2611. // - OM_ObjectDeleteConfirm, when a Client confirms the deletion of an
  2612. // object.
  2613. //
  2614. // - WorksetDoClear, to delete each individual object
  2615. //
  2616. // - ProcessObjectDelete when ObMan receives a Delete message from the
  2617. // network for an object in a workset which no local Clients have open.
  2618. //
  2619. //
  2620. void ObjectDoDelete(PUT_CLIENT putTask,
  2621. POM_WSGROUP pWSGroup,
  2622. POM_WORKSET pWorkset,
  2623. POM_OBJECT pObj,
  2624. POM_PENDING_OP pPendingOp);
  2625. //
  2626. //
  2627. // ObjectDRU(...)
  2628. //
  2629. // This function generate, processes and queues a message of type DELETE,
  2630. // REPLACE or UPDATE (as specified by <type>).
  2631. //
  2632. //
  2633. UINT ObjectDRU(PUT_CLIENT putTask,
  2634. POM_WSGROUP pWSGroup,
  2635. POM_WORKSET pWorkset,
  2636. POM_OBJECT pObj,
  2637. POM_OBJECTDATA pData,
  2638. OMNET_MESSAGE_TYPE type);
  2639. //
  2640. //
  2641. // ObjectRead(...)
  2642. //
  2643. // This function converts an object handle to a pointer to the object data.
  2644. // An invalid handle causes an assertion failure.
  2645. //
  2646. //
  2647. void ObjectRead(POM_CLIENT pomClient,
  2648. POM_OBJECT pObj,
  2649. POM_OBJECTDATA * ppData);
  2650. //
  2651. // ObjectInsert(...)
  2652. //
  2653. void ObjectInsert(POM_WORKSET pWorkset,
  2654. POM_OBJECT pObj,
  2655. OM_POSITION position);
  2656. //
  2657. // ObjectDoMove(...)
  2658. //
  2659. void ObjectDoMove(POM_OBJECT pObjToMove,
  2660. POM_OBJECT pOtherObjectRec,
  2661. OM_POSITION position);
  2662. //
  2663. // ObjectDoUpdate(...)
  2664. //
  2665. void ObjectDoUpdate(PUT_CLIENT putTask,
  2666. POM_WSGROUP pWSGroup,
  2667. POM_WORKSET pWorkset,
  2668. POM_OBJECT pObj,
  2669. POM_PENDING_OP pPendingOp);
  2670. //
  2671. // ObjectDoReplace(...)
  2672. //
  2673. void ObjectDoReplace(PUT_CLIENT putTask,
  2674. POM_WSGROUP pWSGroup,
  2675. POM_WORKSET pWorkset,
  2676. POM_OBJECT pObj,
  2677. POM_PENDING_OP pPendingOp);
  2678. //
  2679. // ObjectIDToPtr(...)
  2680. //
  2681. UINT ObjectIDToPtr(POM_WORKSET pWorkset,
  2682. OM_OBJECT_ID objectID,
  2683. POM_OBJECT * ppObj);
  2684. //
  2685. // FindPendingOp(...)
  2686. //
  2687. void FindPendingOp(POM_WORKSET pWorkset,
  2688. POM_OBJECT pObj,
  2689. OM_OPERATION_TYPE type,
  2690. POM_PENDING_OP * ppPendingOp);
  2691. //
  2692. // WSGRecordFind(...)
  2693. //
  2694. void WSGRecordFind(POM_DOMAIN pDomain, OMWSG wsg, OMFP fpHandler,
  2695. POM_WSGROUP * ppWSGroup);
  2696. //
  2697. // DeterminePriority(...)
  2698. //
  2699. void DeterminePriority(NET_PRIORITY * pPriority,
  2700. POM_OBJECTDATA pData);
  2701. //
  2702. // RemoveClientFromWSGList(...)
  2703. //
  2704. // The second parameter is the putTask of the Client to be deregistered.
  2705. // It is NOT (well, not necessarily) the putTask of the calling task, and
  2706. // for this reason (to avoid it being used as such) is passed as a 32-bit
  2707. // integer.
  2708. //
  2709. void RemoveClientFromWSGList(
  2710. PUT_CLIENT putUs,
  2711. PUT_CLIENT putTask,
  2712. POM_WSGROUP pWSGroup);
  2713. //
  2714. // AddClientToWSGList(...)
  2715. //
  2716. UINT AddClientToWSGList(PUT_CLIENT putTask,
  2717. POM_WSGROUP pWSGroup,
  2718. OM_WSGROUP_HANDLE hWSGroup,
  2719. UINT mode);
  2720. //
  2721. // AddClientToWsetList(...)
  2722. //
  2723. UINT AddClientToWsetList(PUT_CLIENT putTask,
  2724. POM_WORKSET pWorkset,
  2725. OM_WSGROUP_HANDLE hWSGroup,
  2726. UINT mode,
  2727. POM_CLIENT_LIST * pClientListEntry);
  2728. //
  2729. // PostWorksetNewEvents(...)
  2730. //
  2731. UINT PostWorksetNewEvents(PUT_CLIENT putFrom,
  2732. PUT_CLIENT putTask,
  2733. POM_WSGROUP pWSGroup,
  2734. OM_WSGROUP_HANDLE hWSGroup);
  2735. //
  2736. //
  2737. // QueueUnlock(...)
  2738. //
  2739. // This function queues a workset unlock packet for sending to the
  2740. // specified destination.
  2741. //
  2742. //
  2743. UINT QueueUnlock(PUT_CLIENT putTask,
  2744. POM_DOMAIN pDomain,
  2745. OM_WSGROUP_ID wsGroupID,
  2746. OM_WORKSET_ID worksetID,
  2747. NET_UID destination,
  2748. NET_PRIORITY priority);
  2749. //
  2750. // PurgeReceiveCBs(...)
  2751. //
  2752. void PurgeReceiveCBs(POM_DOMAIN pDomain,
  2753. NET_CHANNEL_ID channel);
  2754. //
  2755. // FreeSendInst()
  2756. //
  2757. void FreeSendInst(POM_SEND_INST pSendInst);
  2758. //
  2759. // SetPersonData(...)
  2760. //
  2761. UINT SetPersonData(POM_PRIMARY pomPrimary,
  2762. POM_DOMAIN pDomain,
  2763. POM_WSGROUP pWSGroup);
  2764. //
  2765. //
  2766. // FindInfoObject(...)
  2767. //
  2768. // This function searches workset #0 in the ObManControl workset group in
  2769. // the specified Domain for a matching info object.
  2770. //
  2771. // The match is performed as follows:
  2772. //
  2773. // - if functionProfile and wsGroupName are not NULL, the first object
  2774. // matching both is returned
  2775. //
  2776. // - if functionProfile is not NULL but wsGroupName is, the first object
  2777. // matching functionProfile is returned
  2778. //
  2779. // - if functionProfile is NULL, the first object matching wsGroupID is
  2780. // returned.
  2781. //
  2782. //
  2783. void FindInfoObject(POM_DOMAIN pDomain,
  2784. OM_WSGROUP_ID wsGroupID,
  2785. OMWSG wsg,
  2786. OMFP fpHandler,
  2787. POM_OBJECT * ppInfoObjectRec);
  2788. //
  2789. //
  2790. // FindPersonObject(...)
  2791. //
  2792. // This function searches the specified workset in ObManControl looking for
  2793. // a registration object which has
  2794. //
  2795. // - the same user ID as <userID>, if <searchType> == FIND_THIS
  2796. //
  2797. // - a different user ID from <userID>, if <searchType> == FIND_OTHERS.
  2798. //
  2799. //
  2800. void FindPersonObject(POM_WORKSET pOMCWorkset,
  2801. NET_UID userID,
  2802. UINT searchType,
  2803. POM_OBJECT * ppRegObjectRec);
  2804. #define FIND_THIS 1
  2805. #define FIND_OTHERS 2
  2806. //
  2807. // ProcessOMCWorksetNew(...)
  2808. //
  2809. void ProcessOMCWorksetNew(POM_PRIMARY pomPrimary, OM_WSGROUP_HANDLE hWSGroup,
  2810. OM_WORKSET_ID worksetID);
  2811. //
  2812. // ProcessOMCObjectEvents(...)
  2813. //
  2814. void ProcessOMCObjectEvents(POM_PRIMARY pomPrimary,
  2815. UINT event,
  2816. OM_WSGROUP_HANDLE hWSGroup,
  2817. OM_WORKSET_ID worksetID,
  2818. POM_OBJECT pObj);
  2819. //
  2820. // GeneratePersonEvents(...)
  2821. //
  2822. void GeneratePersonEvents(POM_PRIMARY pomPrimary,
  2823. UINT event,
  2824. POM_WSGROUP pWSGroup,
  2825. POM_OBJECT pObj);
  2826. //
  2827. // PostAddEvents(...)
  2828. //
  2829. UINT PostAddEvents(PUT_CLIENT putTaskFrom,
  2830. POM_WORKSET pWorkset,
  2831. OM_WSGROUP_HANDLE hWSGroup,
  2832. PUT_CLIENT putTaskTo);
  2833. //
  2834. // RemovePersonObject(...)
  2835. //
  2836. void RemovePersonObject(POM_PRIMARY pomPrimary,
  2837. POM_DOMAIN pDomain,
  2838. OM_WSGROUP_ID wsGroupID,
  2839. NET_UID detachedUserID);
  2840. //
  2841. // RemoveInfoObject(...)
  2842. //
  2843. void RemoveInfoObject(POM_PRIMARY pomPrimary, POM_DOMAIN pDomain,
  2844. OM_WSGROUP_ID wsGroupID);
  2845. //
  2846. //
  2847. // DEBUG ONLY FUNCTIONS
  2848. //
  2849. // These functions are debug code only - for normal compilations, the
  2850. // declarations are #defined to nothing and the definitions are
  2851. // preprocessed out altogether.
  2852. //
  2853. //
  2854. #ifndef _DEBUG
  2855. #define CheckObjectCount(x, y)
  2856. #define CheckObjectOrder(x)
  2857. #define DumpWorkset(x, y)
  2858. #else // _DEBUG
  2859. //
  2860. //
  2861. // CheckConstants(...)
  2862. //
  2863. // The ObMan code relies on certain assumptions about the sizes and formats
  2864. // of various data structures, and the values of certain constants.
  2865. //
  2866. //
  2867. // The OMNET_OPERATION_PKT type has two one-byte fields, <position> and
  2868. // <flags>, which are used to hold
  2869. //
  2870. // - a NET_PRIORITY value which indicates the priority for the
  2871. // workset for WORKSET_NEW/WORKSET_CATCHUP messages, and
  2872. //
  2873. // - a UINT (the number of bytes being acknowledged) in the case
  2874. // of a DATA_ACK message.
  2875. //
  2876. // GenerateOpMessage and AckData cast the <position> field to a two-byte
  2877. // quantity for this purpose. Therefore, it is necessary that these two
  2878. // fields exist, that they are adjacent and that the <position> one
  2879. // comes first.
  2880. //
  2881. // In addition, since the priority information is a NET_PRIORITY, we
  2882. // must ensure that a NET_PRIORITY is indeed two bytes long.
  2883. //
  2884. //
  2885. // ASSERT((sizeof(NET_PRIORITY) == (2 * sizeof(BYTE))));
  2886. //
  2887. // ASSERT((offsetof(OMNET_OPERATION_PKT, position) + 1 ==
  2888. // offsetof(OMNET_OPERATION_PKT, flags)));
  2889. //
  2890. //
  2891. // In many places, for-loops use workset IDs as the loop variable and
  2892. // OM_MAX_WORKSETS_PER_WSGROUP as the end condition. To avoid infinite
  2893. // loops, this constant must be less than 256:
  2894. //
  2895. // ASSERT((OM_MAX_WORKSETS_PER_WSGROUP < 256));
  2896. //
  2897. // The OMC WSG has one workset for each WSG in the Domain. Since the
  2898. // number of worksets per WSG is limited, the # of WSGs per Domain is
  2899. // limited in the same way:
  2900. //
  2901. // ASSERT(OM_MAX_WSGROUPS_PER_DOMAIN <= OM_MAX_WORKSETS_PER_WSGROUP);
  2902. //
  2903. //
  2904. //
  2905. // CheckObjectCount(...)
  2906. //
  2907. // This function counts the number of non-deleted objects in the specified
  2908. // workset and compares this against the <numObjects> field of the workset
  2909. // record. A mismatch causes an assertion failure.
  2910. //
  2911. //
  2912. void CheckObjectCount(POM_WSGROUP pWSGroup,
  2913. POM_WORKSET pWorkset);
  2914. //
  2915. // CheckObjectOrder(...)
  2916. //
  2917. void CheckObjectOrder(POM_WORKSET pWorkset);
  2918. #endif // _DEBUG
  2919. //
  2920. //
  2921. // WORKSET OPEN/CLOSE BITFIELD MANIPULATION MACROS
  2922. //
  2923. // ObMan maintains one usage record for each workset group a Client is
  2924. // registered with. One of the fields of the usage record is an 32-byte
  2925. // bitfield which is interpreted as an array of 256 booleans, indicating
  2926. // whether a Client has the corresponding workset open.
  2927. //
  2928. // These macros use the EXTRACT_BIT, SET_BIT and CLEAR_BIT macros to set and clear the bit
  2929. // for <worksetID> in the <worksetOpenFlags> bitfield of the usage record.
  2930. //
  2931. //
  2932. BOOL __inline WORKSET_IS_OPEN(POM_USAGE_REC pUsageRec, OM_WORKSET_ID worksetID)
  2933. {
  2934. return((pUsageRec->worksetOpenFlags[worksetID / 8] & (0x80 >> (worksetID % 8))) != 0);
  2935. }
  2936. void __inline WORKSET_SET_OPEN(POM_USAGE_REC pUsageRec, OM_WORKSET_ID worksetID)
  2937. {
  2938. pUsageRec->worksetOpenFlags[worksetID / 8] |= (0x80 >> (worksetID % 8));
  2939. }
  2940. void __inline WORKSET_SET_CLOSED(POM_USAGE_REC pUsageRec, OM_WORKSET_ID worksetID)
  2941. {
  2942. pUsageRec->worksetOpenFlags[worksetID / 8] &= ~(0x80 >> (worksetID % 8));
  2943. }
  2944. //
  2945. //
  2946. // ReleaseAllLocks(...)
  2947. //
  2948. // This function releases all the locks held by a particular Client for a
  2949. // particular workset. In R1.1, this is at most one lock (the workset
  2950. // lock) but if/when object locking is supported, this function will also
  2951. // release all object locks held.
  2952. //
  2953. // This function is closed when a Client is closing a workset.
  2954. //
  2955. //
  2956. void ReleaseAllLocks(POM_CLIENT pomClient,
  2957. POM_USAGE_REC pUsageRec,
  2958. POM_WORKSET pWorkset);
  2959. //
  2960. //
  2961. // ReleaseAllObjects(...)
  2962. //
  2963. // This function releases all the objects held by a particular Client in a
  2964. // particular workset.
  2965. //
  2966. // This function is called when a Client closes a workset.
  2967. //
  2968. void ReleaseAllObjects(POM_USAGE_REC pUsageRec, POM_WORKSET pWorkset);
  2969. //
  2970. //
  2971. // ConfirmAll(...)
  2972. //
  2973. // This function confirms any pending operations for the workset specified.
  2974. //
  2975. // The function is called when a Client closes a workset.
  2976. //
  2977. // Since this function may call WorksetDoClear, the caller must hold the
  2978. // workset group mutex.
  2979. //
  2980. //
  2981. void ConfirmAll(POM_CLIENT pomClient,
  2982. POM_USAGE_REC pUsageRec,
  2983. POM_WORKSET pWorkset);
  2984. //
  2985. //
  2986. // DiscardAllObjects(...)
  2987. //
  2988. // This function discards any objects allocated for the specified Client
  2989. // for the specified workset but so far unused.
  2990. //
  2991. // The function is called when a Client closes a workset.
  2992. //
  2993. //
  2994. void DiscardAllObjects(POM_USAGE_REC pUsageRec,
  2995. POM_WORKSET pWorkset);
  2996. //
  2997. //
  2998. // RemoveFromUnusedList
  2999. //
  3000. // This function removes an object (specified by a pointer to the object)
  3001. // from the Client's list of unused objects. It is called by
  3002. //
  3003. // - OM_ObjectAdd, OM_ObjectUpdate and OM_ObjectReplace when a
  3004. // Client inserts an object into a workset, or
  3005. //
  3006. // - OM_ObjectDiscard, when a Client discards an unused object.
  3007. //
  3008. //
  3009. void RemoveFromUnusedList(POM_USAGE_REC pUsageRec, POM_OBJECTDATA pData);
  3010. //
  3011. //
  3012. // OM_ObjectAdd(...)
  3013. //
  3014. // This function adds an object to a worksets, in the specified position.
  3015. //
  3016. // Although it is not strictly an API function, it performs full parameter
  3017. // validation and could be externalised easily.
  3018. //
  3019. //
  3020. UINT OM_ObjectAdd(POM_CLIENT pomClient,
  3021. OM_WSGROUP_HANDLE hWSGroup,
  3022. OM_WORKSET_ID worksetID,
  3023. POM_OBJECTDATA * ppData,
  3024. UINT updateSize,
  3025. POM_OBJECT * ppObj,
  3026. OM_POSITION position);
  3027. //
  3028. //
  3029. // OM_ObjectMove(...)
  3030. //
  3031. // This function moves an object to the start or end of a workset. It is
  3032. // called by OM_ObjectMoveFirst and OM_ObjectMoveLast.
  3033. //
  3034. // Although it is not strictly an API function, it performs full parameter
  3035. // validation and could be externalised easily.
  3036. //
  3037. //
  3038. UINT OM_ObjectMove(POM_CLIENT pomClient,
  3039. OM_WSGROUP_HANDLE hWSGroup,
  3040. OM_WORKSET_ID worksetID,
  3041. POM_OBJECT pObj,
  3042. OM_POSITION position);
  3043. //
  3044. //
  3045. // ValidateParamsX(...)
  3046. //
  3047. // These functions are used to validate parameters and convert them to
  3048. // various pointers, as follows:
  3049. //
  3050. // ValidateParams2 - checks pomClient, hWSGroup
  3051. // - returns pUsageRec, pWSGroup
  3052. //
  3053. // ValidateParams3 - checks pomClient, hWSGroup, worksetID,
  3054. // - returns pUsageRec, pWorkset
  3055. //
  3056. // Note: also asserts that workset is open
  3057. //
  3058. // ValidateParams4 - checks pomClient, hWSGroup, worksetID, pObj
  3059. //
  3060. // Each of the functions uses DCASSERT to bring down the calling task if an
  3061. // invalid parameter is detected.
  3062. //
  3063. //
  3064. __inline void ValidateParams2(POM_CLIENT pomClient,
  3065. OM_WSGROUP_HANDLE hWSGroup,
  3066. UINT requiredMode,
  3067. POM_USAGE_REC * ppUsageRec,
  3068. POM_WSGROUP * ppWSGroup)
  3069. {
  3070. ValidateOMS(pomClient);
  3071. ASSERT(ValidWSGroupHandle(pomClient, hWSGroup));
  3072. *ppUsageRec = pomClient->apUsageRecs[hWSGroup];
  3073. ValidateUsageRec(*ppUsageRec);
  3074. ASSERT(requiredMode & (*ppUsageRec)->mode);
  3075. *ppWSGroup = (*ppUsageRec)->pWSGroup;
  3076. ValidateWSGroup(*ppWSGroup);
  3077. }
  3078. __inline void ValidateParams3(POM_CLIENT pomClient,
  3079. OM_WSGROUP_HANDLE hWSGroup,
  3080. OM_WORKSET_ID worksetID,
  3081. UINT requiredMode,
  3082. POM_USAGE_REC * ppUsageRec,
  3083. POM_WORKSET * ppWorkset)
  3084. {
  3085. POM_WSGROUP pWSGroup;
  3086. ValidateParams2(pomClient, hWSGroup, requiredMode, ppUsageRec, &pWSGroup);
  3087. ASSERT(WORKSET_IS_OPEN(*ppUsageRec, worksetID));
  3088. *ppWorkset = pWSGroup->apWorksets[worksetID];
  3089. ValidateWorkset(*ppWorkset);
  3090. }
  3091. __inline void ValidateParams4(POM_CLIENT pomClient,
  3092. OM_WSGROUP_HANDLE hWSGroup,
  3093. OM_WORKSET_ID worksetID,
  3094. POM_OBJECT pObj,
  3095. UINT requiredMode,
  3096. POM_USAGE_REC * ppUsageRec,
  3097. POM_WORKSET * ppWorkset)
  3098. {
  3099. ValidateParams3(pomClient, hWSGroup, worksetID, requiredMode, ppUsageRec,
  3100. ppWorkset);
  3101. ValidateObject(pObj);
  3102. ASSERT(!(pObj->flags & DELETED));
  3103. }
  3104. //
  3105. //
  3106. // SetUpUsageRecord(...)
  3107. //
  3108. UINT SetUpUsageRecord(POM_CLIENT pomClient,
  3109. UINT mode,
  3110. POM_USAGE_REC* ppUsageRec,
  3111. OM_WSGROUP_HANDLE * phWSGroup);
  3112. //
  3113. // FindUnusedWSGHandle()
  3114. //
  3115. UINT FindUnusedWSGHandle(POM_CLIENT pomClient, OM_WSGROUP_HANDLE * phWSGroup);
  3116. //
  3117. //
  3118. // ObjectRelease(...)
  3119. //
  3120. // This function releases the specified Client's hold on the the specified
  3121. // object and removes the relevant entry from the Client's objects-in-use
  3122. // list.
  3123. //
  3124. // If <pObj> is NULL, the function releases the first object held by
  3125. // this Client in the specified workset, if any. If there are none, the
  3126. // function returns OM_RC_OBJECT_NOT_FOUND.
  3127. //
  3128. //
  3129. UINT ObjectRelease(POM_USAGE_REC pUsageRec,
  3130. OM_WORKSET_ID worksetID,
  3131. POM_OBJECT pObj);
  3132. //
  3133. //
  3134. // WorksetClearPending(...)
  3135. //
  3136. // Look for a CLEAR_IND which is outstanding for the given workset which,
  3137. // when confirmed, will cause the given object to be deleted.
  3138. //
  3139. // Returns TRUE if such a CLEAR_IND is outstanding, FALSE otherwise.
  3140. //
  3141. //
  3142. BOOL WorksetClearPending(POM_WORKSET pWorkset, POM_OBJECT pObj);
  3143. UINT OM_Register(PUT_CLIENT putTask, OMCLI omClient, POM_CLIENT * ppomClient);
  3144. //
  3145. //
  3146. // Description:
  3147. //
  3148. // This function registers a DC-Groupware task as an ObMan Client. A task
  3149. // must be a registered ObMan Client in order to call any of the other API
  3150. // functions.
  3151. //
  3152. // On successful completion, the value at <ppomClient> is this Client's ObMan
  3153. // handle, which must be passed as a parameter to all other API functions.
  3154. //
  3155. // This function registers an event handler and an exit procedure for the
  3156. // Client, so Clients must have previously registered fewer than the maximum
  3157. // number of Utility Service event handlers and exit procedures.
  3158. //
  3159. // If the are too many Clients already registered with ObMan, an error is
  3160. // returned.
  3161. //
  3162. // Ensuing Events:
  3163. //
  3164. // None
  3165. //
  3166. // Return Codes
  3167. //
  3168. // 0 (== OK)
  3169. // Utility Service return codes
  3170. // OM_RC_TOO_MANY_CLIENTS
  3171. //
  3172. //
  3173. void OM_Deregister(POM_CLIENT * ppomCient);
  3174. void CALLBACK OMSExitProc(LPVOID pomClient);
  3175. //
  3176. //
  3177. // Description:
  3178. //
  3179. // This function deregisters an ObMan Client.
  3180. //
  3181. // On completion, the ObMan handle which the Client was using becomes
  3182. // invalid and the value at <ppomClient> is set to NULL to prevent the task
  3183. // from using it again.
  3184. //
  3185. // This function deregisters the Client from any workset groups with which
  3186. // it was registered.
  3187. //
  3188. // Ensuing Events:
  3189. //
  3190. // None
  3191. //
  3192. // Return Codes
  3193. //
  3194. // None
  3195. //
  3196. //
  3197. UINT OM_WSGroupRegisterPReq(POM_CLIENT pomClient,
  3198. UINT call,
  3199. OMFP fpHandler,
  3200. OMWSG wsg,
  3201. OM_CORRELATOR * pCorrelator);
  3202. //
  3203. //
  3204. // Description:
  3205. //
  3206. // This is an asynchronous function which requests that ObMan register a
  3207. // Client with a particular workset group for PRIMARY access. The workset
  3208. // group is determined by the following:
  3209. //
  3210. // - <call> is the DC-Groupware Call which contains/is to contain the
  3211. // workset group (or OM_NO_CALL if the workset group is/is to
  3212. // be a local workset group)
  3213. //
  3214. // - <functionProfile> is the Function Profile for the workset group
  3215. //
  3216. // - <wsGroupName> is the name of the workset group.
  3217. //
  3218. // The <pomClient> parameter is the ObMan handle returned by the OM_Register
  3219. // function.
  3220. //
  3221. // If a Client wishes to create a new, or register with an existing, workset
  3222. // group which exists only on the local machine, the value OM_NO_CALL should
  3223. // be specified for the <call> parameter. Workset groups created in this
  3224. // way for purely local use may be subsequently transferred into a call by
  3225. // invoking OM_WSGroupMoveReq at some later time.
  3226. //
  3227. // If this function completes successfully, the Client will subsequently
  3228. // receive an OM_WSGROUP_REGISTER_CON event indicating the success or
  3229. // failure of the registration.
  3230. //
  3231. // Registering with a workset group is a prerequisite to opening any of its
  3232. // worksets.
  3233. //
  3234. // If no workset group with this name and function profile exists in the
  3235. // specified call (or locally, if OM_NO_CALL specified), a new, empty
  3236. // workset group is created and assigned <wsGroupName> as its name. This
  3237. // name must be a valid workset group name.
  3238. //
  3239. // If the workset group already exists in the Call, its contents are copied
  3240. // from another node. This data transfer is made at low priority (note that
  3241. // subsequent receipt of the OM_WSGROUP_REGISTER_CON event does not indicate
  3242. // that this data transfer has completed).
  3243. //
  3244. // If there are worksets existing in the workset group, the Client will
  3245. // receive one or more OM_WORKSET_NEW_IND events after receiving the
  3246. // OM_WSGROUP_REGISTER_CON event.
  3247. //
  3248. // Note also that the contents of the workset group may be copied to this
  3249. // node in any order. Therefore, if objects in a workset reference other
  3250. // objects, the Client should not assume that the referenced object is
  3251. // present locally once the reference arrives.
  3252. //
  3253. // Clients registered for primary access to a workset group have full read
  3254. // and write access to the workset group and have a responsilibity to
  3255. // confirm destructive operations (such as workset clear and object delete,
  3256. // update and replace operations), as described in the relevant sections
  3257. // below.
  3258. //
  3259. // At most one Client per node may be registered with a given workset group
  3260. // for primary access. If a second Client attempts to register for primary
  3261. // access, OM_RC_TOO_MANY_CLIENTS is returned asynchronously via the
  3262. // OM_WSGROUP_REGISTER_CON event.
  3263. //
  3264. // On successful completion of the function, the return parameter
  3265. // <pCorrelator> points to a value which may be used by the Client to
  3266. // correlate this call with the event it generates. Notification of a
  3267. // successful registration will contain a workset group handle which the
  3268. // Client must uses subsequently when invoking other ObMan functions
  3269. // relating to this workset group.
  3270. //
  3271. // If the maximum number of workset groups in concurrent use per call has
  3272. // been reached, the OM_RC_TOO_MANY_WSGROUPS error is returned
  3273. // asynchronously. If the maximum number of workset groups in use by one
  3274. // Client is reached, OM_RC_NO_MORE HANDLES is returned synchronously. If
  3275. // ObMan cannot create a new workset group for any other reason, the
  3276. // OM_RC_CANNOT_CREATE_WSG error is returned (synchronously or
  3277. // asynchronously).
  3278. //
  3279. // Note that separate DC-Groupware tasks must each register independently
  3280. // with the workset groups they wish to use, as workset group handles may
  3281. // not be passed between tasks.
  3282. //
  3283. // Ensuing Events:
  3284. //
  3285. // Invoking this function will cause the OM_WSGROUP_REGISTER_CON event to be
  3286. // posted to the invoking Client.
  3287. //
  3288. // If ObMan is forced at some later stage to move the workset group out of
  3289. // the call for which it was intended (usually at call end time), the Client
  3290. // will receive an OM_WSGROUP_MOVE_IND event.
  3291. //
  3292. // When a Client has successfully registered with a workset group, it will
  3293. // receive OM_PERSON_JOINED_IND, OM_PERSON_LEFT_IND and
  3294. // OM_PERSON_DATA_CHANGED_IND events as primaries (including the calling
  3295. // Client) register and deregister from the workset group and change their
  3296. // person data.
  3297. //
  3298. // Return Codes:
  3299. //
  3300. // 0 (== OK)
  3301. // Utility Service return codes
  3302. // OM_RC_NO_MORE_HANDLES
  3303. //
  3304. //
  3305. UINT OM_WSGroupRegisterS(POM_CLIENT pomClient,
  3306. UINT call,
  3307. OMFP fpHandler,
  3308. OMWSG wsg,
  3309. OM_WSGROUP_HANDLE * phWSGroup);
  3310. //
  3311. //
  3312. // Description:
  3313. //
  3314. // This is a synchronous function which requests that ObMan register a
  3315. // Client with a particular workset group for SECONDARY access. The workset
  3316. // group is determined by the following:
  3317. //
  3318. // - <call> is the DC-Groupware call which contains the workset group (or
  3319. // OM_NO_CALL if the workset group is a local workset group)
  3320. //
  3321. // - <functionProfile> is the Function Profile of the workset group
  3322. //
  3323. // - <wsGroupName> is the name of the workset group.
  3324. //
  3325. // The <pomClient> parameter is the ObMan handle returned by the OM_Register
  3326. // function.
  3327. //
  3328. // A Client may only register for secondary access for a workset group when
  3329. // there is already a local Client fully registered for primary access to
  3330. // that workset group. If there is no such local primary, OM_RC_NO_PRIMARY
  3331. // is returned.
  3332. //
  3333. // If there are worksets existing in the workset group, the Client will
  3334. // receive one or more OM_WORKSET_NEW_IND events after this function
  3335. // completes.
  3336. //
  3337. // Registering for secondary access to a workset group gives a Client the
  3338. // same access privileges as a primary Client except for:
  3339. //
  3340. // - creating worksets
  3341. //
  3342. // - moving workset groups into/out of Calls
  3343. //
  3344. // - locking worksets and objects
  3345. //
  3346. // In addition, secondary Clients of a workset group will receive events
  3347. // relating to the workset group in the same way as primary Clients.
  3348. // However, the following important difference applies: secondary Clients
  3349. // will receive notification of object deletes, updates and replaces AFTER
  3350. // the associated operations have taken place (as opposed to primary
  3351. // Clients, who are informed BEFORE action is taken and must invoke the
  3352. // relevant confirmation function).
  3353. //
  3354. // To highlight this difference, these events have a primary and a secondary
  3355. // variety:
  3356. //
  3357. //
  3358. //
  3359. // Primary Secondary
  3360. //
  3361. // - OM_WORKSET_CLEAR_IND OM_WORKSET_CLEARED_IND
  3362. // - OM_OBJECT_DELETE_IND OM_OBJECT_DELETED_IND
  3363. // - OM_OBJECT_REPLACE_IND OM_OBJECT_REPLACED_IND
  3364. // - OM_OBJECT_UPDATE_IND OM_OBJECT_UPDATED_IND
  3365. //
  3366. //
  3367. //
  3368. // Several Clients per node, up to a defined limit, may be registered with
  3369. // a given workset group for secondary access. Once this limit is reached,
  3370. // OM_RC_TOO_MANY_CLIENTS is returned.
  3371. //
  3372. // On successful completion of the function, the return parameter
  3373. // <phWSGoup> points to a workset group handle which the Client must uses
  3374. // subsequently when invoking other ObMan functions relating to this
  3375. // workset group.
  3376. //
  3377. // Note that separate DC-Groupware tasks must each register independently
  3378. // with the workset groups they wish to use, as workset group handles may
  3379. // not be passed between tasks.
  3380. //
  3381. // Ensuing Events:
  3382. //
  3383. // None
  3384. //
  3385. // Return Codes:
  3386. //
  3387. // 0 (== OK)
  3388. // Utility Service return codes
  3389. // OM_RC_NO_MORE_HANDLES
  3390. // OM_RC_NO_PRIMARY
  3391. // OM_RC_TOO_MANY_CLIENTS
  3392. //
  3393. //
  3394. UINT OM_WSGroupMoveReq(POM_CLIENT pomClient,
  3395. OM_WSGROUP_HANDLE hWSGroup,
  3396. UINT callID,
  3397. OM_CORRELATOR * pCorrelator);
  3398. //
  3399. //
  3400. // Description:
  3401. //
  3402. // This function requests that ObMan move a local workset group previously
  3403. // created as a local workset group (i.e. created specifying the OM_NO_CALL
  3404. // for the Call ID parameter) into the DC-Groupware Call identified by
  3405. // <callID>. If the move is successful, the workset group becomes available
  3406. // at all nodes in the Call.
  3407. //
  3408. // The workset group to move is specified by <hWSGroup>, which must be a
  3409. // valid workset group handle.
  3410. //
  3411. // If the function completes successfully, the OM_WSGROUP_MOVE_CON event is
  3412. // posted to the Client when the attempt to move the workset group into the
  3413. // Call has completed. This event indicates whether the attempt was
  3414. // successful.
  3415. //
  3416. // If there is already a (different) workset group in the specified Call
  3417. // with the same name and Function Profile, this function will fail
  3418. // asynchronously.
  3419. //
  3420. // Ensuing Events:
  3421. //
  3422. // Invoking this function causes the OM_WSGROUP_MOVE_CON to be posted to the
  3423. // invoking Client. If the move is successful, the OM_WSGROUP_MOVE_IND
  3424. // event is also posted to all local Clients which are registered with the
  3425. // workset group, including the invoking Client.
  3426. //
  3427. // Return Codes:
  3428. //
  3429. // 0 (== OK)
  3430. // OM_RC_ALREADY_IN_CALL
  3431. // Utility Service return codes
  3432. //
  3433. //
  3434. void OM_WSGroupDeregister(POM_CLIENT pomClient, OM_WSGROUP_HANDLE * phWSGroup);
  3435. //
  3436. //
  3437. // Description:
  3438. //
  3439. // This function deregisters the Client from the workset group specified by
  3440. // the handle at <phWSGroup>. Any worksets which the Client had open in
  3441. // the workset group are closed (thereby releasing all locks), and the
  3442. // Client will receive no more events relating to this workset group.
  3443. //
  3444. // This call may cause the local copy of the workset group and its worksets
  3445. // to be discarded; in this sense, this function is destructive.
  3446. //
  3447. // This call sets the value at <phWSGroup> to NULL to prevent the Client
  3448. // using this handle in further calls to ObMan.
  3449. //
  3450. // Ensuing Events:
  3451. //
  3452. // None
  3453. //
  3454. // Return Codes:
  3455. //
  3456. // None
  3457. //
  3458. //
  3459. UINT OM_WorksetOpenPReq(POM_CLIENT pomClient,
  3460. OM_WSGROUP_HANDLE hWSGroup,
  3461. OM_WORKSET_ID worksetID,
  3462. NET_PRIORITY priority,
  3463. BOOL fTemp,
  3464. OM_CORRELATOR * pCorrelator);
  3465. UINT OM_WorksetOpenS(POM_CLIENT pomClient,
  3466. OM_WSGROUP_HANDLE hWSGroup,
  3467. OM_WORKSET_ID worksetID);
  3468. //
  3469. //
  3470. // Description:
  3471. //
  3472. // These functions open a specified workset for a Client.
  3473. //
  3474. // OM_WorksetOpenPReq is an asynchronous function which will create the
  3475. // workset if it does not exist. Only primary Clients of this workset group
  3476. // may call this function.
  3477. //
  3478. // OM_WorksetOpenS is a synchronous function which will return
  3479. // OM_RC_WORKSET_DOESNT_EXIST if the workset does not exist. Only secondary
  3480. // Clients of this workset group may call this function.
  3481. //
  3482. // In the asynchronous (primary) case, when ObMan has opened the workset for
  3483. // the Client, or failed to do so, it posts an OM_WORKSET_OPEN_CON event to
  3484. // the Client indicating success or the reason for failure. This event will
  3485. // contain the correlator value returned in <pCorrelator> by this function.
  3486. //
  3487. // If this action results in the creation of a new workset, <priority> will
  3488. // specify the MCS priority at which data relating to the workset will be
  3489. // transmitted. Note that NET_TOP_PRIORITY is reserved for ObMan's private
  3490. // use and must not be specified as the <priority> parameter.
  3491. //
  3492. // If OM_OBMAN_CHOOSES_PRIORITY is specified as the <priority> parameter,
  3493. // ObMan will prioritise data transfers according to size.
  3494. //
  3495. // If the workset already exists, the Client will receive an
  3496. // OM_OBJECT_ADD_IND event for each object that is in the workset when it is
  3497. // opened.
  3498. //
  3499. // Opening a workset is a prerequisite to performing any operations on it or
  3500. // its contents. Once a Client has opened a workset it will receive events
  3501. // when changes are made to the workset or its contents.
  3502. //
  3503. // If this Client has already opened this workset,
  3504. // OM_RC_WORKSET_ALREADY_OPEN is returned. No 'use count' of opens is
  3505. // maintained, so the first OM_WorksetClose will close the workset,
  3506. // irrespective of how many times it has been opened.
  3507. //
  3508. // Ensuing Events:
  3509. //
  3510. // Invoking OM_WorksetOpenPReq causes the OM_WORKSET_OPEN_CON event to be
  3511. // posted to the invoking Client.
  3512. //
  3513. // If this action results in the creation of a new workset, an
  3514. // OM_WORKSET_NEW_IND is posted to all Clients which are registered with the
  3515. // workset group, including the invoking Client.
  3516. //
  3517. // In both the primary and secondary cases, if the workset contains any
  3518. // objects, an OM_OBJECT_ADD_IND event will be posted to the Client for each
  3519. // one.
  3520. //
  3521. // Return Codes:
  3522. //
  3523. // 0 (== OK)
  3524. // Utility Service return codes
  3525. // OM_RC_WORKSET_DOESNT_EXIST
  3526. // OM_RC_WORKSET_ALREADY_OPEN
  3527. //
  3528. //
  3529. #define OM_OBMAN_CHOOSES_PRIORITY (NET_INVALID_PRIORITY)
  3530. void OM_WorksetClose(POM_CLIENT pomClient,
  3531. OM_WSGROUP_HANDLE hWSGroup,
  3532. OM_WORKSET_ID worksetID);
  3533. //
  3534. //
  3535. // Description:
  3536. //
  3537. // This function closes the workset in <hWSGroup> identified by <worksetID>.
  3538. // The Client may no longer access this workset and will receive no more
  3539. // events relating to it. ObMan will however continue to update the
  3540. // contents of the workset in the background; in this sense, this function
  3541. // is non-destructive.
  3542. //
  3543. // When a Client closes a workset, ObMan automatically releases the
  3544. // following resources:
  3545. //
  3546. // - any locks the Client has relating to this workset
  3547. //
  3548. // - any objects which the Client had been reading or had allocated
  3549. // for writing in the workset.
  3550. //
  3551. // If indication events which require a Confirm function to be invoked have
  3552. // been received by the Client but not yet confirmed, these Confirms are
  3553. // implicitly executed by ObMan AND THE CLIENT MUST NOT SUBSEQUENTLY ATTEMPT
  3554. // TO CONFIRM THEM.
  3555. //
  3556. // Ensuing Events:
  3557. //
  3558. // None
  3559. //
  3560. // Return Codes:
  3561. //
  3562. // None
  3563. //
  3564. //
  3565. void OM_WorksetFlowQuery(POM_CLIENT pomClient,
  3566. OM_WSGROUP_HANDLE hWSGroup,
  3567. OM_WORKSET_ID worksetID,
  3568. UINT* pBytesOutstanding);
  3569. //
  3570. //
  3571. // Description:
  3572. //
  3573. // A Client calls this function whenever it wishes to discover the size of
  3574. // the backlog of data relating to the workset identified by <hWSGroup> and
  3575. // <worksetID>.
  3576. //
  3577. // The "backlog" is defined as the total number of bytes of object data
  3578. // which ObMan has been given by its local Clients and which have not yet
  3579. // been acknowledged by all remote nodes where there are Clients registered
  3580. // with the workset group.
  3581. //
  3582. // Ensuing Events:
  3583. //
  3584. // None
  3585. //
  3586. // Return Codes:
  3587. //
  3588. // None
  3589. //
  3590. //
  3591. UINT OM_WorksetLockReq(POM_CLIENT pomClient,
  3592. OM_WSGROUP_HANDLE hWSGroup,
  3593. OM_WORKSET_ID worksetID,
  3594. OM_CORRELATOR * pCorrelator);
  3595. //
  3596. //
  3597. // Description:
  3598. //
  3599. // This is an asynchronous function which requests a lock for the workset in
  3600. // <hWSGroup> identified by <worksetID>. When ObMan has processed the lock
  3601. // request, it will send an OM_WORKSET_LOCK_CON event to the Client
  3602. // indicating success or the reason for failure.
  3603. //
  3604. // Holding a workset lock prevents other Clients from making any changes to
  3605. // the workset or any of its objects. Specifically, the following functions
  3606. // are prohibited:
  3607. //
  3608. // - locking the same workset
  3609. //
  3610. // - locking an object in the workset
  3611. //
  3612. // - moving an object within the workset
  3613. //
  3614. // - adding an object to the workset
  3615. //
  3616. // - deleting an object from the workset
  3617. //
  3618. // - updating or replacing an object in the workset.
  3619. //
  3620. // Locking a workset does not prevent other Clients from reading its
  3621. // contents.
  3622. //
  3623. // The function will cause an assertion failure if the Client requesting the
  3624. // lock already holds or has requested a lock which is equal to or after
  3625. // this one in the Universal Locking Order.
  3626. //
  3627. // On successful completion of the function, the value at <pCorrelator> is a
  3628. // value which the Client can use to correlate the subsequent
  3629. // OM_OBJECT_LOCK_CON event with this request.
  3630. //
  3631. // A Client must release the lock when it no longer needs it, using the
  3632. // OM_WorksetUnlock function. Locks will be automatically released when a
  3633. // Client closes the workset or deregisters from the workset group.
  3634. //
  3635. // Only primary Clients of a workset group may call this function.
  3636. //
  3637. // Ensuing Events:
  3638. //
  3639. // Invoking this function will cause the OM_WORKSET_LOCK_CON event to be
  3640. // posted to the invoking Client at some later time.
  3641. //
  3642. // Return Codes:
  3643. //
  3644. // 0 (== OK)
  3645. // Utility Service return codes
  3646. //
  3647. //
  3648. void OM_WorksetUnlock(POM_CLIENT pomClient,
  3649. OM_WSGROUP_HANDLE hWSGroup,
  3650. OM_WORKSET_ID worksetID);
  3651. //
  3652. //
  3653. // Description:
  3654. //
  3655. // This function unlocks the workset in <hWSGroup> identified by
  3656. // <worksetID>. This must be the lock most recently acquired or requested
  3657. // by the Client; otherwise, the lock violation error causes an assertion
  3658. // failure.
  3659. //
  3660. // If this function is called before the OM_WORKSET_LOCK_CON event is
  3661. // received, the Client will not subsequently receive the event.
  3662. //
  3663. // Ensuing Events:
  3664. //
  3665. // This function causes an OM_WORKSET_UNLOCK_IND to be posted to all Clients
  3666. // which have the workset open, including the invoking Client.
  3667. //
  3668. // Return Codes:
  3669. //
  3670. // None
  3671. //
  3672. //
  3673. void OM_WorksetCountObjects(
  3674. POM_CLIENT pomClient,
  3675. OM_WSGROUP_HANDLE hWSGroup,
  3676. OM_WORKSET_ID worksetID,
  3677. UINT* pCount);
  3678. //
  3679. //
  3680. // Description:
  3681. //
  3682. // On successful completion of this function , the value at <pCount> is the
  3683. // number of objects in the workset in <hWSGroup> identified by
  3684. // <worksetID>.
  3685. //
  3686. // Ensuing Events:
  3687. //
  3688. // None
  3689. //
  3690. // Return Codes:
  3691. //
  3692. // None
  3693. //
  3694. //
  3695. UINT OM_WorksetClear(POM_CLIENT pomClient,
  3696. OM_WSGROUP_HANDLE hWSGroup,
  3697. OM_WORKSET_ID worksetID);
  3698. //
  3699. //
  3700. // Description:
  3701. //
  3702. // This function requests that ObMan clear (i.e. delete the contents of)
  3703. // the workset in <hWSGroup> identified by <worksetID>.
  3704. //
  3705. // When this function is invoked, all Clients with the workset open
  3706. // (including the invoking Client) are notified of the impending clear via
  3707. // the OM_WORKSET_CLEAR_IND event. In response, each Client must invoke the
  3708. // OM_WorksetClearConfirm function; its view of the workset will not be
  3709. // cleared until it has done so.
  3710. //
  3711. // Ensuing Events:
  3712. //
  3713. // This function will result in the OM_WORKSET_CLEAR_IND being posted to all
  3714. // Clients which have the workset open, including the invoking Client.
  3715. //
  3716. // Return Codes
  3717. //
  3718. // 0 (== OK)
  3719. // Utility Service return codes
  3720. // OM_RC_WORKSET_EXHAUSTED
  3721. //
  3722. //
  3723. void OM_WorksetClearConfirm(
  3724. POM_CLIENT pomClient,
  3725. OM_WSGROUP_HANDLE hWSGroup,
  3726. OM_WORKSET_ID worksetID);
  3727. //
  3728. //
  3729. // Description:
  3730. //
  3731. // A Client must call this function after it receives an
  3732. // OM_WORKSET_CLEAR_IND. When the function is invoked, ObMan clears this
  3733. // Client's view of the workset. It is bad Groupware programming practice
  3734. // for a Client to unduly delay invoking this function.
  3735. //
  3736. // Note however that this function has a purely local effect: delaying (or
  3737. // executing) a clear confirm at one node will not affect the contents of
  3738. // the workset group at any other node.
  3739. //
  3740. // It is illegal to call this function when a Client has not received an
  3741. // OM_WORKSET_CLEAR_IND event.
  3742. //
  3743. // The arguments to the function must be the same as the workset group
  3744. // handle and workset ID included with the OM_WORKSET_CLEAR_IND event.
  3745. //
  3746. // The function will fail if ObMan is not expecting a clear-confirmation for
  3747. // this workset.
  3748. //
  3749. // This function causes all objects being read in this workset, and all
  3750. // object locks in this workset, to be released (i.e. the function performs
  3751. // implicit OM_ObjectUnlock and OM_ObjectRelease functions). It does not
  3752. // cause objects allocated using OM_ObjectAlloc to be discarded.
  3753. //
  3754. // If there are indication events for object Deletes, Replaces or Confirms
  3755. // which have been posted to the Client but not yet confirmed, these
  3756. // confirmations are implicitly executed.
  3757. //
  3758. // Ensuing Events:
  3759. //
  3760. // When the primary Client of a workset group confirms a clear using this
  3761. // function, an OM_WORKSET_CLEARED_IND is posted to all local secondary
  3762. // Clients of the workset group.
  3763. //
  3764. // Return Codes:
  3765. //
  3766. // None
  3767. //
  3768. //
  3769. //
  3770. //
  3771. // Description:
  3772. //
  3773. // These functions add an object to the workset in <hWSGroup> identified by
  3774. // <worksetID>. The <ppObject> parameter is a pointer to a pointer to the
  3775. // object.
  3776. //
  3777. // The position to add the object is determined as follows:
  3778. //
  3779. // - OM_ObjectAddLast: after the last object in the workset
  3780. //
  3781. // - OM_ObjectAddFirst: before the first object in the workset
  3782. //
  3783. // - OM_ObjectAddAfter: after the object specified by <hExistingObject>
  3784. //
  3785. // - OM_ObjectAddBefore: before the object specified by <hExistingObject>.
  3786. //
  3787. // Note that the OM_ObjectAddAfter and OM_ObjectAddBefore functions require
  3788. // that the invoking Client holds a workset lock, whereas the
  3789. // OM_ObjectAddFirst and OM_ObjectAddLast functions will fail if the workset
  3790. // is locked by another Client.
  3791. //
  3792. // ------------------------------------------------------------------------
  3793. //
  3794. // Note: OM_ObjectAddAfter and OM_ObjectAddBefore are not implemented in
  3795. // DC-Groupware R1.1.
  3796. //
  3797. // ------------------------------------------------------------------------
  3798. //
  3799. // On successful completion of the function, <phNewObject> points to the
  3800. // newly created handle of the object added. The Client should use this
  3801. // handle in all subsequent ObMan calls relating to this object.
  3802. //
  3803. // The <ppObject> parameter must be a pointer to a valid object pointer
  3804. // returned by the OM_ObjectAlloc function. If the function completes
  3805. // successfully, ObMan assumes ownership of the object and the value at
  3806. // <ppObject> is set to NULL to prevent the Client using the object pointer
  3807. // again.
  3808. //
  3809. // The <updateSize> parameter is the size (in bytes) of that portion of the
  3810. // object which may be updated using the OM_ObjectUpdate function (not
  3811. // counting the <length> field).
  3812. //
  3813. // Additions to a workset will be sequenced identically at all nodes which
  3814. // have the workset open, but the actual sequence arising from simultaneous
  3815. // additions by multiple Clients cannot be predicted in advance.
  3816. //
  3817. // If a set of Clients wishes to impose a particular sequence, they can
  3818. // enforce this using an agreed locking protocol based on the workset
  3819. // locking (in most cases, it is only necessary that the order is the same
  3820. // everywhere, which is why locking is not enforced by ObMan).
  3821. //
  3822. // Ensuing Events:
  3823. //
  3824. // This function causes an OM_OBJECT_ADD_IND to be posted to all Clients
  3825. // which have the workset open, including the invoking Client.
  3826. //
  3827. // Return Codes:
  3828. //
  3829. // 0 (== OK)
  3830. // Utility Service return codes
  3831. // OM_RC_WORKSET_LOCKED (AddFirst, AddLast only)
  3832. // OM_RC_WORKSET_EXHAUSTED
  3833. //
  3834. //
  3835. //
  3836. //
  3837. // Description:
  3838. //
  3839. // These functions move an object within a workset. The workset is
  3840. // specified by <worksetID> and <hWSGroup> and the handle of the object to
  3841. // be moved is specified by <pObj>
  3842. //
  3843. // The position to which the object is moved is determined as follows:
  3844. //
  3845. // - OM_ObjectMoveLast: after the last object in the workset
  3846. //
  3847. // - OM_ObjectMoveFirst: before the first object in the workset
  3848. //
  3849. // - OM_ObjectMoveAfter: after the object specified by <pObj2>
  3850. //
  3851. // - OM_ObjectMoveBefore: before the object specified by <pObj2>.
  3852. //
  3853. // Note that OM_ObjectMoveAfter and OM_ObjectMoveBefore require that the
  3854. // invoking Client holds a workset lock, whereas the OM_ObjectMoveFirst and
  3855. // OM_ObjectMoveLast functions will fail if the workset is locked by another
  3856. // Client.
  3857. //
  3858. // ------------------------------------------------------------------------
  3859. //
  3860. // Note: OM_ObjectMoveAfter and OM_ObjectMoveBefore are not implemented in
  3861. // DC-Groupware R1.1.
  3862. //
  3863. // ------------------------------------------------------------------------
  3864. //
  3865. // Locked objects may be moved.
  3866. //
  3867. // Neither the handle nor the ID of an object is altered by moving it within
  3868. // a workset.
  3869. //
  3870. // Ensuing Events
  3871. //
  3872. // This action causes the OM_OBJECT_MOVE_IND to be posted to all Clients
  3873. // which have the workset open, including the invoking Client.
  3874. //
  3875. // Return Codes
  3876. //
  3877. // 0 (== OK)
  3878. // Utility Service return codes
  3879. // OM_RC_WORKSET_EXHAUSTED
  3880. // OM_RC_WORKSET_LOCKED (MoveFirst, MoveLast only)
  3881. //
  3882. //
  3883. UINT OM_ObjectDelete(
  3884. POM_CLIENT pomClient,
  3885. OM_WSGROUP_HANDLE hWSGroup,
  3886. OM_WORKSET_ID worksetID,
  3887. POM_OBJECT pObj);
  3888. //
  3889. //
  3890. // Description:
  3891. //
  3892. // This function requests that ObMan delete an object from a workset. The
  3893. // workset is specified by <worksetID> and <hWSGroup> and the handle of the
  3894. // object to be deleted is <pObj>.
  3895. //
  3896. // The local copy of the object is not actually deleted until the Client
  3897. // invokes OM_ObjectDeleteConfirm in response to the OM_OBJECT_DELETE_IND
  3898. // event which this function generates.
  3899. //
  3900. // When this function is invoked, all Clients with the workset open
  3901. // (including the invoking Client) are notified of the impending deletion
  3902. // via the OM_OBJECT_DELETE_IND event. In response, each Client must invoke
  3903. // the OM_ObjectDeleteConfirm function; each Client will have access to the
  3904. // object until it has done so.
  3905. //
  3906. // If this object is already pending deletion (i.e. a DELETE_IND event has
  3907. // been posted to the Client but not yet Confirmed) this function returns
  3908. // the OM_RC_OBJECT_DELETED error.
  3909. //
  3910. // ObMan guarantees not to reuse a discarded object handle in the same
  3911. // workset within the lifetime of the workset group.
  3912. //
  3913. // Ensuing Events:
  3914. //
  3915. // This function causes the OM_OBJECT_DELETE_IND to be posted to all Clients
  3916. // which have the workset open, including the invoking Client (except as
  3917. // where stated above).
  3918. //
  3919. // Return Codes:
  3920. //
  3921. // 0 (== OK)
  3922. // Utility Service return codes
  3923. // OM_RC_WORKSET_LOCKED
  3924. // OM_RC_WORKSET_EXHAUSTED
  3925. // OM_RC_OBJECT_DELETED
  3926. //
  3927. //
  3928. void OM_ObjectDeleteConfirm(
  3929. POM_CLIENT pomClient,
  3930. OM_WSGROUP_HANDLE hWSGroup,
  3931. OM_WORKSET_ID worksetID,
  3932. POM_OBJECT pObj);
  3933. //
  3934. //
  3935. // Description:
  3936. //
  3937. // A Client must call this function after it receives an
  3938. // OM_OBJECT_DELETE_IND. When the function is invoked, ObMan deletes the
  3939. // object specified by <hWSGroup>, <worksetID> and the value at <ppObj>.
  3940. // It is bad Groupware programming practice for a Client to unduly delay
  3941. // invoking this function.
  3942. //
  3943. // Note however that this function has a purely local effect: delaying (or
  3944. // executing) a delete confirm at one node will not affect the contents of
  3945. // the workset group at any other node.
  3946. //
  3947. // On successful completion, the handle of the deleted object becomes
  3948. // invalid and the value at <ppObj> is set to NULL to prevent the Client
  3949. // from further accessing this object.
  3950. //
  3951. // Any pointer to the previous version of this object which the Client had
  3952. // obtained using OM_ObjectRead becomes invalid and should not be referred
  3953. // to again (i.e. the function performs an implicit OM_ObjectRelease).
  3954. //
  3955. // The function will cause an assertion failure if ObMan is not expecting a
  3956. // delete-confirmation for this object.
  3957. //
  3958. // Ensuing Events:
  3959. //
  3960. // When the primary Client of a workset group confirms a delete using this
  3961. // function, an OM_OBJECT_DELETED_IND is posted to all local secondary
  3962. // Clients of the workset group.
  3963. //
  3964. // Return Codes:
  3965. //
  3966. // None
  3967. //
  3968. //
  3969. UINT OM_ObjectReplace(
  3970. POM_CLIENT pomClient,
  3971. OM_WSGROUP_HANDLE hWSGroup,
  3972. OM_WORKSET_ID worksetID,
  3973. POM_OBJECT pObj,
  3974. POM_OBJECTDATA * ppData);
  3975. UINT OM_ObjectUpdate(
  3976. POM_CLIENT pomClient,
  3977. OM_WSGROUP_HANDLE hWSGroup,
  3978. OM_WORKSET_ID worksetID,
  3979. POM_OBJECT pObj,
  3980. POM_OBJECTDATA * ppData);
  3981. //
  3982. //
  3983. // Description:
  3984. //
  3985. // This function requests that ObMan replaces/updates the object specified
  3986. // by <pObj> in the workset specified by <worksetID> and <hWSGroup>.
  3987. //
  3988. // "Replacing" one object with another causes the previous object to be
  3989. // lost. "Updating" an object causes only the first N bytes of the object
  3990. // to be replaced by the <data> field of the object supplied, where N is the
  3991. // <length> field of the update. The rest of the object data remains the
  3992. // same, as does the length of the object.
  3993. //
  3994. // The local copy of the object is not actually replaced/updated until the
  3995. // Client invokes OM_ObjectReplaceConfirm/OM_ObjectUpdateConfirm in response
  3996. // to the OM_OBJECT_REPLACE_IND/OM_OBJECT_UPDATE_IND which this function
  3997. // generates.
  3998. //
  3999. // The <ppObject> parameter must be a pointer to a valid object pointer
  4000. // returned by the OM_ObjectAlloc function. If the function completes
  4001. // successfully, ObMan assumes ownership of the object and the value at
  4002. // <ppObject> is set to NULL to prevent the Client using the object pointer
  4003. // again.
  4004. //
  4005. // Neither the handle nor the ID of an object is altered by replacing or
  4006. // updating the object.
  4007. //
  4008. // If the object is pending deletion i.e. if ObMan has posted an
  4009. // OM_OBJECT_DELETE_IND event which has not yet been confirmed, the
  4010. // OM_RC_OBJECT_DELETED error is returned.
  4011. //
  4012. // If the object is pending replace or update i.e. if ObMan has posted an
  4013. // OM_OBJECT_REPLACE_IND/OM_OBJECT_UPDATE_IND event which has not yet been
  4014. // confirmed, this replace/update spoils the previous one. In this case, no
  4015. // further event is posted, and when the outstanding event is confirmed, the
  4016. // most recent replace/update is performed.
  4017. //
  4018. // The <reserved> parameter to OM_ObjectUpdate is not used in DC-Groupware
  4019. // R1.1 and must be set to zero.
  4020. //
  4021. // For a replace, the size of the object specified by <ppObject> must be at
  4022. // least as large as the <updateSize> specified when the object was
  4023. // originally added.
  4024. //
  4025. // For an update, the size of the object specified by <ppObject> must be the
  4026. // same as the <updateSize> specified when the object was originally added.
  4027. //
  4028. // Object replaces/updates will be sequenced identically at all nodes, but
  4029. // the actual sequence arising from simultaneous replace/update operations
  4030. // by multiple Clients cannot be predicted in advance.
  4031. //
  4032. // If a set of Clients wishes to impose a particular sequence, they should
  4033. // use an agreed locking protocol based on object or workset locking (in
  4034. // most cases, it is only necessary that the order is the same everywhere,
  4035. // which is why locking is not enforced by ObMan).
  4036. //
  4037. // Replaces and updates may be spoiled by ObMan so Client should not assume
  4038. // that an event will be generated for each replace or update carried out.
  4039. //
  4040. // Ensuing Events:
  4041. //
  4042. // This function causes the OM_OBJECT_REPLACE_IND/OM_OBJECT_UPDATE_IND to be
  4043. // posted to all Clients which have the workset open, including the invoking
  4044. // Client.
  4045. //
  4046. // Return Codes:
  4047. //
  4048. // 0 (== OK)
  4049. // Utility Service return codes
  4050. // OM_RC_WORKSET_LOCKED
  4051. // OM_RC_OBJECT_LOCKED
  4052. // OM_RC_OBJECT_DELETED
  4053. //
  4054. //
  4055. void OM_ObjectReplaceConfirm(
  4056. POM_CLIENT pomClient,
  4057. OM_WSGROUP_HANDLE hWSGroup,
  4058. OM_WORKSET_ID worksetID,
  4059. POM_OBJECT pObj);
  4060. void OM_ObjectUpdateConfirm(
  4061. POM_CLIENT pomClient,
  4062. OM_WSGROUP_HANDLE hWSGroup,
  4063. OM_WORKSET_ID worksetID,
  4064. POM_OBJECT pObj);
  4065. //
  4066. //
  4067. // Description:
  4068. //
  4069. // When a Client receives an OM_OBJECT_REPLACE_IND/OM_OBJECT_UPDATE_IND, it
  4070. // must confirm the relevant operation by calling OM_ObjectReplaceConfirm or
  4071. // OM_ObjectUpdateConfirm.
  4072. //
  4073. // When the functions are invoked, ObMan replaces/updates the object
  4074. // specified by <hWSGroup>, <worksetID> and <pObj>. It is bad Groupware
  4075. // programming practice for a Client to unduly delay invoking this function.
  4076. //
  4077. // Note however that these functions have a purely local effect: delaying
  4078. // (or executing) replace/update confirms at one node will not affect the
  4079. // contents of the workset group at any other node.
  4080. //
  4081. // Any pointer to the previous version of this object which the Client had
  4082. // obtained using OM_ObjectRead becomes invalid and should not be referred
  4083. // to again (i.e. the functions perform an implicit OM_ObjectRelease).
  4084. //
  4085. // The functions will cause an assertion failure if ObMan is not expecting a
  4086. // replace- or update-confirmation for this object.
  4087. //
  4088. // Ensuing Events:
  4089. //
  4090. // When the primary Client of a workset group confirms an update or replace
  4091. // using this function, an OM_OBJECT_UPDATED_IND/OM_OBJECT_REPLACED_IND is
  4092. // posted to all local secondary Clients of the workset group.
  4093. //
  4094. // Return Codes
  4095. //
  4096. // None
  4097. //
  4098. //
  4099. UINT OM_ObjectLockReq(POM_CLIENT pomClient, OM_WSGROUP_HANDLE hWSGroup,
  4100. OM_WORKSET_ID worksetID, POM_OBJECT pObj, BOOL reserved,
  4101. OM_CORRELATOR * pCorrelator);
  4102. //
  4103. //
  4104. // Description:
  4105. //
  4106. // This is an asynchronous function which requests a lock for the object
  4107. // specified by <pObj> in the workset identified by <worksetID> and
  4108. // <hWSGroup>. When ObMan has processed the lock request, it will send an
  4109. // OM_OBJECT_LOCK_CON to the Client indicating success or the reason for
  4110. // failure.
  4111. //
  4112. // ------------------------------------------------------------------------
  4113. //
  4114. // Note: OM_ObjectLockReq and OM_ObjectUnlock are not implemented in
  4115. // DC-Groupware R1.1.
  4116. //
  4117. // ------------------------------------------------------------------------
  4118. //
  4119. // Holding an object lock prevents other Clients from
  4120. //
  4121. // - locking the workset
  4122. //
  4123. // - locking the object
  4124. //
  4125. // - updating or replacing the object
  4126. //
  4127. // - deleting the object.
  4128. //
  4129. // It does not prevent other Clients from reading the object or moving it
  4130. // within a workset.
  4131. //
  4132. // The function will cause an assertion failure if the Client requesting the
  4133. // lock already holds or has requested a lock which is equal to or after
  4134. // this one in the Universal Locking Order.
  4135. //
  4136. // On successful completion of the function, the value at <pCorrelator> is a
  4137. // value which the Client can use to correlate the subsequent
  4138. // OM_OBJECT_LOCK_CON event with this request.
  4139. //
  4140. // The <reserved> parameter is not used in DC-Groupware R1.1 and must be set
  4141. // to zero.
  4142. //
  4143. // A Client must release the lock when it no longer needs it, using the
  4144. // OM_ObjectUnlock function. Locks will be automatically released when a
  4145. // Client closes the workset or deregisters from the workset group.
  4146. //
  4147. // Ensuing Events:
  4148. //
  4149. // Invoking this function will cause the OM_OBJECT_LOCK_CON event to be
  4150. // posted to the invoking Client at some later time.
  4151. //
  4152. // Return Codes:
  4153. //
  4154. // 0 (== OK)
  4155. // Utility Service return codes
  4156. //
  4157. //
  4158. void OM_ObjectUnlock(
  4159. POM_CLIENT pomClient,
  4160. OM_WSGROUP_HANDLE hWSGroup,
  4161. OM_WORKSET_ID worksetID,
  4162. POM_OBJECT pObj);
  4163. //
  4164. //
  4165. // Description:
  4166. //
  4167. // This function unlocks the object specified by <worksetID> and <pObj>.
  4168. // This must be the lock most recently acquired or requested by the Client;
  4169. // otherwise, the lock violation error causes an assertion failure.
  4170. //
  4171. // If this function is called before the OM_OBJECT_LOCK_CON event is
  4172. // received, the Client will not subsequently receive the event.
  4173. //
  4174. // ------------------------------------------------------------------------
  4175. //
  4176. // Note: OM_ObjectLockReq and OM_ObjectUnlock are not implemented in
  4177. // DC-Groupware R1.1.
  4178. //
  4179. // ------------------------------------------------------------------------
  4180. //
  4181. // Ensuing Events:
  4182. //
  4183. // This function causes an OM_OBJECT_UNLOCK_IND to be posted to all other
  4184. // Clients which have the workset open.
  4185. //
  4186. // Return Codes:
  4187. //
  4188. // None
  4189. //
  4190. //
  4191. UINT OM_ObjectH(POM_CLIENT pomClient,
  4192. OM_WSGROUP_HANDLE hWSGroup,
  4193. OM_WORKSET_ID worksetID,
  4194. POM_OBJECT pObjOther,
  4195. POM_OBJECT * pObj,
  4196. OM_POSITION omPos);
  4197. UINT OM_ObjectRead(POM_CLIENT pomClient,
  4198. OM_WSGROUP_HANDLE hWSGroup,
  4199. OM_WORKSET_ID worksetID,
  4200. POM_OBJECT pObj,
  4201. POM_OBJECTDATA * ppData);
  4202. //
  4203. //
  4204. // Description:
  4205. //
  4206. // This function enables a Client to read the contents of an object by
  4207. // converting an object handle into a pointer to the object.
  4208. //
  4209. // On successful completion, the value at <ppObject> points to the specified
  4210. // object.
  4211. //
  4212. // Invoking this function causes the object to be held in memory at the
  4213. // location indicated by the return value at <ppObject>. When it has
  4214. // finished reading the object, the Client must release it using the
  4215. // OM_ObjectRelease function. Holding object pointer for extended lengths
  4216. // of time may adversely affect ObMan's ability to efficiently manage its
  4217. // memory.
  4218. //
  4219. // This pointer is valid until the Client releases the object, either
  4220. // explicitly with OM_ObjectRelease or implicitly.
  4221. //
  4222. // Ensuing Events:
  4223. //
  4224. // None
  4225. //
  4226. // Return Codes:
  4227. //
  4228. // 0 (== OK)
  4229. // Utility Service return codes
  4230. //
  4231. //
  4232. void OM_ObjectRelease(POM_CLIENT pomClient,
  4233. OM_WSGROUP_HANDLE hWSGroup,
  4234. OM_WORKSET_ID worksetID,
  4235. POM_OBJECT pObj,
  4236. POM_OBJECTDATA * ppData);
  4237. //
  4238. //
  4239. // Description:
  4240. //
  4241. // Calling this function indicates to ObMan that the Client has finished
  4242. // reading the object specified by the handle <pObj>. The <ppObject>
  4243. // parameter is a pointer to a pointer to the object, which was previously
  4244. // obtained using OM_ObjectRead.
  4245. //
  4246. // On successful completion, the pointer to this object which the Client
  4247. // acquired using OM_ObjectRead becomes invalid (as the object may
  4248. // subsequently move in memory) and the value at <ppObject> is set to NULL
  4249. // to prevent the Client from using it again.
  4250. //
  4251. // Ensuing Events:
  4252. //
  4253. // None
  4254. //
  4255. // Return Codes:
  4256. //
  4257. // None
  4258. //
  4259. //
  4260. UINT OM_ObjectAlloc(POM_CLIENT pomClient,
  4261. OM_WSGROUP_HANDLE hWSGroup,
  4262. OM_WORKSET_ID worksetID,
  4263. UINT length,
  4264. POM_OBJECTDATA * ppData);
  4265. //
  4266. //
  4267. // Description:
  4268. //
  4269. // This function allocates a new, empty object the <data> field of which is
  4270. // <length> bytes long. The object must be intended for subsequent
  4271. // insertion into the workset specified by <hWSGroup> and <worksetID>.
  4272. //
  4273. // Note that the <length> parameter is the length of the object's data field
  4274. // (so the total memory requirement for this function is length+4 bytes).
  4275. //
  4276. // The contents of the memory allocated are undefined, and it is the
  4277. // Client's responsibility to fill in the <length> field at the start of the
  4278. // object.
  4279. //
  4280. // On successful completion, the value at <ppObject> points to the new
  4281. // object. This pointer is valid until the Client returns the object to
  4282. // ObMan using one of the functions mentioned here.
  4283. //
  4284. // A Client may write in this object and will normally insert it in the
  4285. // workset for which it was allocated using one of the object add, update or
  4286. // replace functions. However, if a Client fails to do so or decides for
  4287. // some other reason not to do so, it must free up the object by calling the
  4288. // OM_ObjectDiscard function.
  4289. //
  4290. // Ensuing Events:
  4291. //
  4292. // None
  4293. //
  4294. // Return Codes:
  4295. //
  4296. // 0 (== OK)
  4297. // Utility Service return codes
  4298. //
  4299. //
  4300. void OM_ObjectDiscard(POM_CLIENT pomClient,
  4301. OM_WSGROUP_HANDLE hWSGroup,
  4302. OM_WORKSET_ID worksetID,
  4303. POM_OBJECTDATA * ppData);
  4304. //
  4305. //
  4306. // Description:
  4307. //
  4308. // This function discards an object which a Client previously allocated
  4309. // using OM_ObjectAlloc. A Client will call this function if for some
  4310. // reason it does not want to or cannot insert the object into the workset
  4311. // for which it was allocated. A Client must not call this function for an
  4312. // object which it has already added to a workset or used to update or
  4313. // replace an object in a workset.
  4314. //
  4315. // On successful completion, the value at <ppObject> is set to NULL to
  4316. // prevent the Client from accessing the object again.
  4317. //
  4318. // Ensuing Events:
  4319. //
  4320. // None
  4321. //
  4322. // Return Codes:
  4323. //
  4324. // None
  4325. //
  4326. //
  4327. UINT OM_ObjectIDToPtr(POM_CLIENT pomClient,
  4328. OM_WSGROUP_HANDLE hWSGroup,
  4329. OM_WORKSET_ID worksetID,
  4330. OM_OBJECT_ID objectID,
  4331. POM_OBJECT * ppObj);
  4332. //
  4333. //
  4334. // Description:
  4335. //
  4336. // This functions converts an object ID to an object handle. If no object
  4337. // with the specified ID is found in the specified workset, an error is
  4338. // returned.
  4339. //
  4340. // Ensuing Events:
  4341. //
  4342. // None
  4343. //
  4344. // Return Codes:
  4345. //
  4346. // 0 (== OK)
  4347. // OM_RC_BAD_OBJECT_ID
  4348. //
  4349. //
  4350. void OM_ObjectPtrToID(POM_CLIENT pomClient,
  4351. OM_WSGROUP_HANDLE hWSGroup,
  4352. OM_WORKSET_ID worksetID,
  4353. POM_OBJECT pObj,
  4354. POM_OBJECT_ID pObjectID);
  4355. //
  4356. //
  4357. // Description:
  4358. //
  4359. // This functions converts an object handle to an object ID.
  4360. //
  4361. // Ensuing Events:
  4362. //
  4363. // None
  4364. //
  4365. // Return Codes:
  4366. //
  4367. // None
  4368. //
  4369. //
  4370. //
  4371. //
  4372. // Description
  4373. //
  4374. // These functions return information about a particular primary Client
  4375. // (identified by <hPerson>) of the workset group identified by <hWSGroup>
  4376. // <function profile> combination.
  4377. //
  4378. // If the person handle <hPerson> is invalid, the OM_RC_NO_SUCH_PERSON error
  4379. // is returned.
  4380. //
  4381. // Ensuing Events:
  4382. //
  4383. // None
  4384. //
  4385. // Return Codes:
  4386. //
  4387. // 0 (== OK)
  4388. // OM_RC_NO_SUCH_PERSON
  4389. // Utility Service return codes
  4390. //
  4391. //
  4392. UINT OM_GetNetworkUserID(
  4393. POM_CLIENT pomClient,
  4394. OM_WSGROUP_HANDLE hWSGroup,
  4395. NET_UID * pNetUserID);
  4396. //
  4397. //
  4398. // Description:
  4399. //
  4400. // This functions returns ObMan's Network user ID for the call which
  4401. // contains the workset group specified by <hWSGroup>.
  4402. //
  4403. // This network ID corresponds to the <creator> field of objects defined by
  4404. // the Object Manager Function Profile.
  4405. //
  4406. // If the specified workset group is a local workset group (i.e. its
  4407. // "call" is OM_NO_CALL), then the function returns OM_RC_LOCAL_WSGROUP.
  4408. //
  4409. // Ensuing Events:
  4410. //
  4411. // None
  4412. //
  4413. // Return Codes:
  4414. //
  4415. // 0 (== OK)
  4416. // OM_RC_LOCAL_WSGROUP
  4417. //
  4418. //
  4419. BOOL CALLBACK OMSEventHandler(LPVOID pomClient, UINT event, UINT_PTR param1, UINT_PTR param2);
  4420. //
  4421. //
  4422. // Description
  4423. //
  4424. // This is the handler that ObMan registers (as a Utility Service event
  4425. // handler) for Client tasks to trap ObMan events. It serves two main
  4426. // purposes:
  4427. //
  4428. // - some state changes associated with events posted to Client tasks
  4429. // are better made when the event arrives than when it is posted
  4430. //
  4431. // - this handler can detect and discard "out-of-date" events, such as
  4432. // those arriving for a workset which a Client has just closed.
  4433. //
  4434. // The first parameter is the Client's ObMan handle, as returned by
  4435. // OM_Register, cast to a UINT.
  4436. //
  4437. // The second parameter is the event to be processed.
  4438. //
  4439. // The third and fourth parameters to the function are the two parameters
  4440. // associated with the event.
  4441. //
  4442. //
  4443. //
  4444. //
  4445. // OM_OUT_OF_RESOURCES_IND
  4446. //
  4447. // Description:
  4448. //
  4449. // This abnormal failure event is posted when ObMan cannot allocate
  4450. // sufficient resources to complete a particular action, usually one
  4451. // prompted by a network event.
  4452. //
  4453. // Clients should treat this event as a fatal error and attempt to
  4454. // terminate.
  4455. //
  4456. // The parameters included with the event are reserved.
  4457. //
  4458. //
  4459. //
  4460. //
  4461. // OM_WSGROUP_REGISTER_CON
  4462. //
  4463. // Description:
  4464. //
  4465. // This event is posted when ObMan has finished processing a request to
  4466. // register a Client with a workset group. The parameters included with
  4467. // the event are defined as follows:
  4468. //
  4469. // - the second parameter is an OM_EVENT_DATA32 structure:
  4470. //
  4471. // - the <correlator> field is the value which was returned by
  4472. // the corresponding invocation of the OM_WSGroupRegisterPReq
  4473. // function
  4474. //
  4475. // - the <result> field is one of
  4476. //
  4477. // 0 (== OK)
  4478. // Utility Service return codes
  4479. // OM_RC_OUT_OF_RESOURCES
  4480. // OM_RC_TOO_MANY_CLIENTS
  4481. // OM_RC_TOO_MANY_WSGROUPS
  4482. // OM_RC_ALREADY_REGISTERED
  4483. // OM_RC_CANNOT_CREATE_WSG
  4484. //
  4485. // - if the <result> field is 0 (== OK), the first parameter is an
  4486. // OM_EVENT_DATA16 structure which contains a newly created handle
  4487. // to the workset group involved (the <worksetID> field is
  4488. // reserved).
  4489. //
  4490. // Once a Client has received this notification, it will receive
  4491. // OM_WORKSET_NEW_IND events to notify it of the existing worksets in the
  4492. // group, if there are any.
  4493. //
  4494. //
  4495. //
  4496. //
  4497. // OM_WSGROUP_MOVE_CON
  4498. //
  4499. // Description:
  4500. //
  4501. // This event is posted when ObMan has finished processing a request to
  4502. // move an existing workset group into a Call. The parameters included
  4503. // with the event are defined as follows:
  4504. //
  4505. // - the second parameter is an OM_EVENT_DATA32 structure:
  4506. //
  4507. // - the <correlator> field is the value which was returned by
  4508. // the corresponding invocation of the OM_WSGroupMoveReq
  4509. // function
  4510. //
  4511. // - the <result> field is one of
  4512. //
  4513. // 0 (== OK)
  4514. // Utility Service return codes
  4515. // OM_RC_CANNOT_MOVE_WSGROUP
  4516. //
  4517. // - the first parameter is a OM_EVENT_DATA16 structure which contains the
  4518. // handle of the workset group involved (the <worksetID> field is
  4519. // reserved).
  4520. //
  4521. //
  4522. //
  4523. //
  4524. // OM_WSGROUP_MOVE_IND
  4525. //
  4526. // Description:
  4527. //
  4528. // This event is posted when ObMan has moved a workset group either into or
  4529. // out of a Call.
  4530. //
  4531. // This will happen
  4532. //
  4533. // - when the workset group is moved out of a Call (because e.g. the call
  4534. // has ended), thus becoming a local workset group
  4535. //
  4536. // - when a local Client requests to move a local workset group into a
  4537. // Call.
  4538. //
  4539. // The parameters included with the event are defined as follows:
  4540. //
  4541. // - the first parameter is a OM_EVENT_DATA16 which identifies the
  4542. // workset group involved (the <worksetID> field is reserved).
  4543. //
  4544. // - the second parameter is the handle of the Call into which the
  4545. // workset group has been moved (== OM_NO_CALL when the workset group
  4546. // has been moved out of a Call).
  4547. //
  4548. // If the workset group has been moved out of a call, it continues in
  4549. // existence as a local workset group and the Client may continue to use it
  4550. // as before. However, no updates will be sent to or received from Clients
  4551. // residing on other nodes.
  4552. //
  4553. // If a Client wishes to move this workset group into another Call, it can
  4554. // do so using the OM_WSGroupMoveReq function. Note that an attempt to move
  4555. // the workset group back into the same Call is likely to fail due to a name
  4556. // clash since the original version probably still exists in the Call.
  4557. //
  4558. // This event may also be prompted by the failure to allocate memory for a
  4559. // large object being transferred from another node.
  4560. //
  4561. //
  4562. //
  4563. //
  4564. // OM_WORKSET_NEW_IND
  4565. //
  4566. // Description:
  4567. //
  4568. // This event is posted when a new workset has been created (by the
  4569. // receiving Client or by another Client). The parameters included with
  4570. // the event are defined as follows:
  4571. //
  4572. // - the first parameter is a OM_EVENT_DATA16 which identifies the
  4573. // workset involved
  4574. //
  4575. // - the second parameter is reserved.
  4576. //
  4577. //
  4578. //
  4579. //
  4580. // OM_WORKSET_OPEN_CON
  4581. //
  4582. // Description:
  4583. //
  4584. // This event is posted when ObMan has finished processing a request to
  4585. // open a workset for a specific Client.
  4586. //
  4587. // The parameters included with the event are defined as follows:
  4588. //
  4589. // - the first parameter is a OM_EVENT_DATA16 which identifies the
  4590. // workset involved
  4591. //
  4592. // - the second parameter is a OM_EVENT_DATA32 structure:
  4593. //
  4594. // - the <correlator> field is the correlator which was
  4595. // returned by the corresponding invocation of the
  4596. // OM_WorksetOpenReq function
  4597. //
  4598. // - the <result> field is one of
  4599. //
  4600. // 0 (== OK)
  4601. // OM_RC_OUT_OF_RESOURCES.
  4602. //
  4603. // In all but the case of OK, the open request has failed and the Client
  4604. // does not have the workset open.
  4605. //
  4606. //
  4607. //
  4608. //
  4609. // OM_WORKSET_LOCK_CON
  4610. //
  4611. // Description:
  4612. //
  4613. // This event is posted to a Client when ObMan has succeeded in obtaining,
  4614. // or failed to obtain, a workset lock which the Client had requested. The
  4615. // parameters included with the event are as follows:
  4616. //
  4617. // - the first parameter is a OM_EVENT_DATA16 which identifies the
  4618. // workset involved
  4619. //
  4620. // - the second parameter is a OM_EVENT_DATA32 structure:
  4621. //
  4622. // - the <correlator> field is the correlator which was
  4623. // returned by the corresponding invocation of the
  4624. // OM_WorksetLockReq function
  4625. //
  4626. // - the <result> field is one of
  4627. //
  4628. // 0 (== OK)
  4629. // OM_RC_OUT_OF_RESOURCES
  4630. // OM_RC_WORKSET_LOCKED
  4631. // OM_RC_OBJECT_LOCKED.
  4632. //
  4633. // In all but the case of OK, the lock request has failed and the Client
  4634. // does not hold the lock.
  4635. //
  4636. //
  4637. //
  4638. //
  4639. // OM_WORKSET_UNLOCK_IND
  4640. //
  4641. // Description:
  4642. //
  4643. // This event is posted when a workset is unlocked using the
  4644. // OM_WorksetUnlock function. The parameters included with the event are
  4645. // as follows:
  4646. //
  4647. // - the first parameter is a OM_EVENT_DATA16 which identifies the
  4648. // workset involved
  4649. //
  4650. // - the second parameter is reserved.
  4651. //
  4652. //
  4653. //
  4654. //
  4655. // OM_WORKSET_CLEAR_IND
  4656. //
  4657. // Description:
  4658. //
  4659. // This event is posted (to primary Clients only) after a local or remote
  4660. // Client has invoked the OM_WorksetClear function. After a Client receives
  4661. // this event, it must call OM_WorksetClearConfirm to enable ObMan to clear
  4662. // the workset.
  4663. //
  4664. // The parameters included with the event are defined as follows:
  4665. //
  4666. // - the first parameter is a OM_EVENT_DATA16 which identifies the
  4667. // workset involved
  4668. //
  4669. // - the second parameter is reserved.
  4670. //
  4671. //
  4672. //
  4673. //
  4674. // OM_WORKSET_CLEARED_IND
  4675. //
  4676. // Description:
  4677. //
  4678. // This event is posted (to secondary Clients only) when a workset has been cleared.
  4679. //
  4680. // The parameters included with the event are defined as follows:
  4681. //
  4682. // - the first parameter is a OM_EVENT_DATA16 which identifies the
  4683. // workset involved
  4684. //
  4685. // - the second parameter is reserved.
  4686. //
  4687. //
  4688. //
  4689. //
  4690. // OM_OBJECT_ADD_IND
  4691. //
  4692. // Description:
  4693. //
  4694. // This event is posted after a new object has been added to a workset.
  4695. //
  4696. // The parameters to the event are defined as follows:
  4697. //
  4698. // - the first parameter is a OM_EVENT_DATA16 which identifies the
  4699. // workset group and workset involved
  4700. //
  4701. // - the second parameter is the handle of the object involved.
  4702. //
  4703. //
  4704. //
  4705. //
  4706. // OM_OBJECT_MOVE_IND
  4707. //
  4708. // Description:
  4709. //
  4710. // This event is posted after a new object has been moved within a workset.
  4711. //
  4712. // The parameters to the event are defined as follows:
  4713. //
  4714. // - the first parameter is a OM_EVENT_DATA16 which identifies the
  4715. // workset group and workset involved
  4716. //
  4717. // - the second parameter is the handle of the object involved.
  4718. //
  4719. //
  4720. //
  4721. //
  4722. // OM_OBJECT_DELETE_IND
  4723. //
  4724. // Description:
  4725. //
  4726. // This event is posted (to primary Clients only) after a local or remote
  4727. // Client has invoked the OM_ObjectDelete function. After a Client
  4728. // receives this event, it must call OM_ObjectDeleteConfirm to enable ObMan
  4729. // to delete the object.
  4730. //
  4731. // The parameters to the event are defined as follows:
  4732. //
  4733. // - the first parameter is a OM_EVENT_DATA16 which identifies the
  4734. // workset group and workset involved
  4735. //
  4736. // - the second parameter is the handle of the object involved.
  4737. //
  4738. // See also OM_OBJECT_DELETED_IND.
  4739. //
  4740. //
  4741. //
  4742. //
  4743. // OM_OBJECT_REPLACE_IND
  4744. // OM_OBJECT_UPDATE_IND
  4745. //
  4746. // Description:
  4747. //
  4748. // These events are posted (to primary Clients only) after a local or remote
  4749. // Client has invoked the OM_ObjectReplace/OM_ObjectUpdate function. After
  4750. // a Client receives this event, it must call OM_ObjectReplaceConfirm/
  4751. // OM_ObjectUpdateConfirm to enable ObMan to replace/update the object.
  4752. //
  4753. // The parameters to the event are defined as follows:
  4754. //
  4755. // - the first parameter is a OM_EVENT_DATA16 which identifies the
  4756. // workset group and workset involved
  4757. //
  4758. // - the second parameter is the handle of the object involved.
  4759. //
  4760. // See also OM_OBJECT_REPLACED_IND/OM_OBJECT_UPDATED_IND.
  4761. //
  4762. //
  4763. //
  4764. //
  4765. // OM_OBJECT_DELETED_IND
  4766. //
  4767. // Description:
  4768. //
  4769. // This event is posted (to secondary Clients only) when an object has been
  4770. // deleted from a workset. The handle it contains is thus invalid and can
  4771. // only be used to cross-reference against lists maintained by the Client.
  4772. //
  4773. // The Client must not invoke the OM_ObjectDeleteConfirm function on
  4774. // receipt of this event.
  4775. //
  4776. // The parameters to the event are defined as follows:
  4777. //
  4778. // - the first parameter is a OM_EVENT_DATA16 identifying the workset
  4779. // group and workset involved
  4780. //
  4781. // - the second parameter is the handle of the object involved.
  4782. //
  4783. //
  4784. //
  4785. //
  4786. // OM_OBJECT_REPLACED_IND
  4787. // OM_OBJECT_UPDATED_IND
  4788. //
  4789. // Description:
  4790. //
  4791. // These events are posted (to secondary Clients only) when an object has
  4792. // been replaced or updated. When the Client receives this event, the
  4793. // previous data is thus inaccessible.
  4794. //
  4795. // The Client must not invoke the OM_ObjectReplaceConfirm/
  4796. // OM_ObjectUpdateConfirm function on receipt of this event.
  4797. //
  4798. // The parameters to the event are defined as follows:
  4799. //
  4800. // - the first parameter is a OM_EVENT_DATA16 identifying the workset
  4801. // group and workset involved
  4802. //
  4803. // - the second parameter is the handle of the object involved.
  4804. //
  4805. //
  4806. //
  4807. //
  4808. // OM_OBJECT_LOCK_CON
  4809. //
  4810. // Description:
  4811. //
  4812. // This event is posted to a Client when ObMan has succeeded in obtaining
  4813. // (or failed to obtain) an object lock which the Client had requested.
  4814. // The parameters included with the event are defined as follows:
  4815. //
  4816. // - the first parameter is reserved
  4817. //
  4818. // - the second parameter is a OM_EVENT_DATA32 structure:
  4819. //
  4820. // - the <correlator> field is the correlator which was
  4821. // returned by the corresponding invocation of the
  4822. // OM_ObjectLockReq function
  4823. //
  4824. // - the <result> field is one of
  4825. //
  4826. // 0 (== OK)
  4827. // Utility Service return codes
  4828. // OM_RC_WORKSET_LOCKED
  4829. // OM_RC_OBJECT_LOCKED.
  4830. //
  4831. // In all but the case of OK, the lock request has failed and the Client
  4832. // does not hold the lock.
  4833. //
  4834. //
  4835. //
  4836. //
  4837. // OM_OBJECT_UNLOCK_IND
  4838. //
  4839. // Description:
  4840. //
  4841. // This event is posted when a Client has released an object lock using the
  4842. // OM_ObjectUnlock function.
  4843. //
  4844. // The parameters to the event are defined as follows:
  4845. //
  4846. // - the first parameter is a OM_EVENT_DATA16 which identifies the
  4847. // workset group and workset involved
  4848. //
  4849. // - the second parameter is the handle of the object involved.
  4850. //
  4851. //
  4852. //
  4853. //
  4854. // OM_PERSON_JOINED_IND
  4855. // OM_PERSON_LEFT_IND
  4856. // OM_PERSON_DATA_CHANGED_IND
  4857. //
  4858. // Description:
  4859. //
  4860. // These events inform clients registered with a workset group when clients
  4861. // register with the workset group, deregister from it and set their person
  4862. // data, respectively.
  4863. //
  4864. // A client will also receive the appropriate events when it performs these
  4865. // actions itself.
  4866. //
  4867. // Parameters:
  4868. //
  4869. // The first parameter in an OM_EVENT_DATA16 which identifies the workset
  4870. // group to which the event relates. The <worksetID> field of the structure
  4871. // is undefined.
  4872. //
  4873. // The second parameter is the POM_EXTOBJEECT for the person to which the
  4874. // event relates. These handles are not guaranteed to be still valid. In
  4875. // particular, the handle received on the OM_PERSON_LEFT_IND is never valid.
  4876. // If a client wishes to correlate these events with a list of clients,
  4877. // then it is responsible for maintaining the list itself.
  4878. //
  4879. //
  4880. //
  4881. // OMP_Init()
  4882. // OMP_Term()
  4883. //
  4884. BOOL OMP_Init(BOOL * pfCleanup);
  4885. void OMP_Term(void);
  4886. void CALLBACK OMPExitProc(LPVOID pomPrimary);
  4887. BOOL CALLBACK OMPEventsHandler(LPVOID pomPrimary, UINT event, UINT_PTR param1, UINT_PTR param2);
  4888. //
  4889. //
  4890. // ProcessNetData(...)
  4891. //
  4892. // This function is called when a NET_EV_SEND_INDICATION event is received,
  4893. // indicating the arrival of a message from another instance of ObMan. The
  4894. // function determines which OMNET_... message is contained in the network
  4895. // packet and invokes the appropriate ObMan function to process the
  4896. // message.
  4897. //
  4898. //
  4899. void ProcessNetData(POM_PRIMARY pomPrimary,
  4900. POM_DOMAIN pDomain,
  4901. PNET_SEND_IND_EVENT pNetEvent);
  4902. //
  4903. //
  4904. // ProcessNetDetachUser(...)
  4905. //
  4906. // This function is called when a NET_EV_DETACH_INDICATION event is received
  4907. // from the network layer.
  4908. //
  4909. // The function determines whether
  4910. //
  4911. // - we have been thrown out of the Domain by MCS, or
  4912. //
  4913. // - someone else has left/been thrown out
  4914. //
  4915. // and calls ProcessOwnDetach or ProcessOtherDetach as appropriate.
  4916. //
  4917. //
  4918. void ProcessNetDetachUser(POM_PRIMARY pomPrimary, POM_DOMAIN pDomain,
  4919. NET_UID userID);
  4920. //
  4921. //
  4922. // ProcessNetAttachUser(...)
  4923. //
  4924. // This function is called when a NET_ATTACH_INDICATION event is received
  4925. // from the network layer. The function calls MG_ChannelJoin to join us
  4926. // to our own single-user channel.
  4927. //
  4928. //
  4929. void ProcessNetAttachUser(POM_PRIMARY pomPrimary, POM_DOMAIN pDomain,
  4930. NET_UID userID, NET_RESULT result);
  4931. //
  4932. //
  4933. // ProcessNetJoinChannel(...)
  4934. //
  4935. // This function is called when a NET_EV_JOIN_CONFIRM event is received from
  4936. // the network layer. This function determines whether the join was
  4937. // successful and whether the channel joined is
  4938. //
  4939. // - our own single-user channel
  4940. //
  4941. // - the well-known ObManControl channel
  4942. //
  4943. // - a regular workset group channel
  4944. //
  4945. // and then takes appropriate action.
  4946. //
  4947. //
  4948. void ProcessNetJoinChannel(POM_PRIMARY pomPrimary,
  4949. POM_DOMAIN pDomain,
  4950. PNET_JOIN_CNF_EVENT pNetJoinCnf);
  4951. //
  4952. //
  4953. // ProcessNetLeaveChannel(...)
  4954. //
  4955. // This function is called when a NET_EV_LEAVE_INDICATION event is received
  4956. // from the network layer, indicating that we've been thrown out of a
  4957. // channel. This function determines whether the channel is
  4958. //
  4959. // - our own single-user channel
  4960. //
  4961. // - the well-known ObManControl channel
  4962. //
  4963. // - a regular workset group channel
  4964. //
  4965. // and then takes appropriate action; in the first two cases, this means
  4966. // behaving as if we've been thrown out of the Domain altogether, whereas
  4967. // we treat the last case just as if a Client had asked to move the workset
  4968. // group into the local Domain.
  4969. //
  4970. //
  4971. UINT ProcessNetLeaveChannel(POM_PRIMARY pomPrimary,
  4972. POM_DOMAIN pDomain,
  4973. NET_CHANNEL_ID channel);
  4974. //
  4975. //
  4976. // DomainRecordFindOrCreate(...)
  4977. //
  4978. //
  4979. UINT DomainRecordFindOrCreate(POM_PRIMARY pomPrimary,
  4980. UINT callID,
  4981. POM_DOMAIN * ppDomain);
  4982. //
  4983. //
  4984. // DomainDetach(...)
  4985. //
  4986. void DomainDetach(POM_PRIMARY pomPrimary, POM_DOMAIN * ppDomain, BOOL fExit);
  4987. //
  4988. //
  4989. // DeregisterLocalClient(...)
  4990. //
  4991. // This function is called by the ObMan task after the local client
  4992. // deregisters from a workset group. It causes this node's person object
  4993. // for the workset group to be deleted.
  4994. //
  4995. // If this node was the last node to be registered with the workset group,
  4996. // it also causes the relevant INFO object to be discarded.
  4997. //
  4998. // If this in turn causes the last workset group in the domain (which must
  4999. // be ObManControl) to be removed, ObMan is detached from the domain and
  5000. // the domain record becomes invalid. In this case, the ppDomain
  5001. // pointer passed in is nulled out.
  5002. //
  5003. //
  5004. void DeregisterLocalClient(POM_PRIMARY pomPrimary,
  5005. POM_DOMAIN * ppDomain,
  5006. POM_WSGROUP pWSGroup,
  5007. BOOL fExit);
  5008. //
  5009. //
  5010. // GetOMCWorksetPtr(...)
  5011. //
  5012. // This function derives a pointer to a specified workset in the
  5013. // ObManControl workset in the specified Domain.
  5014. //
  5015. //
  5016. UINT GetOMCWorksetPtr(POM_PRIMARY pomPrimary,
  5017. POM_DOMAIN pDomain,
  5018. OM_WORKSET_ID worksetID,
  5019. POM_WORKSET * ppWorkset);
  5020. //
  5021. //
  5022. // SayWelcome(...)
  5023. //
  5024. // This function is called
  5025. //
  5026. // - when the "top" ObMan finishes initalizing (the WELCOME is broadcast)
  5027. //
  5028. // - when ObMan receives an HELLO message from a late joiner (the WELCOME
  5029. // is sent to the late joiner)
  5030. //
  5031. //
  5032. UINT SayWelcome(POM_PRIMARY pomPrimary,
  5033. POM_DOMAIN pDomain,
  5034. NET_CHANNEL_ID channel);
  5035. //
  5036. //
  5037. // ProcessWelcome(...)
  5038. //
  5039. // Called when a WELCOME is received from another node. This may be in
  5040. // response to a HELLO, or it may be the "top" ObMan announcing the
  5041. // completion of its initialization.
  5042. //
  5043. // If this is the first WELCOME we've got for this Domain, we merge the
  5044. // capabilities and reply to the sender, asking for a copy of the
  5045. // ObManControl workset group.
  5046. //
  5047. //
  5048. UINT ProcessWelcome(POM_PRIMARY pomPrimary,
  5049. POM_DOMAIN pDomain,
  5050. POMNET_JOINER_PKT pWelcomePkt,
  5051. UINT lengthOfPkt);
  5052. //
  5053. //
  5054. // SayHello(...)
  5055. //
  5056. // Called when we join that domain and determine that we're not the "top"
  5057. // ObMan. We expect a WELCOME to come in response. We include our
  5058. // capabilities in the broadcast HELLO packet so that everyone knows what
  5059. // we support.
  5060. //
  5061. //
  5062. UINT SayHello(POM_PRIMARY pomPrimary,
  5063. POM_DOMAIN pDomain);
  5064. //
  5065. //
  5066. // ProcessHello(...)
  5067. //
  5068. // Called when we get a HELLO from another node. If we've completed our
  5069. // own initialization in the domain, we merge in that node's capabilities,
  5070. // then we respond with a WELCOME.
  5071. //
  5072. //
  5073. UINT ProcessHello(POM_PRIMARY pomPrimary,
  5074. POM_DOMAIN pDomain,
  5075. POMNET_JOINER_PKT pHelloPkt,
  5076. UINT lengthOfPkt);
  5077. //
  5078. //
  5079. // MergeCaps(...)
  5080. //
  5081. // Called by ProcessHello and ProcessWelcome to merge in capabilities
  5082. // received in the packet (which will be, respectively, a late joiner's
  5083. // capabilities or the domain-wide capabilities as determined by the sender
  5084. // of the WELCOME).
  5085. //
  5086. //
  5087. void MergeCaps(POM_DOMAIN pDomain,
  5088. POMNET_JOINER_PKT pJoinerPkt,
  5089. UINT lengthOfPkt);
  5090. //
  5091. //
  5092. // ProcessOwnDetach(...)
  5093. //
  5094. // This function is called when a NET_EV_DETACH_INDICATION is received for a
  5095. // user ID that matches our own. The function moves all of the workset
  5096. // groups for this Domain into ObMan's own "local" Domain.
  5097. //
  5098. //
  5099. UINT ProcessOwnDetach(POM_PRIMARY pomPrimary,
  5100. POM_DOMAIN pDomain);
  5101. //
  5102. //
  5103. // ProcessOtherDetach(...)
  5104. //
  5105. // This function is called when a NET_EV_DETACH_INDICATION is received for a
  5106. // user ID that doesn't match our own. The function examines each workset
  5107. // in the ObManControl workset group and deletes any registration objects
  5108. // that the departed node may have put there.
  5109. //
  5110. // If any local Clients have any of these worksets open, they are informed
  5111. // of the delete. However, OBEJCT_DELETE messages are not broadcast
  5112. // throughout the Domain, since each ObMan will do them locally.
  5113. //
  5114. //
  5115. UINT ProcessOtherDetach(POM_PRIMARY pomPrimary,
  5116. POM_DOMAIN pDomain,
  5117. NET_UID detachedUserID);
  5118. //
  5119. //
  5120. // WSGRegisterStage1(...)
  5121. //
  5122. // This function is ObMan's handler for the OMINT_EVENT_WSGROUP_REGISTER
  5123. // function. It is the first step in the chain of functions running in the
  5124. // ObMan context which are invoked during the workset group registration
  5125. // process (the OM_WSGroupRegisterReq, running in the Client context,
  5126. // posted the original OMINT_EVENT_WSGROUP_REGISTER event).
  5127. //
  5128. // This function ensures that we are fully attached to the Domain (if not,
  5129. // it starts the Domain attach procedure and reposts a delayed
  5130. // OMINT_EVENT_WSGROUP_REGISTER event) and then starts the process of locking
  5131. // workset #0 in the ObManControl workset group.
  5132. //
  5133. //
  5134. void WSGRegisterStage1(POM_PRIMARY pomPrimary,
  5135. POM_WSGROUP_REG_CB pRegistrationCB);
  5136. //
  5137. // ProcessOMCLockConfirm(...)
  5138. //
  5139. void ProcessOMCLockConfirm(POM_PRIMARY pomPrimary, OM_CORRELATOR cor, UINT result);
  5140. //
  5141. // ProcessCheckpoint(...)
  5142. //
  5143. void ProcessCheckpoint(POM_PRIMARY pomPrimary, OM_CORRELATOR cor, UINT result);
  5144. //
  5145. //
  5146. // WSGRegisterStage2(...)
  5147. //
  5148. // This function is called when we have successfully locked workset #0 in
  5149. // ObManControl.
  5150. //
  5151. // The function checks workset #0 in ObManControl to see if the workset
  5152. // group we're trying to register the Client with already exists in the
  5153. // Domain.
  5154. //
  5155. // If it does, it finds the channel number and requests to join the
  5156. // channel.
  5157. //
  5158. // If it doesn't, it requests to join a new channel and also calls
  5159. // WSGGetNewID to generate a new workset group ID (unique within the
  5160. // Domain).
  5161. //
  5162. //
  5163. void WSGRegisterStage2(POM_PRIMARY pomPrimary,
  5164. POM_WSGROUP_REG_CB pRegistrationCB);
  5165. //
  5166. //
  5167. // WSGGetNewID(...)
  5168. //
  5169. // This function is called by WSGRegisterStage2 to generate a new workset
  5170. // group ID, in the case where the workset group doesn't already exist.
  5171. //
  5172. // It also creates a new workset in ObManControl with the same ID as the ID
  5173. // just generated. This workset which will hold the registration objects
  5174. // for the new workset group
  5175. //
  5176. //
  5177. UINT WSGGetNewID(POM_PRIMARY pomPrimary,
  5178. POM_DOMAIN pDomain,
  5179. POM_WSGROUP_ID pWSGroupID);
  5180. //
  5181. //
  5182. // WSGRegisterStage3(...)
  5183. //
  5184. // This function is called by ProcessNetJoinChannel when a Join event
  5185. // arrives for a workset group channel.
  5186. //
  5187. // Depending on whether or not the workset was created in Stage2, the
  5188. // function calls WSGAnnounce (if it was) or WSGCatchUp (if it was not).
  5189. //
  5190. // It then unlocks the ObManControl workset and calls WSGRegisterResult.
  5191. //
  5192. //
  5193. void WSGRegisterStage3(POM_PRIMARY pomPrimary,
  5194. POM_DOMAIN pDomain,
  5195. POM_WSGROUP_REG_CB pRegistrationCB,
  5196. NET_CHANNEL_ID channelID);
  5197. //
  5198. //
  5199. // CreateAnnounce(...)
  5200. //
  5201. // This function is called by WSGRegisterStage3 after we have joined the
  5202. // channel for a new workset group.
  5203. //
  5204. // The function announces the new workset group throughout the Domain by
  5205. // adding an object containing the name, Function Profile, ObMan ID and MCS
  5206. // channel of the workset group to workset #0 in ObManControl.
  5207. //
  5208. // Note that this "announcement" cannot be made before the Join completes
  5209. // since we only learn the ID of the channel joined when we receive the
  5210. // Join event.
  5211. //
  5212. //
  5213. UINT CreateAnnounce(POM_PRIMARY pomPrimary,
  5214. POM_DOMAIN pDomain,
  5215. POM_WSGROUP pWSGroup);
  5216. //
  5217. //
  5218. // RegAnnounceBegin(...)
  5219. //
  5220. // This function adds a registration object to a workset in ObManControl.
  5221. // The workset is determined by the ID of the workset group identified by
  5222. // <pWSGroup>.
  5223. //
  5224. // This function is called
  5225. //
  5226. // - when ObMan creates a workset group
  5227. //
  5228. // - when ObMan receives a request to send a workset group to a late
  5229. // joiner.
  5230. //
  5231. // In the first case, the registration object identifies this node's use of
  5232. // the workset group. In the second case, the reg object identifies the
  5233. // late joiner's use of the workset group.
  5234. //
  5235. // The object ID returned is the ID of the reg object added.
  5236. //
  5237. //
  5238. UINT RegAnnounceBegin(POM_PRIMARY pomPrimary,
  5239. POM_DOMAIN pDomain,
  5240. POM_WSGROUP pWSGroup,
  5241. NET_UID nodeID,
  5242. POM_OBJECT * ppObjReg);
  5243. //
  5244. //
  5245. // RegAnnounceComplete(...)
  5246. //
  5247. // This function is called when we are fully caught up with a workset group
  5248. // we have joined, either because we have received the SEND_COMPLETE
  5249. // message or because we just created the group ourselves.
  5250. //
  5251. // The function updates the reg object specified by <regObjectID> by
  5252. // changing the <status> field to READY_TO_SEND.
  5253. //
  5254. //
  5255. UINT RegAnnounceComplete(POM_PRIMARY pomPrimary,
  5256. POM_DOMAIN pDomain,
  5257. POM_WSGROUP pWSGroup);
  5258. //
  5259. //
  5260. // WSGCatchUp(...)
  5261. //
  5262. // This function is called by Stage3 after we have joined the channel
  5263. // belonging to a workset group which already exists in the Domain.
  5264. //
  5265. // The function examines ObManControl to find the MCS ID of an instance of
  5266. // ObMan which claims to have a copy of this workset group, then sends it a
  5267. // request to transfer the workset group.
  5268. //
  5269. // The function also posts a delayed timeout event so we don't wait for
  5270. // ever to get a workset group from a particular node (this timeout is
  5271. // processed in ProcessWSGSendTimeout).
  5272. //
  5273. //
  5274. UINT WSGCatchUp(POM_PRIMARY pomPrimary,
  5275. POM_DOMAIN pDomain,
  5276. POM_WSGROUP pWSGroup);
  5277. //
  5278. //
  5279. // WSGRegisterResult(...)
  5280. //
  5281. // This function is called wherever any of the workset group registration
  5282. // functions have done enough processing to know the outcome of the
  5283. // registration attempt. If all is well, it will be called by Stage3 but
  5284. // it may also be called earlier if an error occurs.
  5285. //
  5286. // The function posts an OM_WSGROUP_REGISTER_CON event to the Clientn which
  5287. // initiated the workset group registration.
  5288. //
  5289. //
  5290. void WSGRegisterResult(POM_PRIMARY pomPrimary,
  5291. POM_WSGROUP_REG_CB pRegistrationCB,
  5292. UINT result);
  5293. //
  5294. //
  5295. // WSGRegisterRetry(...)
  5296. //
  5297. // This function is called wherever any of the workset group registration
  5298. // functions encounter a recoverable "error" situation, such as failing to
  5299. // get the ObManControl lock.
  5300. //
  5301. // This function checks if we've exceeded the retry count for this
  5302. // registration attempt and if not, reposts the OMINT_EVENT_WSGROUP_REGISTER
  5303. // event, so that the whole process is started again from Stage1.
  5304. //
  5305. // If we've run out of retries, WSGRegisterResult is invoked to post
  5306. // failure to the Client.
  5307. //
  5308. //
  5309. void WSGRegisterRetry(POM_PRIMARY pomPrimary,
  5310. POM_WSGROUP_REG_CB pRegistrationCB);
  5311. //
  5312. //
  5313. // ProcessSendReq(...)
  5314. //
  5315. // This function is called when an OMNET_WSGROUP_SEND_REQ message is
  5316. // received from another node (i.e. a late joiner)
  5317. //
  5318. // The function starts the process of sending the workset group contents to
  5319. // the late joiner.
  5320. //
  5321. //
  5322. void ProcessSendReq(POM_PRIMARY pomPrimary,
  5323. POM_DOMAIN pDomain,
  5324. POMNET_WSGROUP_SEND_PKT pSendReq);
  5325. //
  5326. //
  5327. // SendWSGToLateJoiner(...)
  5328. //
  5329. // This function is called when the checkpointing for a workset has
  5330. // completed. It sends the contents to the late joiner node.
  5331. //
  5332. //
  5333. void SendWSGToLateJoiner(POM_PRIMARY pomPrimary,
  5334. POM_DOMAIN pDomain,
  5335. POM_WSGROUP pWSGroup,
  5336. NET_UID lateJoiner,
  5337. OM_CORRELATOR remoteCorrelator);
  5338. //
  5339. //
  5340. // ProcessSendMidway(...)
  5341. //
  5342. // This function is called when an OMNET_WSGROUP_SEND_MIDWAY message is
  5343. // received from another node (the node which was helping us by sending us
  5344. // the contents of a workset group).
  5345. //
  5346. // We have now received all the WORKSET_CATCHUP messages (one for each
  5347. // workset). If all is well we inform the client that registration has
  5348. // been successful and set the workset group state to
  5349. // PENDING_SEND_COMPLETE.
  5350. //
  5351. //
  5352. void ProcessSendMidway(POM_PRIMARY pomPrimary,
  5353. POM_DOMAIN pDomain,
  5354. POMNET_WSGROUP_SEND_PKT pSendMidwayPkt);
  5355. //
  5356. //
  5357. // ProcessSendComplete(...)
  5358. //
  5359. // This function is called when an OMNET_WSGROUP_SEND_COMPLETE message is
  5360. // received from another node (the node which was helping us by sending us
  5361. // the contents of a workset group).
  5362. //
  5363. // If this message relates to the ObManControl workset group, we now have
  5364. // most of the ObManControl workset group (only "most" since there could be
  5365. // some recent objects still flying around).
  5366. //
  5367. // However, we do know that we have ALL the contents of workset #0 in
  5368. // ObManControl, since that workset is only ever altered under lock.
  5369. //
  5370. // Accordingly, we now consider ourselves to be fully-fledged members of
  5371. // the Domain, in the sense that we can correctly process our Clients
  5372. // requests to register with workset groups.
  5373. //
  5374. // If the message relates to another workset group, we now have enough of
  5375. // its contents to consider ourselves eligible to help other late joiners
  5376. // (as we have just been). Therefore, we announce this eligibilty
  5377. // throughout the Domain (using the ObManControl workset group).
  5378. //
  5379. //
  5380. UINT ProcessSendComplete(
  5381. POM_PRIMARY pomPrimary,
  5382. POM_DOMAIN pDomain,
  5383. POMNET_WSGROUP_SEND_PKT pSendCompletePkt);
  5384. //
  5385. //
  5386. // MaybeRetryCatchUp(...)
  5387. //
  5388. // This function is called on receipt of a DETACH indication from MCS or a
  5389. // SEND_DENY message from another node. In both cases we compare the
  5390. // helperNode field in OM_WSGROUP structure with the userID and if they
  5391. // match then we retry the catch up.
  5392. //
  5393. // Depending on the workset group status we do the following:
  5394. //
  5395. // PENDING_SEND_MIDWAY : Retry the registration from the top.
  5396. // PENDING_SEND_COMPLETE : Just repeat the catch up.
  5397. //
  5398. // If there is no one to catch up from then we do the following depending
  5399. // on the workset group status:
  5400. //
  5401. // PENDING_SEND_MIDWAY : Retry the registration from the top. Regardless
  5402. // of whether someone else is out there or not (they cannot be in the
  5403. // READY_TO_SEND state) we will end up in a consistent state.
  5404. //
  5405. // PENDING_SEND_COMPLETE : If two (or more) nodes are in this state and
  5406. // catching up from the same box who then leaves, they will have two
  5407. // partial sets of objects one of which may or may not be a subset of the
  5408. // other. If there is no one else in the READY_TO_SEND state then each
  5409. // node needs to obtain a copy of all the objects in a given workset at the
  5410. // other node.
  5411. //
  5412. //
  5413. void MaybeRetryCatchUp(POM_PRIMARY pomPrimary,
  5414. POM_DOMAIN pDomain,
  5415. OM_WSGROUP_ID wsGroupID,
  5416. NET_UID userID);
  5417. //
  5418. //
  5419. // IssueSendDeny(...)
  5420. //
  5421. // This function issues a SEND_DENY message to a remote node.
  5422. //
  5423. //
  5424. void IssueSendDeny(POM_PRIMARY pomPrimary,
  5425. POM_DOMAIN pDomain,
  5426. OM_WSGROUP_ID wsGroupID,
  5427. NET_UID sender,
  5428. OM_CORRELATOR remoteCorrelator);
  5429. //
  5430. //
  5431. // WSGRecordMove(...)
  5432. //
  5433. // This function moves the record for specified workset group from one
  5434. // Domain record to another, and posts events to all relevant Clients. If
  5435. // does not check for name contention in the destination Domain.
  5436. //
  5437. //
  5438. void WSGRecordMove(POM_PRIMARY pomPrimary,
  5439. POM_DOMAIN pDestDomainRec,
  5440. POM_WSGROUP pWSGroup);
  5441. //
  5442. //
  5443. // WSGMove(...)
  5444. //
  5445. // This function moves the record for specified workset group from one
  5446. // Domain record to another, and posts events to all relevant Clients. If
  5447. // does not check for name contention in the destination Domain.
  5448. //
  5449. //
  5450. UINT WSGMove(POM_PRIMARY pomPrimary,
  5451. POM_DOMAIN pDestDomainRec,
  5452. POM_WSGROUP pWSGroup);
  5453. //
  5454. //
  5455. // DomainAttach(...)
  5456. //
  5457. // This function calls MG_AttachUser to start the process of attaching to
  5458. // a Domain. It also allocates and initialises the local structures
  5459. // associated with the Domain (the Domain record).
  5460. //
  5461. // A pointer to the newly-created Domain record is returned.
  5462. //
  5463. //
  5464. UINT DomainAttach(POM_PRIMARY pomPrimary,
  5465. UINT callID,
  5466. POM_DOMAIN * ppDomainord);
  5467. //
  5468. //
  5469. // WSGRecordFindOrCreate(...)
  5470. //
  5471. // This function searches the workset group list in the specified Domain
  5472. // record for a workset group record whose name and FP match the ones
  5473. // specified. If none is found, a new workset group record is allocated,
  5474. // initialised and inserted into the list.
  5475. //
  5476. // A pointer to the found-or-created workset group record is returned.
  5477. //
  5478. // NOTE: This function does not cause ObMan to join the workset group
  5479. // channel or copy the workset group from another node if it
  5480. // exists elsewhere; it merely creates the local structures for
  5481. // the workset group.
  5482. //
  5483. //
  5484. UINT WSGRecordFindOrCreate(POM_PRIMARY pomPrimary,
  5485. POM_DOMAIN pDomain,
  5486. OMWSG wsg,
  5487. OMFP fpHandler,
  5488. POM_WSGROUP * ppWSGroup);
  5489. //
  5490. //
  5491. // ProcessSendQueue(...)
  5492. //
  5493. // This function prompts ObMan to examine the send queues for the specified
  5494. // Domain. If there are any messages queued for sending (including remains
  5495. // of messages which have been partly sent), ObMan will try to send more
  5496. // data. ObMan stops when either the send queues are all empty or the
  5497. // network layer has stopped giving us memory.
  5498. //
  5499. // The <domainRecBumped> flag indicates whether the Domain record has had
  5500. // its use count bumped; if TRUE, then this function calls UT_SubFreeShared
  5501. // to decrement the use count.
  5502. //
  5503. //
  5504. void ProcessSendQueue(POM_PRIMARY pomPrimary,
  5505. POM_DOMAIN pDomain,
  5506. BOOL domainRecBumped);
  5507. //
  5508. // ProcessWSGDiscard(...)
  5509. //
  5510. void ProcessWSGDiscard(POM_PRIMARY pomPrimary, POM_WSGROUP pWSGroup);
  5511. //
  5512. // ProcessWSGMove(...)
  5513. //
  5514. UINT ProcessWSGMove(POM_PRIMARY pomPrimary, long moveCBOffset);
  5515. //
  5516. // ProcessNetTokenGrab(...)
  5517. //
  5518. UINT ProcessNetTokenGrab(POM_PRIMARY pomPrimary,
  5519. POM_DOMAIN pDomain,
  5520. NET_RESULT result);
  5521. //
  5522. // ProcessCMSTokenAssign(...)
  5523. //
  5524. void ProcessCMSTokenAssign(POM_PRIMARY pomPrimary,
  5525. POM_DOMAIN pDomain,
  5526. BOOL success,
  5527. NET_TOKEN_ID tokenID);
  5528. //
  5529. // ProcessNetTokenInhibit(...)
  5530. //
  5531. UINT ProcessNetTokenInhibit(POM_PRIMARY pomPrimary,
  5532. POM_DOMAIN pDomain,
  5533. NET_RESULT result);
  5534. //
  5535. // CreateObManControl(...)
  5536. //
  5537. UINT ObManControlInit(POM_PRIMARY pomPrimary,
  5538. POM_DOMAIN pDomain);
  5539. //
  5540. // WSGDiscard(...)
  5541. //
  5542. void WSGDiscard(POM_PRIMARY pomPrimary,
  5543. POM_DOMAIN pDomain,
  5544. POM_WSGROUP pWSGroup,
  5545. BOOL fExit);
  5546. //
  5547. // IssueSendReq(...)
  5548. //
  5549. UINT IssueSendReq(POM_PRIMARY pomPrimary,
  5550. POM_DOMAIN pDomain,
  5551. POM_WSGROUP pWSGroup,
  5552. NET_UID remoteNode);
  5553. //
  5554. // GenerateUnlockMessage(...)
  5555. //
  5556. UINT GenerateUnlockMessage(POM_PRIMARY pomPrimary,
  5557. POM_DOMAIN pDomain,
  5558. OM_WSGROUP_ID wsGroupID,
  5559. OM_WORKSET_ID worksetID,
  5560. POMNET_LOCK_PKT * ppUnlockPkt);
  5561. //
  5562. // ProcessWSGRegister(...)
  5563. //
  5564. void ProcessWSGRegister(POM_PRIMARY pomPrimary, POM_WSGROUP_REG_CB pRegCB);
  5565. //
  5566. // LockObManControl(...)
  5567. //
  5568. void LockObManControl(POM_PRIMARY pomPrimary,
  5569. POM_DOMAIN pDomain,
  5570. OM_CORRELATOR * pLockCorrelator);
  5571. //
  5572. //
  5573. // MaybeUnlockObManControl(...)
  5574. //
  5575. // If the LOCKED_OMC flag is set in the registration CB, then unlock the
  5576. // Obman Control workset and clear the LOCKED_OMC flag.
  5577. //
  5578. //
  5579. void MaybeUnlockObManControl(POM_PRIMARY pomPrimary,
  5580. POM_WSGROUP_REG_CB pRegistrationCB);
  5581. //
  5582. // WSGRecordCreate(...)
  5583. //
  5584. UINT WSGRecordCreate(POM_PRIMARY pomPrimary,
  5585. POM_DOMAIN pDomain,
  5586. OMWSG wsg,
  5587. OMFP fpHandler,
  5588. POM_WSGROUP * ppWSGroup);
  5589. //
  5590. //
  5591. // WorksetDiscard(...)
  5592. //
  5593. // This function is called by WSGDiscard to discard the individual worksets
  5594. // of a workset group when the last local Client deregisters. It discards
  5595. // the contents of the workset, frees the workset record itself and clears
  5596. // the worksets's entry in the workset group record.
  5597. //
  5598. // It is not called when a workset is closed, since closing a workset does
  5599. // not discard its contents.
  5600. //
  5601. //
  5602. void WorksetDiscard(POM_WSGROUP pWSGroup, POM_WORKSET * pWorkset, BOOL fExit);
  5603. //
  5604. // ProcessLockNotify(...)
  5605. //
  5606. void ProcessLockNotify(POM_PRIMARY pomPrimary,
  5607. POM_DOMAIN pDomain,
  5608. POM_WSGROUP pWSGroup,
  5609. POM_WORKSET pWorkset,
  5610. NET_UID owner);
  5611. //
  5612. // SendMessagePkt(...)
  5613. //
  5614. UINT SendMessagePkt(POM_PRIMARY pomPrimary,
  5615. POM_DOMAIN pDomain,
  5616. POM_SEND_INST pSendInst);
  5617. //
  5618. // SendMoreData(...)
  5619. //
  5620. UINT SendMoreData(POM_PRIMARY pomPrimary,
  5621. POM_DOMAIN pDomain,
  5622. POM_SEND_INST pSendInst);
  5623. //
  5624. // StartReceive(...)
  5625. //
  5626. UINT StartReceive(POM_PRIMARY pomPrimary,
  5627. POM_DOMAIN pDomain,
  5628. POMNET_OPERATION_PKT pHeaderPkt,
  5629. POM_WSGROUP pWSGroup,
  5630. POM_WORKSET pWorkset,
  5631. POM_OBJECT pObj);
  5632. //
  5633. // ProcessMessage(...)
  5634. //
  5635. // This function takes a receive control block (generated by ReceiveData)
  5636. // and tries to process it as an ObMan message. If the message can not be
  5637. // processed at this time, it is put on the bounce list. If the message is
  5638. // an "enabling" message (one which might enable previously bounced
  5639. // messages to be processed now) the bounce queue is flushed.
  5640. //
  5641. // Since this function is also called to process bounced messages, and
  5642. // since we want to prevent deep recursion as one bounced "enabling"
  5643. // message prompts re-examination of the bounce queue etc., we use the
  5644. // <whatNext> parameter to determine whether the bounce list should be
  5645. // examined.
  5646. //
  5647. //
  5648. UINT ProcessMessage(POM_PRIMARY pomPrimary,
  5649. POM_RECEIVE_CB pReceiveCB,
  5650. UINT whatNext);
  5651. #define OK_TO_RETRY_BOUNCE_LIST 1
  5652. #define DONT_RETRY_BOUNCE_LIST 2
  5653. //
  5654. // ReceiveData(...)
  5655. //
  5656. UINT ReceiveData(POM_PRIMARY pomPrimary,
  5657. POM_DOMAIN pDomain,
  5658. PNET_SEND_IND_EVENT pNetSendInd,
  5659. POMNET_OPERATION_PKT pNetMessage);
  5660. //
  5661. // TryToSpoilOp
  5662. //
  5663. UINT TryToSpoilOp(POM_SEND_INST pSendInst);
  5664. //
  5665. // DecideTransferSize(...)
  5666. //
  5667. void DecideTransferSize(POM_SEND_INST pSendInst,
  5668. UINT * pTransferSize,
  5669. UINT * pDataTransferSize);
  5670. //
  5671. // CreateReceiveCB(...)
  5672. //
  5673. UINT CreateReceiveCB(POM_DOMAIN pDomain,
  5674. PNET_SEND_IND_EVENT pNetSendInd,
  5675. POMNET_OPERATION_PKT pNetMessage,
  5676. POM_RECEIVE_CB * ppReceiveCB);
  5677. //
  5678. // FindReceiveCB(...)
  5679. //
  5680. UINT FindReceiveCB(POM_DOMAIN pDomain,
  5681. PNET_SEND_IND_EVENT pNetSendInd,
  5682. POMNET_OPERATION_PKT pDataPkt,
  5683. POM_RECEIVE_CB * ppReceiveCB);
  5684. //
  5685. // WSGRegisterAbort(...)
  5686. //
  5687. void WSGRegisterAbort(POM_PRIMARY pomPrimary,
  5688. POM_DOMAIN pDomain,
  5689. POM_WSGROUP_REG_CB pRegistrationCB);
  5690. //
  5691. //
  5692. // BounceMessage(...)
  5693. //
  5694. // cmf
  5695. //
  5696. //
  5697. void BounceMessage(POM_DOMAIN pDomain,
  5698. POM_RECEIVE_CB pReceiveCB);
  5699. //
  5700. //
  5701. // NewDomainRecord(...)
  5702. //
  5703. //
  5704. UINT NewDomainRecord(POM_PRIMARY pomPrimary, UINT callID, POM_DOMAIN * ppDomain);
  5705. void FreeDomainRecord(POM_DOMAIN * ppDomain);
  5706. //
  5707. // ProcessBouncedMessages(...)
  5708. //
  5709. void ProcessBouncedMessages(POM_PRIMARY pomPrimary,
  5710. POM_DOMAIN pDomain);
  5711. void WSGResetBytesUnacked(POM_WSGROUP pWSGroup);
  5712. //
  5713. // NewHelperCB()
  5714. // FreeHelperCB()
  5715. //
  5716. BOOL NewHelperCB(POM_DOMAIN pDomain,
  5717. POM_WSGROUP pWSGroup,
  5718. NET_UID lateJoiner,
  5719. OM_CORRELATOR remoteCorrelator,
  5720. POM_HELPER_CB * ppHelperCB);
  5721. void FreeHelperCB(POM_HELPER_CB * ppHelperCB);
  5722. void PurgePendingOps(POM_WORKSET pWorkset, POM_OBJECT pObj);
  5723. OMFP OMMapNameToFP(LPCSTR szName);
  5724. LPCSTR OMMapFPToName(OMFP fp);
  5725. OMWSG OMMapNameToWSG(LPCSTR szName);
  5726. LPCSTR OMMapWSGToName(OMWSG wsg);
  5727. #endif // _H_OM
  5728.