Sporadically crashes on Windows when exit. Fixes #3177
1) Shutdown the python server properly. 2) Disabled "Shutdown server" menu till server is not successfully started. Initial patch sent by Maxim, modified by Akshay Joshi.pull/9/head
parent
3c4359270e
commit
54b1a79cb6
|
|
@ -328,3 +328,14 @@ void Server::run()
|
|||
fclose(cp);
|
||||
}
|
||||
|
||||
void Server::shutdown(QUrl url)
|
||||
{
|
||||
bool shotdown = shutdownServer(url);
|
||||
if (!shotdown)
|
||||
setError(tr("Failed to shutdown application server thread."));
|
||||
|
||||
QThread::quit();
|
||||
QThread::wait();
|
||||
while(!this->isFinished()){}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ public:
|
|||
bool Init();
|
||||
QString getError() { return m_error; }
|
||||
|
||||
public slots:
|
||||
void shutdown(QUrl url);
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ void TrayIcon::createActions()
|
|||
connect(m_logAction, SIGNAL(triggered()), this, SLOT(onLog()));
|
||||
|
||||
m_quitAction = new QAction(tr("&Shutdown server"), this);
|
||||
m_quitAction->setEnabled(false);
|
||||
connect(m_quitAction, SIGNAL(triggered()), this, SLOT(onQuit()));
|
||||
}
|
||||
|
||||
|
|
@ -239,6 +240,16 @@ void TrayIcon::onQuit()
|
|||
{
|
||||
if (QMessageBox::Yes == QMessageBox::question(this, tr("Shutdown server?"), QString(tr("Are you sure you want to shutdown the %1 server?")).arg(PGA_APP_NAME), QMessageBox::Yes | QMessageBox::No))
|
||||
{
|
||||
// Emit the signal to shutdown the python server.
|
||||
emit shutdownSignal(m_appServerUrl);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void TrayIcon::enableShutdownMenu()
|
||||
{
|
||||
if (m_quitAction != NULL)
|
||||
{
|
||||
m_quitAction->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ public:
|
|||
|
||||
bool Init();
|
||||
void setAppServerUrl(QString appServerUrl);
|
||||
void enableShutdownMenu();
|
||||
|
||||
private:
|
||||
void createTrayIcon();
|
||||
|
|
@ -56,6 +57,9 @@ private slots:
|
|||
void onConfig();
|
||||
void onLog();
|
||||
void onQuit();
|
||||
|
||||
signals:
|
||||
void shutdownSignal(QUrl);
|
||||
};
|
||||
|
||||
#endif // TRAYICON_H
|
||||
|
|
|
|||
|
|
@ -239,6 +239,7 @@ int main(int argc, char * argv[])
|
|||
exit(1);
|
||||
}
|
||||
|
||||
QObject::connect(server, SIGNAL(finished()), server, SLOT(deleteLater()));
|
||||
server->start();
|
||||
|
||||
// This is a hack to give the server a chance to start and potentially fail. As
|
||||
|
|
@ -336,6 +337,8 @@ int main(int argc, char * argv[])
|
|||
|
||||
// Go!
|
||||
trayicon->setAppServerUrl(appServerUrl);
|
||||
// Enable the shutdown server menu as server started successfully.
|
||||
trayicon->enableShutdownMenu();
|
||||
|
||||
QString cmd = settings.value("BrowserCommand").toString();
|
||||
|
||||
|
|
@ -355,6 +358,8 @@ int main(int argc, char * argv[])
|
|||
}
|
||||
}
|
||||
|
||||
QObject::connect(trayicon, SIGNAL(shutdownSignal(QUrl)), server, SLOT(shutdown(QUrl)));
|
||||
|
||||
splash->finish(NULL);
|
||||
|
||||
return app.exec();
|
||||
|
|
@ -435,3 +440,44 @@ unsigned long sdbm(unsigned char *str)
|
|||
|
||||
return hash;
|
||||
}
|
||||
|
||||
// Shutdown the application server
|
||||
bool shutdownServer(QUrl url)
|
||||
{
|
||||
QNetworkAccessManager manager;
|
||||
QEventLoop loop;
|
||||
QNetworkReply *reply;
|
||||
QVariant redirectUrl;
|
||||
|
||||
url.setPath("/misc/shutdown");
|
||||
|
||||
do
|
||||
{
|
||||
reply = manager.get(QNetworkRequest(url));
|
||||
|
||||
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||
loop.exec();
|
||||
|
||||
redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
|
||||
url = redirectUrl.toUrl();
|
||||
|
||||
if (!redirectUrl.isNull())
|
||||
delete reply;
|
||||
|
||||
} while (!redirectUrl.isNull());
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QString response = reply->readAll();
|
||||
|
||||
if (response != "SHUTDOWN")
|
||||
{
|
||||
qDebug() << "Failed to connect, server response: " << response;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,5 +39,6 @@ bool PingServer(QUrl url);
|
|||
void delay(int milliseconds);
|
||||
void cleanup();
|
||||
unsigned long sdbm(unsigned char *str);
|
||||
bool shutdownServer(QUrl url);
|
||||
|
||||
#endif // PGADMIN4_H
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
"""A blueprint module providing utility functions for the application."""
|
||||
|
||||
import pgadmin.utils.driver as driver
|
||||
from flask import url_for, render_template, Response
|
||||
from flask import url_for, render_template, Response, request
|
||||
from flask_babel import gettext
|
||||
from pgadmin.utils import PgAdminModule
|
||||
from pgadmin.utils.preferences import Preferences
|
||||
|
|
@ -116,3 +116,17 @@ def explain_js():
|
|||
status=200,
|
||||
mimetype="application/javascript"
|
||||
)
|
||||
|
||||
##########################################################################
|
||||
# A special URL used to shutdown the server
|
||||
##########################################################################
|
||||
@blueprint.route("/shutdown", methods=('get', 'post'))
|
||||
def shutdown():
|
||||
if config.SERVER_MODE is not True:
|
||||
func = request.environ.get('werkzeug.server.shutdown')
|
||||
if func is None:
|
||||
raise RuntimeError('Not running with the Werkzeug Server')
|
||||
func()
|
||||
return 'SHUTDOWN'
|
||||
else:
|
||||
return ''
|
||||
|
|
|
|||
Loading…
Reference in New Issue