public ARP() { DebugPrint("Initializing ARP module\n"); arpTable = new ArpTable(this); pendingRequests = new Queue(); pendingRequestsFreelist = new Queue(); //start the array list with 256 elements to for (int i = 0; i < DefaultMaxPendingArpRequests; i++) { PendingArpRequest pendingArpRequest = new PendingArpRequest(); pendingRequestsFreelist.Enqueue(pendingArpRequest); } arpHandle = new AutoResetEvent(false); Thread arpThread = new Thread(this); DebugStub.Assert(arpThread != null); arpThread.Start(); }
private AutoResetEvent AddPendingRequest(IPv4 address, TimeSpan timeout, EthernetAddress localMac, Bytes header, Bytes buffer, IAdapter adapter ) { PendingArpRequest pendingRequest = (PendingArpRequest)pendingRequestsFreelist.Dequeue(); VTable.Assert(pendingRequest != null); pendingRequest.address = address; pendingRequest.active = true; pendingRequest.localMac = localMac; pendingRequest.adapter = adapter; VectorQueueByte txBuffer = pendingRequest.txContainer.Acquire(); txBuffer.AddTail(header); txBuffer.AddTail(buffer); pendingRequest.txContainer.Release(txBuffer); using (pendingRequestsLock.Lock()) { pendingRequests.Enqueue(pendingRequest); } SchedulerTime expiration = SchedulerTime.Now; expiration = expiration.Add(timeout); pendingRequest.requestExpiration = expiration; //poke the wait thread if (pendingRequests.Count == 1) { arpHandle.Set(); } return(pendingRequest.requestEvent); }
private void ARPManageThread() { DebugPrint("ARP managment thread spinning up\n"); //the pending requests list is ordered by deadline... //finding a requests when we rceive a reply is in the worst case O(n)... //Hopefully we won't have many oustanding requests, and the first request out //will often return first... //track two different timeouts here...ARP requests and ARP table aging. SchedulerTime ageTableTimeout; SchedulerTime now; SchedulerTime nextTimer; ageTableTimeout = SchedulerTime.Now; ageTableTimeout = ageTableTimeout.AddMinutes(5); while (true) { now = SchedulerTime.Now; if (now > ageTableTimeout) { arpTable.AgeTable(); ageTableTimeout = SchedulerTime.Now; ageTableTimeout = ageTableTimeout.AddMinutes(5); } using (pendingRequestsLock.Lock()) { nextTimer = SchedulerTime.MaxValue; bool done = false; while (!done) { if (pendingRequests.Count == 0) { done = true; continue; } PendingArpRequest pendingArpRequest = (PendingArpRequest)pendingRequests.Peek(); if (pendingArpRequest == null) { done = true; continue; } if (pendingArpRequest.requestExpiration > now) { nextTimer = pendingArpRequest.requestExpiration; done = true; continue; } else { pendingArpRequest = (PendingArpRequest)pendingRequests.Dequeue(); if (pendingArpRequest.active == true) { //We need error propagation here... pendingArpRequest.active = false; DebugStub.Assert(false); } pendingRequestsFreelist.Enqueue(pendingArpRequest); } } } if (ageTableTimeout < nextTimer) { DebugPrint("setting nextTimer ageTableTimeout\n"); nextTimer = ageTableTimeout; } bool rc; rc = arpHandle.WaitOne(nextTimer); } }