/** * Note that a LinkProtocolState only gets a lock *AFTER* it has * received a LinkMessageReply. Prior to that, the Linker that * created it holds the lock (if the _linker.Target is not null). * * So, given that we are being asked to transfer a lock, we must * have already gotten our LinkMessageReply set, or we wouldn't * hold the lock in the first place. * * So, we only transfer locks to other Linkers when we are finished * since us holding a lock means we have already head some * communication from the other side. * * Since the CT.Lock and CT.Unlock methods can't be called when this * is being called, we know that _target_lock won't change during * this method. */ public bool AllowLockTransfer(Address a, string contype, ILinkLocker l) { bool hold_lock = (a.Equals(_target_lock) && contype == _contype); if (false == hold_lock) { //This is a bug. throw new Exception(String.Format("We don't hold the lock: {0}", a)); } if ((l is Linker) && IsFinished) { return(true); } return(false); }
public bool AllowLockTransfer(Address a, string contype, ILinkLocker new_locker) { return false; }
public bool AllowLockTransfer(Address a, string contype, ILinkLocker new_locker) { return(false); }
/** * Note that a LinkProtocolState only gets a lock *AFTER* it has * received a LinkMessageReply. Prior to that, the Linker that * created it holds the lock (if the _linker.Target is not null). * * So, given that we are being asked to transfer a lock, we must * have already gotten our LinkMessageReply set, or we wouldn't * hold the lock in the first place. * * So, we only transfer locks to other Linkers when we are finished * since us holding a lock means we have already head some * communication from the other side. * * Since the CT.Lock and CT.Unlock methods can't be called when this * is being called, we know that _target_lock won't change during * this method. */ public bool AllowLockTransfer(Address a, string contype, ILinkLocker l) { bool hold_lock = (a.Equals( _target_lock ) && contype == _contype); if( false == hold_lock ) { //This is a bug. throw new Exception(String.Format("We don't hold the lock: {0}", a)); } if( (l is Linker) && IsFinished ) { return true; } return false; }
/** * Allow if we are transfering to a LinkProtocolState or ConnectionPacketHandler * Note this method does not change anything, if the transfer is done, it * is done by the ConnectionTable while it holds its lock. */ public bool AllowLockTransfer(Address a, string contype, ILinkLocker l) { bool allow = false; bool hold_lock = (a.Equals( _target_lock ) && contype == _contype); if( false == hold_lock ) { //We don't even hold this lock! throw new Exception( String.Format("{2} asked to transfer a lock({0}) we don't hold: ({1})", a, _target_lock, this)); } if( l is Linker ) { //Never transfer to another linker: } else if ( l is ConnectionPacketHandler.CphState ) { /** * The ConnectionPacketHandler only locks when it * has actually received a packet. This is a "bird in the * hand" situation, however, if both sides in the double * link case transfer the lock, then we have accomplished * nothing. * * There is a specific case to worry about: the case of * a firewall, where only one node can contact the other. * In this case, it may be very difficult to connect if * we don't eventually transfer the lock to the * ConnectionPacketHandler. In the case of bi-directional * connectivity, we only transfer the lock if the * address we are locking is greater than our own (which * clearly cannot be true for both sides). * * To handle the firewall case, we keep count of how * many times we have been asked to transfer the lock. On * the third time we are asked, we assume we are in the firewall * case and we allow the transfer, this is just a hueristic. */ int reqs = Interlocked.Increment(ref _cph_transfer_requests); if ( (reqs >= 3 ) || ( a.CompareTo( LocalNode.Address ) > 0) ) { allow = true; } } else if( l is LinkProtocolState ) { LinkProtocolState lps = (LinkProtocolState)l; /** * Or Transfer the lock to a LinkProtocolState if: * 1) We created this LinkProtocolState * 2) The LinkProtocolState has received a packet */ if( (lps.Linker == this ) && ( lps.LinkMessageReply != null ) ) { allow = true; } } #if LINK_DEBUG if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format("{0}: Linker({1}) {2}: transfering lock on {3} to {4}", _local_n.Address, _lid, (_target_lock == null), a, l)); } #endif return allow; }
/** * Allow if we are transfering to a LinkProtocolState or ConnectionPacketHandler * Note this method does not change anything, if the transfer is done, it * is done by the ConnectionTable while it holds its lock. */ public bool AllowLockTransfer(Address a, string contype, ILinkLocker l) { bool allow = false; bool hold_lock = (a.Equals(_target_lock) && contype == _contype); if (false == hold_lock) { //We don't even hold this lock! throw new Exception( String.Format("{2} asked to transfer a lock({0}) we don't hold: ({1})", a, _target_lock, this)); } if (l is Linker) { //Never transfer to another linker: } else if (l is ConnectionPacketHandler.CphState) { /** * The ConnectionPacketHandler only locks when it * has actually received a packet. This is a "bird in the * hand" situation, however, if both sides in the double * link case transfer the lock, then we have accomplished * nothing. * * There is a specific case to worry about: the case of * a firewall, where only one node can contact the other. * In this case, it may be very difficult to connect if * we don't eventually transfer the lock to the * ConnectionPacketHandler. In the case of bi-directional * connectivity, we only transfer the lock if the * address we are locking is greater than our own (which * clearly cannot be true for both sides). * * To handle the firewall case, we keep count of how * many times we have been asked to transfer the lock. On * the third time we are asked, we assume we are in the firewall * case and we allow the transfer, this is just a hueristic. */ int reqs = Interlocked.Increment(ref _cph_transfer_requests); if ((reqs >= 3) || (a.CompareTo(LocalNode.Address) > 0)) { allow = true; } } else if (l is LinkProtocolState) { LinkProtocolState lps = (LinkProtocolState)l; /** * Or Transfer the lock to a LinkProtocolState if: * 1) We created this LinkProtocolState * 2) The LinkProtocolState has received a packet */ if ((lps.Linker == this) && (lps.LinkMessageReply != null)) { allow = true; } } #if LINK_DEBUG if (BU.ProtocolLog.LinkDebug.Enabled) { BU.ProtocolLog.Write(BU.ProtocolLog.LinkDebug, String.Format("{0}: Linker({1}) {2}: transfering lock on {3} to {4}", _local_n.Address, _lid, (_target_lock == null), a, l)); } #endif return(allow); }