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;
						}
					}
				}
			}
		}
	}
}
Esempio n. 2
0
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();
	}
}
Esempio n. 3
0
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)