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.
|