void BufferedSocket::threadSendFile(InputStream* file) throw(Exception) { if(state != RUNNING) return; if(disconnecting) return; dcassert(file != NULL); size_t sockSize = (size_t)sock->getSocketOptInt(SO_SNDBUF); size_t bufSize = max(sockSize, (size_t)64*1024); ByteVector readBuf(bufSize); ByteVector writeBuf(bufSize); size_t readPos = 0; bool readDone = false; dcdebug("Starting threadSend\n"); UploadManager *um = UploadManager::getInstance(); size_t sendMaximum, start = 0, current= 0; bool throttling; while(true) { if(!readDone && readBuf.size() > readPos) { // Fill read buffer size_t bytesRead = readBuf.size() - readPos; size_t actual = file->read(&readBuf[readPos], bytesRead); if(bytesRead > 0) { fire(BufferedSocketListener::BytesSent(), bytesRead, 0); } if(actual == 0) { readDone = true; } else { readPos += actual; } } if(readDone && readPos == 0) { fire(BufferedSocketListener::TransmitDone()); return; } readBuf.swap(writeBuf); readBuf.resize(bufSize); writeBuf.resize(readPos); readPos = 0; size_t writePos = 0; while(writePos < writeBuf.size()) { if(disconnecting) return; throttling = BOOLSETTING(THROTTLE_ENABLE); size_t writeSize; if(throttling) { start = TimerManager::getTick(); sendMaximum = um->throttleGetSlice(); if(sendMaximum < 0) { throttling = false; writeSize = min(sockSize / 2, writeBuf.size() - writePos); } else { writeSize = min(min(sockSize / 2, writeBuf.size() - writePos), sendMaximum); } } else { writeSize = min(sockSize / 2, writeBuf.size() - writePos); } int written = sock->write(&writeBuf[writePos], writeSize); if(written > 0) { writePos += written; fire(BufferedSocketListener::BytesSent(), 0, written); if(throttling) { int32_t cycle_time = um->throttleCycleTime(); current = TimerManager::getTick(); int32_t sleep_time = cycle_time - (current - start); if (sleep_time > 0 && sleep_time <= cycle_time) { Thread::sleep(sleep_time); } } } else if(written == -1) { if(!readDone && readPos < readBuf.size()) { // Read a little since we're blocking anyway... size_t bytesRead = min(readBuf.size() - readPos, readBuf.size() / 2); size_t actual = file->read(&readBuf[readPos], bytesRead); if(bytesRead > 0) { fire(BufferedSocketListener::BytesSent(), bytesRead, 0); } if(actual == 0) { readDone = true; } else { readPos += actual; } } else { while(!disconnecting) { int w = sock->wait(POLL_TIMEOUT, Socket::WAIT_WRITE | Socket::WAIT_READ); if(w & Socket::WAIT_READ) { threadRead(); } if(w & Socket::WAIT_WRITE) { break; } } } } } } }
void BufferedSocket::threadSendFile(InputStream* file) throw(Exception) { dcassert(sock); if(!sock) return; dcassert(file != NULL); size_t sockSize = (size_t)sock->getSocketOptInt(SO_SNDBUF); size_t bufSize = max(sockSize, (size_t)64*1024); vector<uint8_t> readBuf(bufSize); vector<uint8_t> writeBuf(bufSize); size_t readPos = 0; bool readDone = false; dcdebug("Starting threadSend\n"); UploadManager *um = UploadManager::getInstance(); size_t sendMaximum; uint64_t start = 0; bool throttling; while(true) { if(disconnecting) return; throttling = (BOOLSETTING(THROTTLE_ENABLE) && getSuperUser() == false); int UserSleep = getSleep(); // !SMT!-S if(!readDone && readBuf.size() > readPos) { // Fill read buffer size_t bytesRead = readBuf.size() - readPos; // !SMT!-S if (UserSleep >= 0) { // throttleGetSlice() should not be called for superusers, so their downloaded bytes don't count in mUploadLimit if(throttling) { start = GET_TICK(); sendMaximum = um->throttleGetSlice(); if (sendMaximum == (size_t)-1) { throttling = false; sendMaximum = bytesRead; } bytesRead = min(bytesRead, sendMaximum); } if (UserSleep) { ::Sleep(UserSleep); bytesRead = min(bytesRead, (size_t)1024); } // !SMT!-S } size_t actual = file->read(&readBuf[readPos], bytesRead); if(bytesRead > 0) { fire(BufferedSocketListener::BytesSent(), bytesRead, 0); } if(actual == 0) { readDone = true; } else { readPos += actual; } } if(readDone && readPos == 0) { fire(BufferedSocketListener::TransmitDone()); return; } readBuf.swap(writeBuf); readBuf.resize(bufSize); writeBuf.resize(readPos); readPos = 0; size_t writePos = 0; while(writePos < writeBuf.size()) { if(disconnecting) return; size_t writeSize = min(sockSize / 2, writeBuf.size() - writePos); int written = sock->write(&writeBuf[writePos], writeSize); if(written > 0) { writePos += written; fire(BufferedSocketListener::BytesSent(), 0, written); } else if(written == -1) { if(!readDone && readPos < readBuf.size() && UserSleep <= 0) { // !SMT!-S // Read a little since we're blocking anyway... size_t bytesRead = min(readBuf.size() - readPos, readBuf.size() / 2); if(throttling) { start = GET_TICK(); sendMaximum = um->throttleGetSlice(); if (sendMaximum == (size_t)-1) { throttling = false; sendMaximum = bytesRead; } bytesRead = (uint32_t)min((int64_t)bytesRead, (int64_t)sendMaximum); } size_t actual = file->read(&readBuf[readPos], bytesRead); if(bytesRead > 0) { fire(BufferedSocketListener::BytesSent(), bytesRead, 0); } if(actual == 0) { readDone = true; } else { readPos += actual; } } else { while(!disconnecting) { int w = sock->wait(POLL_TIMEOUT, Socket::WAIT_WRITE | Socket::WAIT_READ); if(w & Socket::WAIT_READ) { threadRead(); } if(w & Socket::WAIT_WRITE) { break; } } } } if(throttling) { uint32_t cycle_time = um->throttleCycleTime(); uint64_t sleep_time = cycle_time - (GET_TICK() - start); if (sleep_time > 0 && sleep_time <= cycle_time) { Thread::sleep(sleep_time); } } } Thread::yield(); } }
int main(int argc, char *argv[]) { QtSingleApplication a(argc, argv); int retcode; if(a.isRunning()) { QMessageBox::critical(NULL, QObject::tr("Running instance detected"), QObject::tr("ScreenCloud is already running. Please close the running instance before starting a new one.")); return 1; } a.setOrganizationName("screencloud"); a.setApplicationName("ScreenCloud"); a.setQuitOnLastWindowClosed(false); //Create data location for storing plugins if it dosen't exist QDir d; d.mkpath(QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "/plugins"); //Prepare settings QSettings settings("screencloud", "ScreenCloud"); settings.setValue("config-version", "1.1"); bool firstRun = settings.value("first-run", true).toBool(); //Parse command line switches QStringList cmdline_args = a.arguments(); if(cmdline_args.contains("--help") || cmdline_args.contains("-h") ) { INFO(QObject::tr("USAGE: screencloud [-v|-c|-s|-w|-a]")); return 0; } if(cmdline_args.contains("--version") || cmdline_args.contains("-v") ) { INFO(QObject::tr("ScreenCloud version ") + QString(VERSION) + "(" + QString(OPERATING_SYSTEM) + ")"); return 0; } //Setup the python interpreter PythonQt::init(); PythonQt_init_QtBindings(); PythonQt::self()->addSysPath(a.applicationDirPath() + QDir::separator() + "modules"); PythonQt::self()->addSysPath(a.applicationDirPath() + QDir::separator() + "modules" + QDir::separator() + "python-stdlib"); //Global vars if(cmdline_args.contains("--cli") || cmdline_args.contains("-c")) { //Running in CLI mode, do not show GUI if(firstRun) { CRITICAL(QObject::tr("This is the first time you're running ScreenCloud. Refusing to run in CLI mode.")); return 1; } ScreenShooter screenShooter; QImage screenshot; if(cmdline_args.contains("--area") || cmdline_args.contains("-a")) { int areaGeomIndex = cmdline_args.indexOf("--area"); if(areaGeomIndex == -1) { areaGeomIndex = cmdline_args.indexOf("-a"); } areaGeomIndex += 1; if(areaGeomIndex > 0 && areaGeomIndex < cmdline_args.count()) { QString areaString = cmdline_args.at(areaGeomIndex); INFO("Grabbing area (" + areaString + ")"); QRect area(QPoint(areaString.split(",")[0].toUInt(), areaString.split(",")[1].toUInt()), QSize(areaString.split(",")[2].toUInt(), areaString.split(",")[3].toUInt())); screenshot = screenShooter.captureSelection(area); }else { CRITICAL("No area provided. Format: --area x,y,width,height. Example: --area 0,0,640,480"); return 1; } } else if(cmdline_args.contains("--window") || cmdline_args.contains("-w")) { //Get the window id int winIdIndex = cmdline_args.indexOf("--window"); if(winIdIndex == -1) { winIdIndex = cmdline_args.indexOf("-w"); } winIdIndex += 1; if(winIdIndex > 0 && winIdIndex < cmdline_args.count()) { WId windowId = (WId)cmdline_args.at(winIdIndex).toInt(); INFO("Grabbing window with id " + QString::number((int)windowId)); screenshot = screenShooter.captureWindow(windowId); }else { CRITICAL("No window id provided."); return 1; } } else { //Default to fullscreen if(!cmdline_args.contains("--fullscreen") && !cmdline_args.contains("-f")) { INFO("No --area or --window set. Defaulting to fullscreen."); }else { INFO("Capturing fullscreen.") } screenshot = screenShooter.captureFullscreen(); } UploadManager up; QString serviceShortname = up.getDefaultService(); if(serviceShortname.isEmpty()) { if(cmdline_args.contains("--service") || cmdline_args.contains("-s")) { int serviceNameIndex = cmdline_args.indexOf("--service"); if(serviceNameIndex == -1) { serviceNameIndex = cmdline_args.indexOf("-s"); } serviceNameIndex += 1; serviceShortname = cmdline_args.at(serviceNameIndex); }else { CRITICAL("No --service set and no default was found."); return 1; } } up.upload(screenshot, serviceShortname, up.getUploader(serviceShortname)->getFilename(), true); retcode = 0; }else { //Show GUI if(firstRun)