Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CoreServices initalisation order #4058

Merged
merged 13 commits into from
Aug 1, 2021
Merged
37 changes: 22 additions & 15 deletions src/coreservices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ inline QLocale inputLocale() {
namespace mixxx {

CoreServices::CoreServices(const CmdlineArgs& args)
: m_runtime_timer(QLatin1String("CoreServices::runtime")),
: m_pLV2Backend(nullptr),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should initialize this plain pointer in the header with LV2Backend* m_pLV2Backend{};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EffectsBackends don't even belong here. This is fixed in #2618. DlgPrefLV2 has been removed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not touch any effects code before merging #2618. I refuse to fix any merge conflicts from others doing so.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should initialize this plain pointer in the header with LV2Backend* m_pLV2Backend{};

In Mixxx we only header initialization with exceptions because this introduces a hidden static constructor.
https://github.com/mixxxdj/mixxx/wiki/Coding-Guidelines#non-static-data-member-initializers

Copy link
Contributor

@uklotzde uklotzde Jul 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I strongly disagree. It doesn't make any sense to repeat all plain pointer members and initialize them explicitly with nullptr. This introduces useless noise. It's much more safe to initialize them directly, especially if you have many of them, see WTrackMenu. By using managed pointers this issue will hopefully disappear over time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should revise the coding guidelines. Neither do I understand the motivation nor the issue that should be solved.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"...is used if the member is omitted from the member initializer list of a constructor".

What's wrong with providing a sensible default value to prevent uninitialized members???

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole discussion about what to do with the pointer is moot. It is removed from this code already in #2618.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's wrong with providing a sensible default value to prevent uninitialized members???

Nothing.

The question is just where it should be done.
The normal or lets say legacy place is the initialization list in the constructor.
If we keep this habit we have a single place to look at.

Here we have the case where some variables are const initialized and some from parameter values. So you need to look at two places. The header initialization causes an extra static inline constructor and forces recompile more files if we change that value.

The solution in WTrackMenu initializes many pointers twice. One time the stat inline constructor and one time in the real constructor. This is IMHO even more an issue, because the reader might think that he has to deal with a null pointer when he looks into the header which is not the case.

I am not opposing to adjust our policy if we have sensible new ideas. But for now I like to keep the current solution here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to choose the header-only modification for minimizing the amount of changes and potential merge conflicts. In the end it doesn't matter, so let's be pragmatic.

m_runtime_timer(QLatin1String("CoreServices::runtime")),
m_cmdlineArgs(args) {
}

Expand All @@ -122,11 +123,7 @@ void CoreServices::initializeSettings() {
m_pSettingsManager = std::make_unique<SettingsManager>(settingsPath);
}

void CoreServices::initialize(QApplication* pApp) {
m_runtime_timer.start();
mixxx::Time::start();
ScopedTimer t("CoreServices::initialize");

void CoreServices::initializeLogging() {
mixxx::LogFlags logFlags = mixxx::LogFlag::LogToFile;
if (m_cmdlineArgs.getDebugAssertBreak()) {
logFlags.setFlag(mixxx::LogFlag::DebugAssertBreak);
Expand All @@ -136,6 +133,25 @@ void CoreServices::initialize(QApplication* pApp) {
m_cmdlineArgs.getLogLevel(),
m_cmdlineArgs.getLogFlushLevel(),
logFlags);
}

void CoreServices::preInitialize(QApplication* pApp) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this method really necessary? Couldn't we just make it part of the CoreServices constructor?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any need to create the CoreServices object before creating a QApplication? If not, we should move this into the constructor. Less possibilities to use this class wrong or miss an initialization step.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There does not seem to be a purpose for this method. Move the code directly into the constructor.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is just documentation support.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this makes the code more readable; it makes me wonder why the function exists. I think it would be better to move the code into the constructor and add a comment: "These need to be initialized before the GUI. They are fast to initialize. Everything else is deferred to the initialize method so the GUI can show the progress."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the current state.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't to bike-shed, but

  • it only contains the body of the constructor, which now contains just this single invocation and
  • the method is public although it doesn't need to be.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function is private.

ScopedTimer t("CoreServices::preInitialize");
initializeSettings();
initializeLogging();
// Only record stats in developer mode.
if (m_cmdlineArgs.getDeveloper()) {
StatsManager::createInstance();
}
mixxx::Translations::initializeTranslations(
m_pSettingsManager->settings(), pApp, m_cmdlineArgs.getLocale());
initializeKeyboard();
}

void CoreServices::initialize(QApplication* pApp) {
uklotzde marked this conversation as resolved.
Show resolved Hide resolved
m_runtime_timer.start();
mixxx::Time::start();
ScopedTimer t("CoreServices::initialize");

VERIFY_OR_DEBUG_ASSERT(SoundSourceProxy::registerProviders()) {
qCritical() << "Failed to register any SoundSource providers";
Expand All @@ -144,15 +160,6 @@ void CoreServices::initialize(QApplication* pApp) {

VersionStore::logBuildDetails();

// Only record stats in developer mode.
if (m_cmdlineArgs.getDeveloper()) {
StatsManager::createInstance();
}

initializeKeyboard();

mixxx::Translations::initializeTranslations(
m_pSettingsManager->settings(), pApp, m_cmdlineArgs.getLocale());

#if defined(Q_OS_LINUX)
// XESetWireToError will segfault if running as a Wayland client
Expand Down
6 changes: 5 additions & 1 deletion src/coreservices.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,12 @@ class CoreServices : public QObject {
~CoreServices() = default;

void initializeSettings();
// FIXME: should be private, but WMainMenuBar needs it initialized early
void initializeKeyboard();
void initializeLogging();

// The short first run that is done without start up screen
void preInitialize(QApplication* pApp);
// The secondary long run which should be called after displaying the start up screen
void initialize(QApplication* pApp);
Holzhaus marked this conversation as resolved.
Show resolved Hide resolved
void shutdown();

Expand Down
3 changes: 1 addition & 2 deletions src/mixxx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ MixxxMainWindow::MixxxMainWindow(
m_toolTipsCfg(mixxx::TooltipsPreference::TOOLTIPS_ON) {
DEBUG_ASSERT(pApp);
DEBUG_ASSERT(pCoreServices);
m_pCoreServices->initializeSettings();
m_pCoreServices->initializeKeyboard();
m_pCoreServices->preInitialize(pApp);
// These depend on the settings
createMenuBar();
m_pMenuBar->hide();
Expand Down