bool QtLocalPeer::sendMessage(const QString &message, int timeout, bool block) { if (!isClient()) return false; QLocalSocket socket; bool connOk = false; for (int i = 0; i < 2; i++) { // Try twice, in case the other instance is just starting up socket.connectToServer(socketName); connOk = socket.waitForConnected(timeout/2); if (connOk || i) break; int ms = 250; #if defined(Q_OS_WIN) Sleep(DWORD(ms)); #else struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; nanosleep(&ts, NULL); #endif } if (!connOk) return false; QByteArray uMsg(message.toUtf8()); QDataStream ds(&socket); ds.writeBytes(uMsg.constData(), uMsg.size()); bool res = socket.waitForBytesWritten(timeout); res &= socket.waitForReadyRead(timeout); // wait for ack res &= (socket.read(qstrlen(ack)) == ack); if (block) // block until peer disconnects socket.waitForDisconnected(-1); return res; }
void QtLocalPeer::receiveConnection() { QLocalSocket* socket = server->nextPendingConnection(); if (!socket) return; while (socket->bytesAvailable() < (int)sizeof(quint32)) socket->waitForReadyRead(); QDataStream ds(socket); QByteArray uMsg; quint32 remaining; ds >> remaining; uMsg.resize(remaining); int got = 0; char* uMsgBuf = uMsg.data(); do { got = ds.readRawData(uMsgBuf, remaining); remaining -= got; uMsgBuf += got; } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); if (got < 0) { qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData()); delete socket; return; } QString message(QString::fromUtf8(uMsg)); socket->write(ack, qstrlen(ack)); socket->waitForBytesWritten(1000); socket->waitForDisconnected(1000); // make sure client reads ack delete socket; emit messageReceived(message); //### (might take a long time to return) }
// Called before a plot to connect to the terminal window, if needed void qt_connectToServer() { if (!qt_initialized) return; // Determine to which server we should connect bool connectToWidget = !qt_optionWidget.isEmpty(); QString server = connectToWidget ? qt_optionWidget : qt_localServerName; if (qt_socket.state() == QLocalSocket::ConnectedState) { // Check if we are already connected to the correct server if (qt_socket.serverName() == server) return; // Otherwise disconnect qt_socket.disconnectFromServer(); while (qt_socket.state() == QLocalSocket::ConnectedState) qt_socket.waitForDisconnected(1000); } // Start the gnuplot_qt helper program if not already started if (!connectToWidget && !qt_gnuplot_qtStarted) execGnuplotQt(); // Connect to the server, or local server if not available. qt_connectToServer(server); }
void qt_connectToServer() { if (!qt_initialized) return; // Determine to which server we should connect QString server = qt_localServerName; if (!qt_optionWidget.isEmpty()) server = qt_optionWidget; // Check if we are already connected if (qt_socket.serverName() == server) return; // Disconnect if (qt_socket.state() == QLocalSocket::ConnectedState) { qt_socket.disconnectFromServer(); qt_socket.waitForDisconnected(1000); } // Connect to server, or local server if not available. qt_socket.connectToServer(server); if (!qt_socket.waitForConnected(3000)) while (qt_socket.state() != QLocalSocket::ConnectedState) qt_socket.connectToServer(qt_localServerName); }
/** * Sets in motion the communication necessary to ensure that only one instance * survives. * @returns true if a single instance is assured, false if it was not possible * to enforce the policy */ bool InstanceManager::ensureSingleInstance(ResolutionScheme scheme) { // If the server exists, it's because we're already the dominant instance if (mServer) { return true; } QLocalSocket socket; socket.connectToServer(mKey); if (!socket.waitForConnected(10000)) { // No remote server? Let's try starting our own. startServer(); return false; } switch (scheme) { case ThisInstanceWins: tellServerToQuit(&socket); break; case HighestVersionWins: default: QTextStream stream(&socket); stream << "version\n"; stream.flush(); socket.waitForReadyRead(); QString remoteVersion = stream.readLine(); if (VersionNumber(remoteVersion) < VersionNumber(APP_VERSION)) { tellServerToQuit(&socket); startServer(); } else { QTimer::singleShot(0, qApp, SLOT(quit())); } break; } socket.disconnectFromServer(); socket.waitForDisconnected(); return true; }
bool Application::IsAlreadyRunning () const { QLocalSocket socket; socket.connectToServer (GetSocketName ()); if (socket.waitForConnected () || socket.state () == QLocalSocket::ConnectedState) { QByteArray toSend; { QDataStream out (&toSend, QIODevice::WriteOnly); out << Arguments_; } socket.write (toSend); socket.disconnectFromServer (); socket.waitForDisconnected (); return true; } else { switch (socket.error ()) { case QLocalSocket::ServerNotFoundError: case QLocalSocket::ConnectionRefusedError: break; default: qWarning () << Q_FUNC_INFO << "socket error" << socket.error (); return true; } } // Clear any halted servers and their messages QLocalServer::removeServer (GetSocketName ()); return false; }
int main(int argc, char * argv[]) { QCoreApplication app(argc, argv); QStringList args; for (int i = 1; i < argc; ++i) args << QString(argv[i]); if (args.count() == 0 ) qFatal("No connection name supplied to lackey process"); // This is a workaround for the fact that we cannot use stdin/stdout/stderr // to communicate with a process on WinCE or Symbian systems. // We use sockets instead, and the first argument given is the port number. QString connectionName = args.takeFirst(); QLocalSocket oopSocket; if (connectionName != QString("NoComms")) { oopSocket.connectToServer(connectionName); oopSocket.waitForConnected(-1); } if (args.count() == 0 ) qFatal("No arguments supplied to lackey process"); int retVal = 0; if (args[0] == "ReadLock") { // 1)read-lock // 2)unlock QSystemReadWriteLock testRwLock("Viper"); write(&oopSocket, qPrintable(Lackey::BeforeLockForRead)); testRwLock.lockForRead(); write(&oopSocket, qPrintable(Lackey::AfterLockForRead)); testRwLock.unlock(); QTest::qSleep(1000); write(&oopSocket, qPrintable(Lackey::AfterUnlockForRead)); } else if (args[0] == "WriteLock") { // 1) write-lock // 2) unlock QSystemReadWriteLock testRwLock("Viper"); write(&oopSocket, qPrintable(Lackey::BeforeLockForWrite)); testRwLock.lockForWrite(); write(&oopSocket, qPrintable(Lackey::AfterLockForWrite)); testRwLock.unlock(); QTest::qSleep(1000); write(&oopSocket, qPrintable(Lackey::AfterUnlockForWrite)); } else if (args[0] == "ReadLockReleaseable") { // 1) read-lock // 2) wait for input on stdin // 3) unlock QSystemReadWriteLock testRwLock("Viper"); write(&oopSocket, qPrintable(Lackey::BeforeLockForRead)); testRwLock.lockForRead(); QTest::qSleep(1000); write(&oopSocket, qPrintable(Lackey::AfterLockForRead)); readLine(&oopSocket); testRwLock.unlock(); write(&oopSocket, qPrintable(Lackey::AfterUnlockForRead)); } else if (args[0] == "WriteLockReleaseable") { // 1) write-lock // 2) wait for input on stdin // 3) unlock QSystemReadWriteLock testRwLock("Viper"); write(&oopSocket, qPrintable(Lackey::BeforeLockForWrite)); testRwLock.lockForWrite(); write(&oopSocket, qPrintable(Lackey::AfterLockForWrite)); readLine(&oopSocket); testRwLock.unlock(); write(&oopSocket, qPrintable(Lackey::AfterUnlockForWrite)); } else if (args[0] == "ReadLockLoop") { // for(runTime msecs): // 1) read-lock // 2) sleep(holdTime msecs) // 3) unlock // 4) sleep(waitTime msecs) Q_ASSERT(args.count() == 4); int runTime = args[1].toInt(); int holdTime = args[2].toInt(); int waitTime = args[3].toInt(); QSystemReadWriteLock testRwLock("Viper"); QTime t; t.start(); while(t.elapsed() < runTime) { testRwLock.lockForRead(); if (holdTime) QTest::qSleep(holdTime); testRwLock.unlock(); if(waitTime) QTest::qSleep(waitTime); } } else if (args[0] == "WriteLockLoop") { // for(runTime msecs): // 1) read-lock // 2) sleep(holdTime msecs) // 3) unlock // 4) sleep(waitTime msecs) Q_ASSERT(args.count() == 4); int runTime = args[1].toInt(); int holdTime = args[2].toInt(); int waitTime = args[3].toInt(); QSystemReadWriteLock testRwLock("Viper"); QTime t; t.start(); while (t.elapsed() < runTime) { testRwLock.lockForWrite(); if (holdTime) QTest::qSleep(holdTime); testRwLock.unlock(); if (waitTime) QTest::qSleep(waitTime); } } else if (args[0] == "ReadLockExcl") { // for (runTime msecs): // 1) read-lock // 2) check that the exclusive file does not // exist, if it does qFatal // 3) sleep(holdTime msecs) // 4) unlock // 5) sleep(waitTime msecs) Q_ASSERT(args.count() == 4); int runTime = args[1].toInt(); int holdTime = args[2].toInt(); int waitTime = args[3].toInt(); QSystemReadWriteLock testRwLock("Viper"); QTime t; t.start(); while (t.elapsed() < runTime) { testRwLock.lockForRead(); QDir cwd; if (cwd.exists("writeLockExcl.tmp")) qFatal("writeLockExcl.tmp file found during read!"); if (holdTime) QTest::qSleep(holdTime); testRwLock.unlock(); if (waitTime) QTest::qSleep(waitTime); } } else if (args[0] == "WriteLockExcl") { // for(runTime msecs) // 1) write-lock // 2) check that exclusive file does not // exist, if it does qFatal // 3) create the exclusive file, // sleep(holdTime msecs), delete the file // 4) unlock // 5) sleep(waitTime msecs) Q_ASSERT(args.count() == 4); int runTime = args[1].toInt(); int holdTime = args[2].toInt(); int waitTime = args[3].toInt(); QSystemReadWriteLock testRwLock("Viper"); QTime t; t.start(); while(t.elapsed() < runTime) { testRwLock.lockForWrite(); QDir cwd; if (cwd.exists("writeLockExcl.tmp")) qFatal("writeLockExcl.tmp file found during write!"); QFile file("writeLockExcl.tmp"); file.open(QIODevice::ReadWrite); if (holdTime) QTest::qSleep(holdTime); file.close(); cwd.remove("writeLockExcl.tmp"); testRwLock.unlock(); if(waitTime) QTest::qSleep(waitTime); } } else { retVal = 1; } if (connectionName != QString("NoComms")) { oopSocket.disconnectFromServer(); oopSocket.waitForDisconnected(-1); } return retVal; }
void LocalPeer::receiveConnection() { #ifdef _WIN32 QLocalSocket* socket = server_->nextPendingConnection(); if (!socket) return; while (socket->bytesAvailable() < (int)sizeof(quint32)) socket->waitForReadyRead(); QDataStream ds(socket); QByteArray uMsg; quint32 remaining; ds >> remaining; uMsg.resize(remaining); int got = 0; char* uMsgBuf = uMsg.data(); do { got = ds.readRawData(uMsgBuf, remaining); remaining -= got; uMsgBuf += got; } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); if (got < 0) { delete socket; return; } QString message(QString::fromUtf8(uMsg)); if (message == crossprocess_message_get_process_id) { unsigned int process_id = 0; process_id = ::GetCurrentProcessId(); socket->write((const char*) &process_id, sizeof(process_id)); } else if (message == crossprocess_message_get_hwnd_activate) { unsigned int hwnd = 0; if (wnd_) { hwnd = (unsigned int) wnd_->winId(); wnd_->activateFromEventLoop(); } socket->write((const char*) &hwnd, sizeof(hwnd)); } else { socket->write("icq", qstrlen("icq")); } socket->waitForBytesWritten(1000); socket->waitForDisconnected(1000); delete socket; if (message == crossprocess_message_shutdown_process) { QApplication::exit(0); } #endif //_WIN32 }
/** Constructor. Parses the command-line arguments, resets Rshare's * configuration (if requested), and sets up the GUI style and language * translation. */ Rshare::Rshare(QStringList args, int &argc, char **argv, const QString &dir) : QApplication(argc, argv) { mStartupTime = QDateTime::currentDateTime(); localServer = NULL; //Initialize connection to LocalServer to know if other process runs. { QString serverName = QString(TARGET); if (!args.isEmpty()) { // load into shared memory QBuffer buffer; buffer.open(QBuffer::ReadWrite); QDataStream out(&buffer); out << args; int size = buffer.size(); QSharedMemory newArgs; newArgs.setKey(serverName + "_newArgs"); if (newArgs.isAttached()) newArgs.detach(); if (!newArgs.create(size)) { std::cerr << "(EE) Rshare::Rshare Unable to create shared memory segment of size:" << size << " error:" << newArgs.errorString().toStdString() << "." << std::endl; #ifdef Q_OS_UNIX std::cerr << "Look with `ipcs -m` for nattch==0 segment. And remove it with `ipcrm -m 'shmid'`." << std::endl; //No need for windows, as it removes shared segment directly even when crash. #endif newArgs.detach(); ::exit(EXIT_FAILURE); } newArgs.lock(); char *to = (char*)newArgs.data(); const char *from = buffer.data().data(); memcpy(to, from, qMin(newArgs.size(), size)); newArgs.unlock(); // Connect to the Local Server of the main process to notify it // that a new process had been started QLocalSocket localSocket; localSocket.connectToServer(QString(TARGET)); std::cerr << "Rshare::Rshare waitForConnected to other instance." << std::endl; if( localSocket.waitForConnected(100) ) { std::cerr << "Rshare::Rshare Connection etablished. Waiting for disconnection." << std::endl; localSocket.waitForDisconnected(1000); newArgs.detach(); std::cerr << "Rshare::Rshare Arguments was sended." << std::endl << " To disable it, in Options - General - Misc," << std::endl << " uncheck \"Use Local Server to get new Arguments\"." << std::endl; ::exit(EXIT_SUCCESS); // Terminate the program using STDLib's exit function } newArgs.detach(); } // No main process exists // Or started without arguments // So we start a Local Server to listen for connections from new process localServer= new QLocalServer(); QObject::connect(localServer, SIGNAL(newConnection()), this, SLOT(slotConnectionEstablished())); updateLocalServer(); } #if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) qInstallMessageHandler(qt_msg_handler); #else qInstallMsgHandler(qt_msg_handler); #endif #ifndef __APPLE__ /* set default window icon */ setWindowIcon(QIcon(":/icons/logo_128.png")); #endif mBlink = true; QTimer *timer = new QTimer(this); timer->setInterval(500); connect(timer, SIGNAL(timeout()), this, SLOT(blinkTimer())); timer->start(); timer = new QTimer(this); timer->setInterval(60000); connect(timer, SIGNAL(timeout()), this, SIGNAL(minuteTick())); timer->start(); /* Read in all our command-line arguments. */ parseArguments(args); /* Check if we're supposed to reset our config before proceeding. */ if (_args.contains(ARG_RESET)) { Settings->reset(); } /* Handle the -loglevel and -logfile options. */ if (_args.contains(ARG_LOGFILE)) _log.open(_args.value(ARG_LOGFILE)); if (_args.contains(ARG_LOGLEVEL)) { _log.setLogLevel(Log::stringToLogLevel( _args.value(ARG_LOGLEVEL))); if (!_args.contains(ARG_LOGFILE)) _log.open(stdout); } if (!_args.contains(ARG_LOGLEVEL) && !_args.contains(ARG_LOGFILE)) _log.setLogLevel(Log::Off); /* config directory */ useConfigDir = false; if (dir != "") { setConfigDirectory(dir); } /** Initialize support for language translations. */ //LanguageSupport::initialize(); resetLanguageAndStyle(); /* Switch off auto shutdown */ setQuitOnLastWindowClosed ( false ); /* Initialize GxsIdDetails */ GxsIdDetails::initialize(); }