Spread 3.17.3 C API

SP_receive
 
int SP_receive (mailbox mbox, service *service_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 SP_scat_receive (mailbox mbox, service *service_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);

   


Parameters
  mbox connection handle to receive on
  service_type specifies the service type the message was sent under
  sender sender of the message
  max_groups size of the groups array
  num_groups number of groups message was sent to
  groups array of groups that the message was sent to
  mess_type message type field the sender application sent with the original message
  endian_mismatch endian difference between sender and receiving computers
  max_mess_len max size of message buffer
  mess message body
  scatt_mess message body in scatter structure


Return Values
  >= 0 Success.(Size of the message received)
  ILLEGAL_SESSION The mbox given to receive on was illegal.
  ILLEGAL_MESSAGE The message had an illegal structure, like a scatter not filled out correctly.
  CONNECTION_CLOSED During communication to receive the message communication errors occurred and the receive could not be completed.
  GROUPS_TOO_SHORT If the groups array is too short to hold the entire list of groups this message was sent to then this error is returned and the num_groups field will be set to the negative of the number of groups needed.
  BUFFER_TOO_SHORT If the message body buffer mess is too short to hold the message being received then this error is returned and the endian_mismatch field is set to the negative value of the required buffer length.


Description
 

SP_receive is the general purpose receive function for the toolkit. This receives not only data messages but also membership messages for the connection. Messages for all groups joined on this connection will arrive to the same mailbox so a call to SP_receive will get a single 'message' from any one of the groups. After the receive completes a number of fields are set to values indicating meta information about the message (such as groups, mess_type, endianness, type, etc).

This function is the most complex used in Spread because it is the only way for the system to return information to the application. The meaning of many of the fields changes depending on whether the message is a data message or a membership message.

The SP_receive function will block if no messages are available.

The following INPUT parameters should be used when calling SP_receive:

mbox spread connection handle receiving on
service_type 0 or DROP_RECV (see below)
sender pointer to an array of characters of at least MAX_GROUP_NAME size
max_groups maximum number of groups you have allocated space for in the 'groups' array
groups user buffer holds upto max_groups group names, each of which is a string of at most MAX_GROUP_NAME characters
mess_type 0
endian_mismatch 0
max_mess_len maximim number of groups you have allocated space for in mess or scat_mess
mess user buffer of up to max_mess_len in size
scat_mess user scatter structure, with total size up to max_mess_len

service_type
Service_type is a pointer to a variable of type 'service' which will be set to the message type of the message just received. The service type will be either a REG_MESSAGE or MEMBERSHIP_MESS, and the specific type. You can use the message type access functions to help determine which types the service type holds.

The variable that service_type points to is also an input parameter and should be set to either 0, for normal semantics, or DROP_RECV (a defined constant) if you want to receive the 'non-reliable' semantics that will truncate messages if the provided buffers for message data and group lists are too small. More information about DROP_RECV semantics are provided below.

The rest of the parameters differ in meaning depending on the service_type.

Output Parameters vs. Service Type
regular message
transitional membership
membership message
self leave
service_type
REG_MESSAGE
MEMB_MESS & MEMB_MESS & MEMB_MESS &
REG_MEMB_MESS & NOT REG_MEMB_MESS &
TRANS_MESS One of: CAUSED_BY_JOIN or CAUSED_BY_LEAVE or CAUSED_BY_DISCONNECT or CAUSED_BY_NETWORK CAUSED_BY_LEAVE
sender
sender group of memb event group of membership event group of memb event
max_groups
max groups array size N/A
N/A
N/A
num_groups
num groups sent to OR 0 group size after membership event
0
negative num groups of message if groups too small
groups
groups message sent to  N/A members of the group after the membership event N/A
mess_type
specified by app on send N/A  index of current process in group array  0
endian_mismatch endian mismatch if any with sender OR N/A  0  0
if BUFFER_TOO_SHORT error set to negative of incoming message size
max_mess_len
message body length N/A N/A N/A
mess group ID
message body N/A unique identifier of the new membership "view" N/A
num_vs_members
vs_set size 1
vs_set
JOIN private group of the joining process private group of self leaving process
LEAVE private group of the leaving process
DISCONNECT private group of the disconnecting process
NETWORK private group names of processes which came with you from the old into this new membership
scatt_mess
same as mess N/A same as mess same as mess

If the service_type is a REG_MESSAGE (i.e. data message) then:

The sender is a pointer to an array of characters of at least MAX_GROUP_NAME size. This will be set to the name of the sending connection (its private group name).

The max_groups is the maximum number of groups you have allocated space for in the 'groups' array passed to the receive function.

Num_groups is a pointer to an int which will be set to the number of groups set in the 'groups' array.

The groups array holds up to max_groups group names, each of which is a string of at most MAX_GROUP_NAME characters. All of the groups which are receiving this message will be listed here, unless the array is too small (GROUPS_TOO_SHORT return code) and then as many as can fit will be listed and the num_groups value will be set to be negative. For example, if your groups array could store 5 group names, but a message for 7 groups arrived, the first five group names would appear in the groups array and num_groups would be set to -7. You can then recall this function with the correct groups array size to get all the groups and the message.

The mess_type field will be set to the message type field the application sent with the original message, this is only a short int (16bits). This value is already endian corrected before the application receives it.

Endian_mismatch will be set to true (1) if the endianness of the sending machine differs from that of this receiving machine. If the BUFFER_TOO_SHORT error is returned then the endian_mismatch field will be set to the size of the incoming message as a negative value. So if the message requires 300 bytes of buffer space and only 200 bytes was provided in the mess buffer, endian_mismatch will be set to -300.

The actual message body being received will be passed into the buffer given by mess which is at least max_mess_len bytes in size. If the message being received is larger then this buffer the default behavior will be to return a BUFFER_TOO_SHORT error and provide the required length in the endian_mismatch field. If the DROP_RECV flag was passed in the service_type field, then as much data as possible will be returned and the extra data will be discarded by the system and the return value of SP_receive will indicate an error. If the SP_scat_receive form is used then instead of the mess buffer and length fields, a single scat_mess scatter structure should be passed to receive filled in with whatever buffers you wish to receive into and their lengths. These buffers must be valid memory areas. They will be filled in by the receive call in the order they are listed.

During a BUFFER_TOO_SHORT or GROUPS_TOO_SHORT condition, both array sizes will be checked and the appropriate values filled in IF the either buffer is too short. If one of the buffers is sufficiently sized, its corresponding size requirement field will be set to 0. For example, if the groups array is too short, but the mess buffer was sufficient, then the endian_mismatch will be set to 0 indicating the mess array was sufficiently sized. Likewise, if the mess array was too short, but the groups array was sufficient, then num_groups will be set to 0.


If this is a MEMB_MESSAGE (i.e. membership message) and it specifically is a TRANS_MESS, then:

The sender char array will be set to the name of the group for which the membership change is occuring.

The max_groups and max_mess_len fields are not used and the num_groups is 0 and groups since there are no normal groups for a transitional membership, the sender field is used instead. The mess_type field is set to -1. The endian_mismatch field will be zero since the transitional does not have any endian issues. The mess field will be left empty. So in essence the only information you get is the sender field is set to the group name which received a transitional membership change. The importance of the TRANS_MEMB_MESS is that it tells the application that all messages received after it and before the REG_MEMB_MESS for the same group are 'clean up' messages to put the messages in a consistent state before actually changing memberships. For more explanations of this please see other documentation and research papers.


If This is a MEMB_MESSAGE (i.e. membership message) and it specifically is a REG_MEMB_MESS, then:

The sender char array will be set to the name of the group for which the membership change is occurring.

The max_groups and max_mess_len fields have the same meaning as before, and the mess_type field will be set to the index of this process in the array of group members. The endian_mismatch field will again be set to 0 since there are no endian issues with regular memberships.

The groups array and mess body are used to provide two kinds of membership information about the change that just occurred 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 occurred). Correspondingly the groups array will be set to 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 recipients 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 and provides a list of all the private group names of those processes which came with your process from the old group membership into this new membership. The data buffer will include the following fields:

