aboutsummaryrefslogtreecommitdiffstats
path: root/ncpd/link.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ncpd/link.cc')
-rw-r--r--ncpd/link.cc38
1 files changed, 28 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++;