bool Thread :: IsCallerInternalThread() const { if (IsInternalThreadRunning() == false) return false; // we can't be him if he doesn't exist! #if defined(MUSCLE_USE_PTHREADS) return pthread_equal(pthread_self(), _thread); #elif defined(MUSCLE_PREFER_WIN32_OVER_QT) return (_threadID == GetCurrentThreadId()); #elif defined(MUSCLE_QT_HAS_THREADS) return (QThread::currentThread() == static_cast<const QThread *>(&_thread)); #elif defined(__BEOS__) || defined(__HAIKU__) return (_thread == find_thread(NULL)); #elif defined(__ATHEOS__) return (_thread == find_thread(NULL)); #else #error "Thread::IsCallerInternalThread(): Unsupported platform?" #endif }
void WUploadThread::DoUpload() { PRINT("WUploadThread::DoUpload\n"); if (fShutdownFlag && *fShutdownFlag) // Do we need to interrupt? { ConnectTimer(); return; } // Still connected? if (!IsInternalThreadRunning()) { ConnectTimer(); return; } // Small files get to bypass queue if (IsLocallyQueued()) { if ( (fFile && (fFileSize >= gWin->fSettings->GetMinQueuedSize())) || IsManuallyQueued() ) { // not yet fForced = false; WUploadEvent *lq = new WUploadEvent(WUploadEvent::FileQueued); if (lq) { SendReply(lq); } return; } fForced = true; // Set this here to avoid duplicate call to DoUpload() } // Recheck if IP is ignored or not // if (gWin->IsIgnoredIP(fStrRemoteIP) && !IsBlocked()) { SetBlocked(true); } if (IsBlocked()) { WUploadEvent *wue = new WUploadEvent(WUploadEvent::FileBlocked); if (wue) { if (fTimeLeft != -1) wue->SetTime(fTimeLeft); SendReply(wue); } return; } if (fStartTime == 0) fStartTime = GetRunTime64(); if (fFile) { MessageRef uref(GetMessageFromPool(WTransfer::TransferFileData)); if (uref()) { // think about doing this in a dynamic way (depending on connection) double dpps = GetPacketSize() * 1024.0; uint32 bufferSize = lrint(dpps); ByteBufferRef buf = GetByteBufferFromPool(bufferSize); uint8 * scratchBuffer = buf()->GetBuffer(); if (scratchBuffer == NULL) { _nobuffer(); return; } int32 numBytes = 0; numBytes = fFile->ReadBlock32(scratchBuffer, bufferSize); if (numBytes > 0) { buf()->SetNumBytes(numBytes, true); // munge mode switch (fMungeMode) { case WTransfer::MungeModeNone: { uref()->AddInt32("mm", WTransfer::MungeModeNone); break; } case WTransfer::MungeModeXOR: { for (int32 x = 0; x < numBytes; x++) scratchBuffer[x] ^= 0xFF; uref()->AddInt32("mm", WTransfer::MungeModeXOR); break; } default: { break; } } if (uref()->AddFlat("data", buf) == B_OK) { // possibly do checksums here uref()->AddInt32("chk", CalculateFileChecksum(buf)); // a little paranoia, due to file-resumes not working.... (TCP should handle this BUT...) SendMessageToSessions(uref); // NOTE: RequestOutputQueuesDrainedNotification() can recurse, so we need to update the offset before // calling it! fCurrentOffset += numBytes; if (fTunneled) { SignalUpload(); } else { MessageRef drain(GetMessageFromPool()); if (drain()) qmtt->RequestOutputQueuesDrainedNotification(drain); } WUploadEvent *update = new WUploadEvent(WUploadEvent::FileDataSent); if (update) { update->SetOffset(fCurrentOffset); update->SetSize(fFileSize); update->SetSent(numBytes); if (fCurrentOffset >= fFileSize) { update->SetDone(true); // file done! update->SetFile(SimplifyPath(fFileUl)); if (gWin->fSettings->GetUploads()) { SystemEvent( gWin, tr("%1 has finished downloading %2.").arg( GetRemoteUser() ).arg( SimplifyPath(fFileUl) ) ); } } SendReply(update); } return; } else { _nobuffer(); return; } } if (numBytes <= 0) { NextFile(); SignalUpload(); return; } } } else { while (!fFile) { if (fUploads.GetNumItems() != 0) { // grab the ref and remove it from the list fUploads.RemoveHead(fCurrentRef); fFileUl = MakeUploadPath(fCurrentRef); #ifdef _DEBUG // <*****@*****.**> 20021023, 20030702 -- Add additional debug message WString wul(fFileUl); PRINT("WUploadThread::DoUpload: filePath = %S\n", wul.getBuffer()); #endif fFile = new WFile(); Q_CHECK_PTR(fFile); if (!fFile->Open(fFileUl, QIODevice::ReadOnly)) // probably doesn't exist { delete fFile; fFile = NULL; fCurFile++; continue; // onward } // got our file! fFileSize = fFile->Size(); fCurrentOffset = 0; // from the start if (fCurrentRef()->FindInt64("secret:offset", fCurrentOffset) == B_OK) { if (!fFile->Seek(fCurrentOffset)) // <*****@*****.**> 20021026 { fFile->Seek(0); // this can't fail :) (I hope) fCurrentOffset = 0; } } // copy the message in our current file ref MessageRef headRef = fCurrentRef.Clone(); if (headRef()) { headRef()->what = WTransfer::TransferFileHeader; headRef()->AddInt64("beshare:StartOffset", fCurrentOffset); SendMessageToSessions(headRef); } fCurFile++; // Reset statistics InitTransferRate(); InitTransferETA(); WUploadEvent *started = new WUploadEvent(WUploadEvent::FileStarted); if (started) { started->SetFile(SimplifyPath(fFileUl)); started->SetStart(fCurrentOffset); started->SetSize(fFileSize); #ifdef _DEBUG started->SetSession(fRemoteSessionID); #endif SendReply(started); } if (gWin->fSettings->GetUploads()) { SystemEvent( gWin, tr("%1 is downloading %2.").arg( GetRemoteUser() ).arg( SimplifyPath(fFileUl) ) ); } // nested call SignalUpload(); return; } else { PRINT("No more files!\n"); fWaitingForUploadToFinish = true; SetFinished(true); if (fTunneled) { _OutputQueuesDrained(); } else { MessageRef drain(GetMessageFromPool()); if (drain()) qmtt->RequestOutputQueuesDrainedNotification(drain); } break; } } } }