/*---------------------------------------------------------------------- | TestMisc +---------------------------------------------------------------------*/ static void TestMisc() { NPT_DateTime date; NPT_TimeStamp ts; NPT_String s; NPT_System::GetCurrentTimeStamp(ts); SHOULD_SUCCEED(date.FromTimeStamp(ts, false)); s = date.ToString(NPT_DateTime::FORMAT_W3C); NPT_Console::OutputF("%s\n", s.GetChars()); s = date.ToString(NPT_DateTime::FORMAT_ANSI); NPT_Console::OutputF("%s\n", s.GetChars()); s = date.ToString(NPT_DateTime::FORMAT_RFC_1036); NPT_Console::OutputF("%s\n", s.GetChars()); s = date.ToString(NPT_DateTime::FORMAT_RFC_1123); NPT_Console::OutputF("%s\n", s.GetChars()); SHOULD_SUCCEED(date.FromTimeStamp(ts, true)); s = date.ToString(NPT_DateTime::FORMAT_W3C); NPT_Console::OutputF("%s\n", s.GetChars()); s = date.ToString(NPT_DateTime::FORMAT_ANSI); NPT_Console::OutputF("%s\n", s.GetChars()); s = date.ToString(NPT_DateTime::FORMAT_RFC_1036); NPT_Console::OutputF("%s\n", s.GetChars()); s = date.ToString(NPT_DateTime::FORMAT_RFC_1123); NPT_Console::OutputF("%s\n", s.GetChars()); ts = 0.0; SHOULD_SUCCEED(date.FromTimeStamp(ts, false)); s = date.ToString(NPT_DateTime::FORMAT_W3C); SHOULD_EQUAL_S(s.GetChars(), "1970-01-01T00:00:00Z"); s = date.ToString(NPT_DateTime::FORMAT_ANSI); SHOULD_EQUAL_S(s.GetChars(), "Thu Jan 1 00:00:00 1970"); s = date.ToString(NPT_DateTime::FORMAT_RFC_1036); SHOULD_EQUAL_S(s.GetChars(), "Thursday, 01-Jan-70 00:00:00 GMT"); s = date.ToString(NPT_DateTime::FORMAT_RFC_1123); SHOULD_EQUAL_S(s.GetChars(), "Thu, 01 Jan 1970 00:00:00 GMT"); ts.SetSeconds(0xFFFFFFFF); SHOULD_SUCCEED(date.FromTimeStamp(ts, false)); s = date.ToString(NPT_DateTime::FORMAT_W3C, false); SHOULD_EQUAL_S(s.GetChars(), "2106-02-07T06:28:15Z"); NPT_TimeStamp now; NPT_System::GetCurrentTimeStamp(now); NPT_DateTime now_local(now, true); NPT_DateTime now_utc(now, false); SHOULD_EQUAL_I(now_utc.m_TimeZone, 0); NPT_TimeStamp ts1, ts2; now_local.ToTimeStamp(ts1); now_utc.ToTimeStamp(ts2); SHOULD_EQUAL_I((int)ts1.ToSeconds(), (int)ts2.ToSeconds()); ts.SetSeconds(0); NPT_DateTime d1(ts); ts.SetSeconds(ts.ToSeconds()-3600); NPT_DateTime d2(ts); d1.ToTimeStamp(ts1); d2.ToTimeStamp(ts2); SHOULD_EQUAL_I((int)ts1.ToSeconds(), (int)ts2.ToSeconds()+3600); }
void logger::run() { utxx::signal_block block_signals(m_block_signals); if (m_on_before_run) m_on_before_run(); if (!m_ident.empty()) pthread_setname_np(pthread_self(), m_ident.c_str()); int event_val; do { event_val = m_event.value(); //wakeup_result rc = wakeup_result::TIMEDOUT; while (!m_abort && m_queue.empty()) { m_event.wait(&m_wait_timeout, &event_val); ASYNC_DEBUG_TRACE( (" %s LOGGER awakened (res=%s, val=%d, futex=%d), abort=%d, head=%s\n", timestamp::to_string().c_str(), to_string(rc).c_str(), event_val, m_event.value(), m_abort, m_queue.empty() ? "empty" : "data") ); } // When running with maximum priority, occasionally excessive use of // sched_yield may use to system slowdown, so this option is // configurable by m_sched_yield_us: if (m_queue.empty() && m_sched_yield_us >= 0) { time_val deadline(rel_time(0, m_sched_yield_us)); while (m_queue.empty()) { if (m_abort) goto DONE; if (now_utc() > deadline) break; sched_yield(); } } // Get all pending items from the queue for (auto* item = m_queue.pop_all(), *next=item; item; item = next) { next = item->next(); try { dolog_msg(item->data()); } catch ( std::exception const& e ) { // Unhandled error writing data to some destination // Print error report to stderr (can't do anything better -- // the error happened in the m_on_error callback!) const msg msg(LEVEL_INFO, "", std::string("Fatal exception in logger"), UTXX_LOG_SRCINFO); detail::basic_buffered_print<1024> buf; char pfx[256], sfx[256]; char* p = format_header(msg, pfx, pfx + sizeof(pfx)); char* q = format_footer(msg, sfx, sfx + sizeof(sfx)); auto ps = p - pfx; auto qs = q - sfx; buf.reserve(msg.m_fun.str.size() + ps + qs + 1); buf.sprint(pfx, ps); buf.print(msg.m_fun.str); buf.sprint(sfx, qs); std::cerr << buf.str() << std::endl; m_abort = true; // TODO: implement attempt to store transient messages to some // other medium // Free all pending messages while (item) { m_queue.free(item); item = next; next = item->next(); } goto DONE; } m_queue.free(item); item = next; } } while (!m_abort); DONE: if (!m_silent_finish) { const msg msg(LEVEL_INFO, "", std::string("Logger thread finished"), UTXX_LOG_SRCINFO); try { dolog_msg(msg); } catch (...) {} } if (m_on_after_run) m_on_after_run(); }