bool Q3Socket::flush() { if ( !d->socket ) return true; bool osBufferFull = false; int consumed = 0; while ( !osBufferFull && d->state >= Connecting && d->wsize > 0 ) { #if defined(Q3SOCKET_DEBUG) qDebug( "Q3Socket (%s): flush: Write data to the socket", name() ); #endif QByteArray *a = d->wba.first(); int nwritten; int i = 0; if ( (int)a->size() - d->windex < 1460 ) { // Concatenate many smaller blocks. the first may be // partial, but each subsequent block is copied entirely // or not at all. the sizes here are picked so that we // generally won't trigger nagle's algorithm in the tcp // implementation: we concatenate if we'd otherwise send // less than PMTU bytes (we assume PMTU is 1460 bytes), // and concatenate up to the largest payload TCP/IP can // carry. with these precautions, nagle's algorithm // should apply only when really appropriate. QByteArray out( 65536 ); int j = d->windex; int s = a->size() - j; while ( a && i+s < (int)out.size() ) { memcpy( out.data()+i, a->data()+j, s ); j = 0; i += s; a = d->wba.next(); s = a ? a->size() : 0; } nwritten = d->socket->write( out.data(), i ); if ( d->wsn ) d->wsn->setEnabled( false ); // the QSocketNotifier documentation says so } else { // Big block, write it immediately i = a->size() - d->windex; nwritten = d->socket->write( a->data() + d->windex, i ); if ( d->wsn ) d->wsn->setEnabled( false ); // the QSocketNotifier documentation says so } if ( nwritten > 0 ) { if ( consumeWriteBuf( nwritten ) ) consumed += nwritten; } if ( nwritten < i ) osBufferFull = true; } if ( consumed > 0 ) { #if defined(Q3SOCKET_DEBUG) qDebug( "Q3Socket (%s): flush: wrote %d bytes, %d left", name(), consumed, (int)d->wsize ); #endif emit bytesWritten( consumed ); } if ( d->state == Closing && d->wsize == 0 ) { #if defined(Q3SOCKET_DEBUG) qDebug( "Q3Socket (%s): flush: Delayed close done. Terminating.", name() ); #endif resetStatus(); setOpenMode(NotOpen); d->close(); d->state = Idle; emit delayedCloseFinished(); return true; } if ( !d->socket->isOpen() ) { d->connectionClosed(); emit connectionClosed(); return true; } if ( d->wsn ) d->wsn->setEnabled( d->wsize > 0 ); // write if there's data return true; }
void HttpPoll::http_result() { // check for death :) QPointer<QObject> self = this; syncFinished(); if(!self) return; // get id and packet QString id; QString cookie = d->http.getHeader("Set-Cookie"); int n = cookie.indexOf("ID="); if(n == -1) { reset(); error(ErrRead); return; } n += 3; int n2 = cookie.indexOf(';', n); if(n2 != -1) id = cookie.mid(n, n2-n); else id = cookie.mid(n); QByteArray block = d->http.body(); // session error? if(id.right(2) == ":0") { if(id == "0:0" && d->state == 2) { reset(); connectionClosed(); return; } else { reset(); error(ErrRead); return; } } d->ident = id; bool justNowConnected = false; if(d->state == 1) { d->state = 2; justNowConnected = true; } // sync up again soon if(bytesToWrite() > 0 || !d->closing) { d->t->start(d->polltime * 1000); } // connecting if(justNowConnected) { connected(); } else { if(!d->out.isEmpty()) { int x = d->out.size(); d->out.resize(0); takeWrite(x); bytesWritten(x); } } if(!self) return; if(!block.isEmpty()) { appendRead(block); readyRead(); } if(!self) return; if(bytesToWrite() > 0) { do_sync(); } else { if(d->closing) { reset(); delayedCloseFinished(); return; } } }