group_id;

int num_vs_members;

char vs_set[][MAX_GROUP_NAME];
The location of the beginning of each field is provided by the accessor functions SP_get_gid_offset_memb_mess, SP_get_num_vs_offset_memb_mess, and SP_get_vs_set_offset_memb_mess. Each accessor function gives the byte offset in the message body of the corresponding field.

The vs_set array will have num_vs_members group names, each of which is a fixed length string. The content of the vs_set array is dependent upon the type of the membership change:

CAUSED_BY_JOIN Vs_set contains the private group of the joining process.
CAUSED_BY_LEAVE Vs_set contains the private group of the leaving process.
CAUSED_BY_DISCONNECT Vs_set contains the private group of the disconnecting process.
CAUSED_BY_NETWORK Vs_set contains the group names of the members of the new membership who came with me (the current process) to the new membership. Of course, all new members can be determined by comparing it with the groups parameter of the SP_receive call.

If this is a MEMB_MESSAGE (i.e. membership message) and it is neither a REG_MEMB_MESS or a TRANS_MEMB_MESS, then:

I t represents exactly the situation where the member receiving this message has left a group and this is notification that the leave has occurred, 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 then it is a self-leave message. TRANS_MEMB_MESS never have a CAUSED_BY_ type because they only serve to signal up to where SAVE delivery and AGREED delivery (with no holes) is guaranteed in the complete old group membership.

The other members of the group this member just left will receive a normal TRANS_MEMB_MESS, REG_MEMB_MESS pair as described above showing the membership change.

The fields of SP_receive in this case will be as follows:

  • sender char array will be set to the name of the group for which the membership change is occurring.
  • max_groups and max_mess_len fields have the same meaning as before
  • mess_type and endian_mismatch fields will be set to 0.
  • num_groups field will be set to 0
  • groups array will be empty, since this member is no longer part of the group

The message body provides a the private group name of the member who just left, which should always be the private group name of the connection which received this message. The private group name can be accessed at a byte offset from the beginning of the buffer given by the SP_get_vs_set_offset_memb_mess function. The name will consist of one fixed length string of MAX_GROUP_NAME size.



Requirements
  Header: Include sp.h
Library: Use libspread or libtspread
Version: 3.17.3


Also See
  SP_multicast, SP_get_gid_offset_memb_mess, SP_get_num_vs_offset_memb_mess, SP_get_vs_set_offset_memb_mess