/**************************************************************/ private Message RecvView(Member m) { View view = new View(); Message msg = new Message(); view.nmembers = ReadInt (); view.version = ReadString (ENS_VERSION_MAX_SIZE); view.group = ReadString(ENS_GROUP_NAME_MAX_SIZE); view.proto = ReadString(ENS_PROTOCOL_MAX_SIZE); view.ltime = ReadInt (); view.primary = ReadBool (); view.parameters=ReadString (ENS_PARAMS_MAX_SIZE); view.address = ReadAddrArray (); view.view = ReadEndptArray (); view.endpt = ReadEndpt (); view.addr= ReadString(ENS_ADDR_MAX_SIZE); view.rank = ReadInt (); view.name = ReadString(ENS_NAME_MAX_SIZE); view.view_id = ReadViewId(); // The group is unblocked now. m.current_status=Member.Status.Normal; m.current_view = view; msg.mtype = UpType.VIEW; msg.view = view; return msg; }
private void WriteHdr(Member m, DnType type) { WriteInt(m.id); WriteInt((int)type); }
private Message RecvExit(Member m) { Message msg = new Message (); if (!(Member.Status.Leaving == m.current_status)) throw new EnsembleException("CbExit: mbr state is not leaving"); msg.mtype = UpType.EXIT; /* Remove the context from the hashtable, we shall no longer deliver * messages to it */ ContextRemove(m); // Tell members that this member is no longer valid m.current_status = Member.Status.Left; return msg; }
private Message RecvSend(Member m) { int origin ; byte[] data; Message msg = new Message (); origin = ReadInt(); data = ReadData(); // assert(origin < s->nmembers) ; msg.mtype= UpType.SEND; msg.origin = origin; msg.data = data; return msg; }
/* Release a context descriptor. */ private void ContextRemove(Member m) { memb_ctx_tbl.Remove(m); }
private Message RecvBlock(Member m) { Message msg = new Message (); msg.mtype = UpType.BLOCK; return msg; }
// Report group members as failure-suspected. internal void Suspect(Member m, int[] suspects) { int i; if (suspects.Length > ENS_DESTS_MAX_SIZE) throw new EnsembleException ("Suspecting more than" + ENS_DESTS_MAX_SIZE + "endpoints"); lock(send_mutex) { CheckValid(m); WriteBegin(); WriteHdr(m,DnType.DN_SUSPECT); WriteInt(suspects.Length); for (i=0; i<suspects.Length; i++) { if (suspects[i] < 0 || suspects[i] > m.current_view.nmembers) throw new EnsembleException("Suspition out of bounds"); WriteInt(suspects[i]); } WriteEnd(); } }
/************************ User Downcalls ****************************/ // Check that the member is in a Normal status private void CheckValid(Member m) { switch (m.current_status) { case Member.Status.Normal: break; default: throw new EnsembleException("Operation while group is " + m.current_status.ToString() + "gid=" + m.id); } }
// Send a point-to-point message to a list of members. internal void Send(Member m, int[] dests, byte[] data) { int i; if (dests.Length > ENS_DESTS_MAX_SIZE) throw new EnsembleException ("Send to more than" + ENS_DESTS_MAX_SIZE + "destinations"); lock(send_mutex) { CheckValid(m); WriteBegin(); WriteHdr(m,DnType.DN_SEND); WriteInt(dests.Length); for (i=0; i<dests.Length; i++) { if (dests[i] < 0 || dests[i] > m.current_view.nmembers) throw new EnsembleException("destination out of bounds"); WriteInt(dests[i]); } WriteData(data); WriteEnd(); } }
// Send a point-to-point message to the specified group member. internal void Send1(Member m, int dest, byte[] data) { lock(send_mutex) { CheckValid(m); if (dest < 0 || dest > m.current_view.nmembers) throw new EnsembleException("destination out of bounds"); WriteBegin(); WriteHdr(m,DnType.DN_SEND1); WriteInt(dest); WriteData(data); WriteEnd(); } }
/* Leave a group. This should be the last call made to the member * It is possible for messages to be delivered to this member after the call * returns. However, it is illegal to initiate new actions on this member. */ internal void Leave(Member m) { lock(send_mutex) { CheckValid(m); m.current_status=Member.Status.Leaving; WriteBegin(); // Write the downcall. WriteHdr(m,DnType.DN_LEAVE); WriteEnd(); } }
/* Join a group. The group context is returned in *contextp. */ internal void Join(Member m, JoinOps ops) { lock(send_mutex) { /* Check that this is a fresh Member, e.g., we haven't already * joined a group with it. */ if (m.current_status != Member.Status.Pre) throw new EnsembleException("Trying to Join more than once"); // Update the state of the member to Joining m.current_status = Member.Status.Joining; // We must provide the member with an ID prior to any other operation m.id = AllocMid(); WriteBegin(); // Write the downcall. WriteHdr(m,DnType.DN_JOIN); WriteString(ops.group_name); WriteString(ops.properties); WriteString(ops.parameters); WriteString(ops.princ); WriteBool(ops.secure); WriteEnd(); // Add the member to the hashtable. This will allow // finding it when messages arrive on the socket. ContextAdd(m); } }
/* Allocate a new context. * The global data record must be locked at this point. */ internal void ContextAdd(Member m) { memb_ctx_tbl.Add(m.id, m); }
// Send a multicast message to the group. internal void Cast(Member m, byte[] data) { lock(send_mutex) { CheckValid(m); WriteBegin(); WriteHdr(m,DnType.DN_CAST); WriteData(data); WriteEnd(); } }
// Send a BlockOk internal void BlockOk(Member m) { // Write the block_ok downcall. lock(send_mutex) { CheckValid(m); WriteBegin(); WriteHdr(m,DnType.DN_BLOCK_OK) ; WriteEnd(); // Update the member state to Blocked. m.current_status = Member.Status.Blocked; } }