int FL_receive(mailbox mbox, service *serv_type, char sender[MAX_GROUP_NAME], int max_groups, int *num_groups, char groups[][MAX_GROUP_NAME], int16 *mess_type, int *endian_mismatch, int max_mess_len, char *mess, int *more_messes);
int FL_scat_receive(mailbox mbox, service *serv_type, char sender[MAX_GROUP_NAME], int max_groups, int *num_groups, char groups[][MAX_GROUP_NAME], int16 *mess_type, int *endian_mismatch, scatter *scat_mess, int *more_messes);
After a call to receive completes, a number of the passed fields are set to values indicating meta-information about the message (such as destination group, message type, endianness, etc). The meanings of these different meta fields depends on the type of message received and the receipt services requested.
Input Parameters:
Receive Semantics:
Normally, a call to receive will block if no messages are immediately available.
Normally, when calling a receive function if a user's buffer (groups, mess, or scat_mess) is too small to contain the data to be returned, then a GROUPS_TOO_SHORT or BUFFER_TOO_SHORT error code will be returned. In this case, the serv_type, and mess_type of the message are filled in from the offending message and the parameters num_groups, and endian_mismatch reflect information about the necessary buffers' sizes. If max_groups was big enough, then *num_groups will be zero, otherwise it will be the negative of how many group names are available to be received (i.e. -7 means the max_groups was less than 7 and 7 group names can be received). If max_mess_len or scat_mess was big enough then *endian_mismatch will be zero, otherwise it will be the negative of how much data is available to be received (i.e. -32768 means the msg buffer was too small and 32768 bytes of data can be received). The offending message is still available to be received through later calls to receive with appropriately sized user buffers.
The parameter serv_type allows the applications to request different receive services that affect the normal semantics of receive. Currently, the only services are DONT_BLOCK and DROP_RECV.
The DONT_BLOCK service makes a receive call non-blocking. With this service, the receive call will return quickly either with a message or with the error code WOULD_BLOCK if no message is available. Using this service is the only way to detect if a message is ready on the connection in a non-blocking manner in Flush Spread.
The DROP_RECV service forces Flush Spread to read the current message off of the connection regardless of whether or not the user's buffers are big enough to fit all of the data. In this case, a TOO_SHORT error code is still returned even though the call actually succeeded. Anyway, as much data as can be fit into the user's buffers will be stuffed into them, and that message will no longer be on the connection. Also, *num_groups will still be set to the negative size of how many names were available (if groups wasn't big enough), but *endian_mismatch will not reflect the size of the data that could have been received (if mess or scat_mess wasn't big enough), instead it indicates whether or not the sending machine had an opposite endianness or not. Using DROP_RECV in this manner, when a buffer problem occurs there is no way to determine how big the data portion of the message actually was. This service is meant to be used when a call to receive without DROP_RECV fails with a buffer error, but it is determined that the message isn't all that important, or something along those lines; otherwise reallocate your receive buffers appropriately and re-call receive again without the DROP_RECV service.
Output Parameters:
Upon a successful return from receive, *serv_type will be filled out with the message type that was just received. The specific type of message received can be tested using the different message and membership type access macros. The rest of the parameters' meanings differ depending on the serv_type.
Regular Messages:
If the serv_type is a REG_MESSAGE (i.e. a data message) then:
The parameter sender will be filled with the private group name of the sending connection.
The parameter num_groups will be set to the number of group names filled into groups.
The groups array will contain the group to which this message was sent. If the message is a SUBGROUP_CAST (check the service type, see FL_multicast) then all of the recipients' private group names will be listed and the last name in the array (i.e. groups[*num_groups-1]) will be the regular group to which this message was sent.
If DROP_RECV is being used, and groups is too small, then as many names as can fit will be filled in as above described. If the message was a SUBGROUP_CAST, then the last group in the array (i.e. groups[max_groups-1]) will be the destination group for the message. If max_groups is zero then even the destination group is not reported.
The parameter *mess_type will be set to the message type field the application sent with the original message, which is a restricted (see FL_multicast) 16 bit integer. This value is endian corrected upon returning.
The parameter *endian_mismatch will be set to true (non-zero) if the endianness of the sending machine is the opposite of this receiving machine's.
The actual message body being received will be filled into either the mess or scat_mess parameter.
Flush Request Message:
If this is a FLUSH_REQ_MESS then this represents that the underlying membership has changed and that this application needs to flush this group before the new view/membership can be installed (see FL_flush).
The sender will be filled in with the name of the group this connection needs to flush. All the other fields are set to empty values.
Membership Messages:
If this is a MEMB_MESSAGE (i.e. membership message) and it specifically is a REG_MEMB_MESS, then:
The sender will be filled with the name of the group for which the membership change is occuring.
The mess_type field will be set to the index of this process in the groups array (see below).
The endian_mismatch field will be set to 0 since there are no endian issues with regular memberships.
The groups array and message body are used to provide two kinds of membership information about the change that just occured in this group. The num_groups field will be set to the number of members in the group in the new membership (i.e. after the change occured). Correspondingly, the groups array will be filled in with the private group names of all members of this group in the new membership. This list of names is always in the same order at all receipients and thus can be used to deterministically pick a group representative if one is needed by the application.
The second set of information is stored in the message body. The data buffer will include the following fields:
The vid and num_members parameters will already be endian corrected. The dgroups array will contain num_members group names. The functions FL_get_gid_offset_memb_mess(), FL_get_num_vs_offset_memb_mess() and FL_get_vs_set_offset_memb_mess() provide the offsets to the associated fields within the body of a membership message. The content of the dgroups array is dependent upon the type of the membership change:
Transitional Message:
If this is a MEMB_MESSAGE and specifically it is a TRANSITION_MESS, then this means that one or more of the current members of the group has left and not all of the safety guarantees can be met w.r.t. all of the original members for the messages delivered after this signal and before the next view/membership. Transitional messages never have a CAUSED_BY type because they only serve to signal up to where SAFE delivery and AGREED delivery (with no holes) is guaranteed in the view/membership in which they are delivered. Only one TRANSITION_MESS is delivered per group view/membership per connection.
The sender will be filled in with the name of the group for which the membership change is occurring. All the other parameters will be set to empty values.
Self-Leave Message:
If this is a MEMB_MESSAGE (i.e. membership message) and it is neither a REG_MEMB_MESS or a TRANSITION_MESS, then it represents exactly the situtation where the member receiving this message has left a group and this is notification that the leave has occured, thus it is sometimes called a self-leave message. The simplest test for this is if a message is CAUSED_BY_LEAVE and REG_MEMB_MESS is false (zero), then it is a self-leave message.
The other members of the group that this member just left will receive a normal TRANSITION_MESS, REG_MEMB_MESS pair as described above showing this connection leaving.
For self-leave messages the sender field will be filled in with the name of the group this connection is leaving. All the other fields are set to empty values.