/*----------------------------------------------------------------------
|   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);
}
Пример #2
0
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();
}