Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
/** \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();
    }
}