diff options
Diffstat (limited to 'ncpd')
-rw-r--r-- | ncpd/link.cc | 38 | ||||
-rw-r--r-- | ncpd/link.h | 3 |
2 files changed, 31 insertions, 10 deletions
diff --git a/ncpd/link.cc b/ncpd/link.cc index 228b878..a52e3ef 100644 --- a/ncpd/link.cc +++ b/ncpd/link.cc @@ -266,10 +266,12 @@ receive(bufferStore buff) break; } pthread_mutex_unlock(&queueMutex); - if (ackFound) + if (ackFound) { // Older packets implicitely ack'ed multiAck(refstamp); - else { + // Transmit waiting packets + transmitWaitQueue(); + } else { if (verbose & LNK_DEBUG_LOG) { cout << "Link: << UNMATCHED ack seq=" << seq ; if (verbose & LNK_DEBUG_DUMP) @@ -363,6 +365,22 @@ transmitHoldQueue(int channel) } void Link:: +transmitWaitQueue() +{ + vector<bufferStore> tmpQueue; + vector<bufferStore>::iterator i; + + // First, move desired packets to a temporary queue + for (i = waitQueue.begin(); i != waitQueue.end(); i++) + tmpQueue.push_back(*i); + waitQueue.clear(); + // transmit the moved packets. If the backlock gets + // full, they are put into waitQueue again. + for (i = tmpQueue.begin(); i != tmpQueue.end(); i++) + transmit(*i); +} + +void Link:: transmit(bufferStore buf) { if (hasFailed()) @@ -375,15 +393,15 @@ transmit(bufferStore buf) pthread_mutex_unlock(&queueMutex); } else { - // Wait, until backlog is drained. + // If backlock is full, put on waitQueue int ql; - do { - pthread_mutex_lock(&queueMutex); - ql = ackWaitQueue.size(); - pthread_mutex_unlock(&queueMutex); - if (ql >= maxOutstanding) - usleep(100000); - } while (ql >= maxOutstanding); + pthread_mutex_lock(&queueMutex); + ql = ackWaitQueue.size(); + pthread_mutex_unlock(&queueMutex); + if (ql >= maxOutstanding) { + waitQueue.push_back(buf); + return; + } ackWaitQueueElement e; e.seq = txSequence++; diff --git a/ncpd/link.h b/ncpd/link.h index cf265c0..81732b6 100644 --- a/ncpd/link.h +++ b/ncpd/link.h @@ -28,6 +28,7 @@ #include <config.h> #endif #include <pthread.h> +#include <sys/time.h> #include "bufferstore.h" #include "bufferarray.h" @@ -151,6 +152,7 @@ private: void multiAck(struct timeval); void retransmit(); void transmitHoldQueue(int channel); + void transmitWaitQueue(); pthread_t checkthread; pthread_mutex_t queueMutex; @@ -168,6 +170,7 @@ private: vector<ackWaitQueueElement> ackWaitQueue; vector<bufferStore> holdQueue; + vector<bufferStore> waitQueue; bool xoff[256]; }; |