ErrorCode Sender::start() { { std::lock_guard<std::mutex> lock(mutex_); if (transferStatus_ != NOT_STARTED) { LOG(ERROR) << "duplicate start() call detected " << transferStatus_; return ALREADY_EXISTS; } transferStatus_ = ONGOING; } checkAndUpdateBufferSize(); const bool twoPhases = options_.two_phases; LOG(INFO) << "Client (sending) to " << destHost_ << ", Using ports [ " << transferRequest_.ports << "]"; startTime_ = Clock::now(); downloadResumptionEnabled_ = options_.enable_download_resumption; if (!progressReporter_) { VLOG(1) << "No progress reporter provided, making a default one"; progressReporter_ = folly::make_unique<ProgressReporter>(transferRequest_); } bool progressReportEnabled = progressReporter_ && progressReportIntervalMillis_ > 0; if (throttler_) { LOG(INFO) << "Skipping throttler setup. External throttler set." << "Throttler details : " << *throttler_; } else { configureThrottler(); } threadsController_ = new ThreadsController(transferRequest_.ports.size()); threadsController_->setNumBarriers(SenderThread::NUM_BARRIERS); threadsController_->setNumFunnels(SenderThread::NUM_FUNNELS); threadsController_->setNumConditions(SenderThread::NUM_CONDITIONS); // TODO: fix this ! use transferRequest! (and dup from Receiver) senderThreads_ = threadsController_->makeThreads<Sender, SenderThread>( this, transferRequest_.ports.size(), transferRequest_.ports); if (downloadResumptionEnabled_ && options_.delete_extra_files) { if (protocolVersion_ >= Protocol::DELETE_CMD_VERSION) { dirQueue_->enableFileDeletion(); } else { LOG(WARNING) << "Turning off extra file deletion on the receiver side " "because of protocol version " << protocolVersion_; } } dirThread_ = dirQueue_->buildQueueAsynchronously(); if (twoPhases) { dirThread_.join(); } for (auto &senderThread : senderThreads_) { senderThread->startThread(); } if (progressReportEnabled) { progressReporter_->start(); std::thread reporterThread(&Sender::reportProgress, this); progressReporterThread_ = std::move(reporterThread); } return OK; }
ErrorCode Receiver::start() { WDT_CHECK_EQ(getTransferStatus(), NOT_STARTED) << "There is already a transfer running on this instance of receiver"; startTime_ = Clock::now(); WLOG(INFO) << "Starting (receiving) server on ports [ " << transferRequest_.ports << "] Target dir : " << destDir_; // TODO do the init stuff here if (!throttler_) { configureThrottler(); } else { WLOG(INFO) << "Throttler set externally. Throttler : " << *throttler_; } setTransferStatus(ONGOING); while (true) { for (auto &receiverThread : receiverThreads_) { receiverThread->startThread(); } if (isJoinable_) { break; } // If it is long running mode, finish the threads // processing the current transfer and re spawn them again // with the same sockets for (auto &receiverThread : receiverThreads_) { receiverThread->finish(); receiverThread->reset(); } threadsController_->reset(); // reset transfer status setTransferStatus(NOT_STARTED); continue; } if (isJoinable_) { if (progressReporter_) { progressReporter_->start(); } std::thread trackerThread(&Receiver::progressTracker, this); progressTrackerThread_ = std::move(trackerThread); } return OK; }