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

Windows: flush_every stops working when adjusting system clock backwards #1200

Open
kbridge opened this issue Aug 30, 2019 · 13 comments
Open

Comments

@kbridge
Copy link

kbridge commented Aug 30, 2019

Tested using VS2017.

To reproduce:

#include <iostream>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <windows.h>

int main()
{
	// use Bash from Git for Windows
	//
	// $ touch app.log
	// $ tail -f app.log

	auto file_logger = spdlog::basic_logger_mt("default", "app.log");
	spdlog::set_default_logger(file_logger);
	
	spdlog::flush_every(std::chrono::seconds(1));

	spdlog::info("first");

	// change system time to an earlier point, then press enter
	//
	// C:\>time 10:00

	getchar();

	// then you won't see this line

	spdlog::info("second");

	for (;;) { Sleep(1000); }
	return 0;
}

Similar to issue #609. But caused by MSVC's buggy implementation of std::condition_variable::wait_for. (According to cppreference, this function must use a steady clock.)

File periodic_worker-inl.h:

SPDLOG_INLINE periodic_worker::periodic_worker(const std::function<void()> &callback_fun, std::chrono::seconds interval)
{
    active_ = (interval > std::chrono::seconds::zero());
    if (!active_)
    {
        return;
    }

    worker_thread_ = std::thread([this, callback_fun, interval]() {
        for (;;)
        {
            std::unique_lock<std::mutex> lock(this->mutex_);
            // ↓ THIS LINE
            if (this->cv_.wait_for(lock, interval, [this] { return !this->active_; }))
            {
                return; // active_ == false, so exit this thread
            }
            callback_fun();
        }
    });
}

I try to replace std::mutex & std::condition_variable to CRITICAL_SECTION & CONDITION_VARIABLE, then the problem disappears.

@kbridge
Copy link
Author

kbridge commented Aug 30, 2019

@gabime
Copy link
Owner

gabime commented Aug 30, 2019

Thanks. Seems very similar #947 isn't it?

@kbridge
Copy link
Author

kbridge commented Aug 30, 2019

Yes. Can't believe g++ has the same issue. These buggy standard libraries... 😞

@kbridge
Copy link
Author

kbridge commented Aug 30, 2019

@gabime Would you like to add a workaround, or leave this to standard library implementors?

@gabime
Copy link
Owner

gabime commented Aug 30, 2019

Lets leave it - it will never end if spdlog try to reimplement buggy standard lib features.
I think it out of spdlog’s scope..

@kbridge
Copy link
Author

kbridge commented Aug 30, 2019

Of course this is out of spdlog's scope!

To be helpful, let me post my workaround here, for people who suffer. Then we can close this issue.

@gabime
Copy link
Owner

gabime commented Aug 30, 2019

Sure. Thanks. if you could make it portable to gcc as well, it would be super!

@kbridge
Copy link
Author

kbridge commented Aug 30, 2019

spdlog periodic_worker workaround for MSVC

https://gist.github.com/kbridge/251808f0cb7411782c3a2ce5f4877287

@kbridge
Copy link
Author

kbridge commented Aug 30, 2019

I think I will try someday, or maybe someone else. I'm a Windows programmer. Haven't been working with pthreads for a long time.

@kbridge kbridge closed this as completed Aug 30, 2019
@gabime
Copy link
Owner

gabime commented Aug 30, 2019

I will leave this open. Its important for users to be aware of this.

@gabime gabime reopened this Aug 30, 2019
@gabime
Copy link
Owner

gabime commented Aug 30, 2019

duplicate of #947

@omnaladkar
Copy link

duplicate of#947

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants