mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-30 23:40:06 +00:00 
			
		
		
		
	Wait for an initial offset prior to proceeding with initialization
This commit is contained in:
		
							parent
							
								
									88d968a533
								
							
						
					
					
						commit
						c76c9b57ed
					
				
					 3 changed files with 49 additions and 3 deletions
				
			
		|  | @ -17,6 +17,7 @@ void Initialize() | ||||||
|    ntpClient_ = network::NtpClient::Instance(); |    ntpClient_ = network::NtpClient::Instance(); | ||||||
| 
 | 
 | ||||||
|    ntpClient_->Start(); |    ntpClient_->Start(); | ||||||
|  |    ntpClient_->WaitForInitialOffset(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Shutdown() | void Shutdown() | ||||||
|  |  | ||||||
|  | @ -35,6 +35,8 @@ public: | ||||||
|    std::string RotateServer(); |    std::string RotateServer(); | ||||||
|    void        RunOnce(); |    void        RunOnce(); | ||||||
| 
 | 
 | ||||||
|  |    void WaitForInitialOffset(); | ||||||
|  | 
 | ||||||
|    static std::shared_ptr<NtpClient> Instance(); |    static std::shared_ptr<NtpClient> Instance(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |  | ||||||
|  | @ -3,6 +3,9 @@ | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| #include <scwx/util/threads.hpp> | #include <scwx/util/threads.hpp> | ||||||
| 
 | 
 | ||||||
|  | #include <condition_variable> | ||||||
|  | #include <mutex> | ||||||
|  | 
 | ||||||
| #include <boost/asio/ip/udp.hpp> | #include <boost/asio/ip/udp.hpp> | ||||||
| #include <boost/asio/steady_timer.hpp> | #include <boost/asio/steady_timer.hpp> | ||||||
| #include <boost/asio/thread_pool.hpp> | #include <boost/asio/thread_pool.hpp> | ||||||
|  | @ -112,6 +115,8 @@ public: | ||||||
|    void        Run(); |    void        Run(); | ||||||
|    void        RunOnce(); |    void        RunOnce(); | ||||||
| 
 | 
 | ||||||
|  |    void FinishInitialization(); | ||||||
|  | 
 | ||||||
|    boost::asio::thread_pool threadPool_ {2u}; |    boost::asio::thread_pool threadPool_ {2u}; | ||||||
| 
 | 
 | ||||||
|    boost::asio::steady_timer pollTimer_ {threadPool_}; |    boost::asio::steady_timer pollTimer_ {threadPool_}; | ||||||
|  | @ -122,6 +127,10 @@ public: | ||||||
|    bool disableServer_ {false}; |    bool disableServer_ {false}; | ||||||
|    bool rotateServer_ {false}; |    bool rotateServer_ {false}; | ||||||
| 
 | 
 | ||||||
|  |    std::mutex              initializationMutex_ {}; | ||||||
|  |    std::condition_variable initializationCondition_ {}; | ||||||
|  |    std::atomic<bool>       initialized_ {false}; | ||||||
|  | 
 | ||||||
|    types::ntp::NtpPacket transmitPacket_ {}; |    types::ntp::NtpPacket transmitPacket_ {}; | ||||||
| 
 | 
 | ||||||
|    boost::asio::ip::udp::socket                  socket_ {threadPool_}; |    boost::asio::ip::udp::socket                  socket_ {threadPool_}; | ||||||
|  | @ -164,6 +173,14 @@ NtpClient::Impl::Impl() | ||||||
| 
 | 
 | ||||||
|    transmitPacket_.fields.vn   = 3; // Version
 |    transmitPacket_.fields.vn   = 3; // Version
 | ||||||
|    transmitPacket_.fields.mode = 3; // Client (3)
 |    transmitPacket_.fields.mode = 3; // Client (3)
 | ||||||
|  | 
 | ||||||
|  |    // If the NTP client is enabled, wait until the first refresh to consider
 | ||||||
|  |    // "initialized". Otherwise, mark as initialized immediately to prevent a
 | ||||||
|  |    // deadlock.
 | ||||||
|  |    if (!enabled_) | ||||||
|  |    { | ||||||
|  |       initialized_ = true; | ||||||
|  |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| NtpClient::Impl::~Impl() | NtpClient::Impl::~Impl() | ||||||
|  | @ -253,7 +270,7 @@ void NtpClient::Impl::Poll() | ||||||
| { | { | ||||||
|    using namespace std::chrono_literals; |    using namespace std::chrono_literals; | ||||||
| 
 | 
 | ||||||
|    static constexpr auto kTimeout_ = 15s; |    static constexpr auto kTimeout_ = 5s; | ||||||
| 
 | 
 | ||||||
|    try |    try | ||||||
|    { |    { | ||||||
|  | @ -359,8 +376,6 @@ void NtpClient::Impl::ReceivePacket(std::size_t length) | ||||||
|          timeOffset_ = ((t1 - t0) + (t2 - t3)) / 2; |          timeOffset_ = ((t1 - t0) + (t2 - t3)) / 2; | ||||||
| 
 | 
 | ||||||
|          logger_->debug("Time offset updated: {:%jd %T}", timeOffset_); |          logger_->debug("Time offset updated: {:%jd %T}", timeOffset_); | ||||||
| 
 |  | ||||||
|          // TODO: Signal
 |  | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|    else |    else | ||||||
|  | @ -496,6 +511,34 @@ void NtpClient::Impl::RunOnce() | ||||||
|       // Did not poll this frame
 |       // Did not poll this frame
 | ||||||
|       error_ = true; |       error_ = true; | ||||||
|    } |    } | ||||||
|  | 
 | ||||||
|  |    FinishInitialization(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void NtpClient::Impl::FinishInitialization() | ||||||
|  | { | ||||||
|  |    if (!initialized_) | ||||||
|  |    { | ||||||
|  |       // Set initialized to true
 | ||||||
|  |       std::unique_lock lock(initializationMutex_); | ||||||
|  |       initialized_ = true; | ||||||
|  |       lock.unlock(); | ||||||
|  | 
 | ||||||
|  |       // Notify any threads waiting for initialization
 | ||||||
|  |       initializationCondition_.notify_all(); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void NtpClient::WaitForInitialOffset() | ||||||
|  | { | ||||||
|  |    std::unique_lock lock(p->initializationMutex_); | ||||||
|  | 
 | ||||||
|  |    // While not yet initialized
 | ||||||
|  |    while (!p->initialized_) | ||||||
|  |    { | ||||||
|  |       // Wait for initialization
 | ||||||
|  |       p->initializationCondition_.wait(lock); | ||||||
|  |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::shared_ptr<NtpClient> NtpClient::Instance() | std::shared_ptr<NtpClient> NtpClient::Instance() | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat