diff --git a/src/ankiconnector.cc b/src/ankiconnector.cc index a6ba7f0e8..17f7ea10a 100644 --- a/src/ankiconnector.cc +++ b/src/ankiconnector.cc @@ -3,6 +3,7 @@ #include #include #include "utils.hh" +#include "global_network_access_manager.hh" QString markTargetWord( QString const & sentence, QString const & word ) { @@ -12,10 +13,10 @@ QString markTargetWord( QString const & sentence, QString const & word ) } AnkiConnector::AnkiConnector( QObject * parent, Config::Class const & _cfg ): - QObject{ parent }, + QObject{parent}, cfg( _cfg ) { - mgr = new QNetworkAccessManager( this ); + mgr = GlobalNetworkAccessManager; connect( mgr, &QNetworkAccessManager::finished, this, &AnkiConnector::finishedSlot ); } @@ -119,4 +120,4 @@ void AnkiConnector::finishedSlot( QNetworkReply * reply ) } reply->deleteLater(); -} +} \ No newline at end of file diff --git a/src/global_network_access_manager.hh b/src/global_network_access_manager.hh new file mode 100644 index 000000000..60a22ed02 --- /dev/null +++ b/src/global_network_access_manager.hh @@ -0,0 +1,21 @@ +#pragma once + +#include + +/* + * Notes: + * + * This MUST be used only in the main/UI thread + * + * Retaining a pointer in objects to this globalNetworkAccessManager is OK. + * Having a pointer to it reduce minor overhead of global object accessing. + * + */ + +#if ( QT_VERSION < QT_VERSION_CHECK( 6, 4, 0 ) ) +Q_GLOBAL_STATIC( QNetworkAccessManager, GlobalNetworkAccessManager ); +#else +#include +Q_APPLICATION_STATIC( QNetworkAccessManager, GlobalNetworkAccessManager ); + +#endif \ No newline at end of file diff --git a/src/iframeschemehandler.cc b/src/iframeschemehandler.cc index 6f97e1716..d2a8520d3 100644 --- a/src/iframeschemehandler.cc +++ b/src/iframeschemehandler.cc @@ -1,7 +1,10 @@ #include "iframeschemehandler.hh" +#include #include +#include "global_network_access_manager.hh" + IframeSchemeHandler::IframeSchemeHandler( QObject * parent ): QWebEngineUrlSchemeHandler( parent ) { @@ -17,7 +20,8 @@ void IframeSchemeHandler::requestStarted( QWebEngineUrlRequestJob * requestJob ) request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy ); - QNetworkReply * reply = mgr.get( request ); + QNetworkReply * reply = GlobalNetworkAccessManager->get( request ); + std::cout<< "thread ID" << std::this_thread::get_id() << std::endl; auto finishAction = [ = ]() { QByteArray contentType = "text/html"; diff --git a/src/iframeschemehandler.hh b/src/iframeschemehandler.hh index 700de6aed..3cf36dbcc 100644 --- a/src/iframeschemehandler.hh +++ b/src/iframeschemehandler.hh @@ -10,11 +10,6 @@ class IframeSchemeHandler: public QWebEngineUrlSchemeHandler public: IframeSchemeHandler( QObject * parent = nullptr ); void requestStarted( QWebEngineUrlRequestJob * requestJob ); - -protected: - -private: - QNetworkAccessManager mgr; }; #endif // IFRAMESCHEMEHANDLER_H diff --git a/src/ui/mainwindow.cc b/src/ui/mainwindow.cc index 0e615f5ba..af6d82c78 100644 --- a/src/ui/mainwindow.cc +++ b/src/ui/mainwindow.cc @@ -6,7 +6,7 @@ #ifndef NO_EPWING_SUPPORT #include "dict/epwing_book.hh" #endif - +#include #include "mainwindow.hh" #include #include "editdictionaries.hh" @@ -16,25 +16,16 @@ #include "mruqmenu.hh" #include "gestures.hh" #include "dictheadwords.hh" -#include -#include -#include + #include -#include -#include #include #include #include -#include -#include #include #include #include #include #include -#include -#include -#include #include #include "weburlrequestinterceptor.hh" #include "folding.hh" @@ -49,8 +40,7 @@ #include "help.hh" #include "ui_authentication.h" #include "resourceschemehandler.hh" -#include - +#include "global_network_access_manager.hh" #include "globalregex.hh" #ifdef Q_OS_MAC @@ -161,7 +151,6 @@ MainWindow::MainWindow( Config::Class & cfg_ ): articleMaker, cfg.preferences.disallowContentFromOtherSites, cfg.preferences.hideGoldenDictHeader ), - dictNetMgr( this ), audioPlayerFactory( cfg.preferences ), wordFinder( this ), wordListSelChanged( false ), @@ -180,8 +169,13 @@ MainWindow::MainWindow( Config::Class & cfg_ ): GlobalBroadcaster::instance()->setPreference( &cfg.preferences ); - localSchemeHandler = new LocalSchemeHandler( articleNetMgr, this ); - QStringList htmlScheme = { "gdlookup", "bword", "entry" }; + + // Ensure globalNetworkAccessManager initalized on the UI theread by doing something with side effect. + qDebug() << "Initalized: " << GlobalNetworkAccessManager->metaObject()->className(); + std::cout<< "Main thread ID" << std::this_thread::get_id() << std::endl; + + localSchemeHandler = new LocalSchemeHandler( articleNetMgr, this ); + QStringList htmlScheme = {"gdlookup", "bword", "entry"}; for ( const auto & localScheme : htmlScheme ) { QWebEngineProfile::defaultProfile()->installUrlSchemeHandler( localScheme.toLatin1(), localSchemeHandler ); } @@ -717,7 +711,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ): //set webengineview font changeWebEngineViewFont(); - connect( &dictNetMgr, &QNetworkAccessManager::proxyAuthenticationRequired, this, &MainWindow::proxyAuthentication ); + connect( GlobalNetworkAccessManager, &QNetworkAccessManager::proxyAuthenticationRequired, this, &MainWindow::proxyAuthentication ); connect( &articleNetMgr, &QNetworkAccessManager::proxyAuthenticationRequired, @@ -1518,7 +1512,7 @@ void MainWindow::makeDictionaries() ftsIndexing.stopIndexing(); ftsIndexing.clearDictionaries(); - loadDictionaries( this, isVisible(), cfg, dictionaries, dictNetMgr, false ); + loadDictionaries( this, isVisible(), cfg, dictionaries, *GlobalNetworkAccessManager, false ); //create map dictMap = Dictionary::dictToMap( dictionaries ); @@ -2090,7 +2084,7 @@ void MainWindow::editDictionaries( unsigned editDictionaryGroup ) { // Limit existence of newCfg Config::Class newCfg = cfg; - EditDictionaries dicts( this, newCfg, dictionaries, groupInstances, dictNetMgr ); + EditDictionaries dicts( this, newCfg, dictionaries, groupInstances, *GlobalNetworkAccessManager ); connect( &dicts, &EditDictionaries::showDictionaryInfo, this, &MainWindow::showDictionaryInfo ); @@ -2850,7 +2844,7 @@ void MainWindow::checkNewRelease() // github_release_api.setRawHeader( QByteArray( "Authorization" ), QByteArray( "" ) ); github_release_api.setRawHeader( QByteArray( "X-GitHub-Api-Version" ), QByteArray( "2022-11-28" ) ); - auto * github_reply = dictNetMgr.get( github_release_api ); // will be marked as deleteLater when reply finished. + auto * github_reply = GlobalNetworkAccessManager->get( github_release_api ); // will be marked as deleteLater when reply finished. QObject::connect( github_reply, &QNetworkReply::finished, [ github_reply, this ]() { if ( github_reply->error() != QNetworkReply::NoError ) { @@ -3277,7 +3271,7 @@ void MainWindow::on_rescanFiles_triggered() dictionariesUnmuted.clear(); dictionaryBar.setDictionaries( dictionaries ); - loadDictionaries( this, true, cfg, dictionaries, dictNetMgr ); + loadDictionaries( this, true, cfg, dictionaries, *GlobalNetworkAccessManager ); dictMap = Dictionary::dictToMap( dictionaries ); for ( unsigned x = 0; x < dictionaries.size(); x++ ) { diff --git a/src/ui/mainwindow.hh b/src/ui/mainwindow.hh index 1af063c89..1b46b73ac 100644 --- a/src/ui/mainwindow.hh +++ b/src/ui/mainwindow.hh @@ -137,9 +137,7 @@ private: Instances::Groups groupInstances; ArticleMaker articleMaker; ArticleNetworkAccessManager articleNetMgr; - QNetworkAccessManager dictNetMgr; // We give dictionaries a separate manager, - // since their requests can be destroyed - // in a separate thread + AudioPlayerFactory audioPlayerFactory; //current active translateLine;