void TTinyTP::TTPHandleDataIndication ( TTPBuf *userData) // data read { int credit; Boolean m; check(userData); { int position, bufsize; position = BufUsed(userData); // should be zero bufsize = BufSize(userData); // amount read XTRACE(kHandleDataIndication, position, bufsize); } ttp_pdu_data_parse(userData, &m, &credit); // strips out ttp overhead byte this->SendCredit += credit; if (SendCredit > 30) SendCredit = 30; // FIXME: temp workaround for HP runaway credits // WARNING: HP tells us that Microsoft believes in // extending lots and lots of credits, and relies on // lap-layer flow control to survive. if (credit > 0) // if we've been given more credits from IrLan box TTPBackEnable(); // then tell clients flow-control state has changed if (BufSize(userData) > 0) { XTRACE(kHandleDataIndication, m, credit); // log what we parsed this->RemoteCredit--; if (m == false) // if no More data this->AppendTail(&(this->RxQueue), TTP_Segment_Last, 0, userData); else // else have More data this->AppendTail(&(this->RxQueue), TTP_Segment, 0, userData); } else { XTRACE(kDataLessPacket, m, credit); // log we received a dataless packet BufFree(userData); // we're done with it now... } // Make sure a read is pending at all times .... this could // use a better model. Only post if connected. if( this->Connected ) { CBufferSegment *getBuf; getBuf = BufAlloc(2048+5); // need up to max lap size require(getBuf, NoMem); this->DataGet(getBuf); } NoMem: return; }
/** \fn ThreadedFileWriter::DiskLoop(void) * \brief The thread run method that actually calls safe_write(). */ void ThreadedFileWriter::DiskLoop(void) { uint size = 0; written = 0; while (!in_dtor || BufUsed() > 0) { buflock.lock(); size = BufUsedPriv(); if (size == 0) { buflock.unlock(); bufferEmpty.wakeAll(); buflock.lock(); } if (!size || (!in_dtor && !flush && ((size < tfw_min_write_size) && (written >= tfw_min_write_size)))) { bufferHasData.wait(&buflock, 100); buflock.unlock(); continue; } uint trpos = rpos; buflock.unlock(); /* cap the max. write size. Prevents the situation where 90% of the buffer is valid, and we try to write all of it at once which takes a long time. During this time, the other thread fills up the 10% that was free... */ size = (size > TFW_MAX_WRITE_SIZE) ? TFW_MAX_WRITE_SIZE : size; bool write_ok; if (ignore_writes) ; else if ((trpos + size) > tfw_buf_size) { int first_chunk_size = tfw_buf_size - trpos; int second_chunk_size = size - first_chunk_size; size = safe_write(fd, buf + trpos, first_chunk_size, write_ok); if ((int)size == first_chunk_size && write_ok) size += safe_write(fd, buf, second_chunk_size, write_ok); } else { size = safe_write(fd, buf + trpos, size, write_ok); } if (!ignore_writes && !write_ok && ((EFBIG == errno) || (ENOSPC == errno))) { QString msg; switch (errno) { case EFBIG: msg = "Maximum file size exceeded by '%1'" "\n\t\t\t" "You must either change the process ulimits, configure" "\n\t\t\t" "your operating system with \"Large File\" support, or use" "\n\t\t\t" "a filesystem which supports 64-bit or 128-bit files." "\n\t\t\t" "HINT: FAT32 is a 32-bit filesystem."; break; case ENOSPC: msg = "No space left on the device for file '%1'" "\n\t\t\t" "file will be truncated, no further writing will be done."; break; } VERBOSE(VB_IMPORTANT, msg.arg(filename)); ignore_writes = true; } if (written <= tfw_min_write_size) { written += size; } buflock.lock(); if (trpos == rpos) { rpos = (rpos + size) % tfw_buf_size; } else { VERBOSE(VB_IMPORTANT, LOC_ERR + "Programmer Error detected! " "rpos was changed from under the DiskLoop() function."); } m_file_wpos += size; buflock.unlock(); bufferWroteData.wakeAll(); } }