
/*
 * Copyright (C) Igor Sysoev
 */


#include <ngx_config.h>
#include <ngx_core.h>


ngx_msec_t        ngx_current_time;

ngx_int_t         ngx_gmtoff;

static ngx_tm_t   ngx_cached_gmtime;


/*
 * In the threaded mode only one thread updates the cached time and strings
 * and these operations are protected by the mutex.  The reading of the cached
 * time and strings is not protected by the mutex.  To avoid the race
 * conditions for non-atomic values we use the NGX_TIME_SLOTS slots to store
 * time value and strings.  Thus thread may get the corrupted values only
 * if it is preempted while copying and then it is not scheduled to run
 * more than NGX_TIME_SLOTS seconds.
 */

#if (NGX_THREADS)

#define NGX_TIME_SLOTS  60
static ngx_uint_t       slot = NGX_TIME_SLOTS;

static ngx_mutex_t     *ngx_time_mutex;

#else

#define NGX_TIME_SLOTS  1
#define slot            0

#endif


#if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE))

volatile time_t  *ngx_cached_time;
static time_t     cached_time[NGX_TIME_SLOTS];

#else

volatile time_t   ngx_cached_time;

#endif


ngx_thread_volatile ngx_str_t  ngx_cached_err_log_time;
ngx_thread_volatile ngx_str_t  ngx_cached_http_time;
ngx_thread_volatile ngx_str_t  ngx_cached_http_log_time;


static u_char  cached_err_log_time[NGX_TIME_SLOTS]
                                  [sizeof("1970/09/28 12:00:00")];
static u_char  cached_http_time[NGX_TIME_SLOTS]
                                  [sizeof("Mon, 28 Sep 1970 06:00:00 GMT")];
static u_char  cached_http_log_time[NGX_TIME_SLOTS]
                                  [sizeof("28/Sep/1970:12:00:00 +0600")];


static char  *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
static char  *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                           "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

void
ngx_time_init(void)
{
    struct timeval  tv;

    ngx_memzero(&ngx_cached_gmtime, sizeof(ngx_tm_t));
#ifdef ngx_tm_zone
    ngx_cached_gmtime.ngx_tm_zone = "GMT";
#endif

    ngx_cached_err_log_time.len = sizeof("1970/09/28 12:00:00") - 1;
    ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1;
    ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1;

#if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE))
    ngx_cached_time = &cached_time[0];
#endif

    ngx_gettimeofday(&tv);

    ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;

#if !(NGX_WIN32)
    tzset();
#endif

    ngx_time_update(tv.tv_sec);
}


#if (NGX_THREADS)

ngx_int_t
ngx_time_mutex_init(ngx_log_t *log)
{
    ngx_time_mutex = ngx_mutex_init(log, NGX_MUTEX_LIGHT);

    if (ngx_time_mutex == NULL) {
        return NGX_ERROR;
    }

    return NGX_OK;
}

#endif


void
ngx_time_update(time_t s)
{
    u_char    *p;
    ngx_tm_t   tm;

    if (ngx_time() == s) {
        return;
    }

#if (NGX_THREADS)

    if (ngx_mutex_trylock(ngx_time_mutex) != NGX_OK) {
        return;
    }

    if (slot == NGX_TIME_SLOTS) {
        slot = 0;
    } else {
        slot++;
    }

#if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE))
    ngx_cached_time = &cached_time[slot];
#endif

#endif

    ngx_time() = s;

    ngx_gmtime(s, &ngx_cached_gmtime);


    p = cached_http_time[slot];

    (void) ngx_sprintf(p, "%s, %02d %s %4d %02d:%02d:%02d GMT",
                       week[ngx_cached_gmtime.ngx_tm_wday],
                       ngx_cached_gmtime.ngx_tm_mday,
                       months[ngx_cached_gmtime.ngx_tm_mon - 1],
                       ngx_cached_gmtime.ngx_tm_year,
                       ngx_cached_gmtime.ngx_tm_hour,
                       ngx_cached_gmtime.ngx_tm_min,
                       ngx_cached_gmtime.ngx_tm_sec);

    ngx_cached_http_time.data = p;


#if (NGX_HAVE_GETTIMEZONE)

    ngx_gmtoff = ngx_gettimezone();
    ngx_gmtime(s + ngx_gmtoff * 60, &tm);

#elif (NGX_HAVE_GMTOFF)

    ngx_localtime(&tm);
    ngx_gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);

#else

    ngx_localtime(&tm);
    ngx_gmtoff = ngx_timezone(tm.ngx_tm_isdst);

#endif


    p = cached_err_log_time[slot];

    (void) ngx_sprintf(p, "%4d/%02d/%02d %02d:%02d:%02d",
                       tm.ngx_tm_year, tm.ngx_tm_mon,
                       tm.ngx_tm_mday, tm.ngx_tm_hour,
                       tm.ngx_tm_min, tm.ngx_tm_sec);

    ngx_cached_err_log_time.data = p;


    p = cached_http_log_time[slot];

    (void) ngx_sprintf(p, "%02d/%s/%d:%02d:%02d:%02d %c%02d%02d",
                       tm.ngx_tm_mday, months[tm.ngx_tm_mon - 1],
                       tm.ngx_tm_year, tm.ngx_tm_hour,
                       tm.ngx_tm_min, tm.ngx_tm_sec,
                       ngx_gmtoff < 0 ? '-' : '+',
                       abs(ngx_gmtoff / 60), abs(ngx_gmtoff % 60));

    ngx_cached_http_log_time.data = p;


#if (NGX_THREADS)
    ngx_mutex_unlock(ngx_time_mutex);
#endif

}


u_char *
ngx_http_time(u_char *buf, time_t t)
{
    ngx_tm_t  tm;

    ngx_gmtime(t, &tm);

    return ngx_sprintf(buf, "%s, %02d %s %4d %02d:%02d:%02d GMT",
                       week[tm.ngx_tm_wday],
                       tm.ngx_tm_mday,
                       months[tm.ngx_tm_mon - 1],
                       tm.ngx_tm_year,
                       tm.ngx_tm_hour,
                       tm.ngx_tm_min,
                       tm.ngx_tm_sec);
}


u_char *
ngx_http_cookie_time(u_char *buf, time_t t)
{
    ngx_tm_t  tm;

    ngx_gmtime(t, &tm);

    /*
     * Netscape 3.x does not understand 4-digit years at all and
     * 2-digit years more than "37"
     */

    return ngx_sprintf(buf,
                       (tm.ngx_tm_year > 2037) ?
                                         "%s, %02d-%s-%d %02d:%02d:%02d GMT":
                                         "%s, %02d-%s-%02d %02d:%02d:%02d GMT",
                       week[tm.ngx_tm_wday],
                       tm.ngx_tm_mday,
                       months[tm.ngx_tm_mon - 1],
                       (tm.ngx_tm_year > 2037) ? tm.ngx_tm_year:
                                                 tm.ngx_tm_year % 100,
                       tm.ngx_tm_hour,
                       tm.ngx_tm_min,
                       tm.ngx_tm_sec);
}


void
ngx_gmtime(time_t t, ngx_tm_t *tp)
{
    ngx_int_t  sec, min, hour, mday, mon, year, wday, yday, days;

    days = t / 86400;

    /* Jaunary 1, 1970 was Thursday */
    wday = (4 + days) % 7;

    t %= 86400;
    hour = t / 3600;
    t %= 3600;
    min = t / 60;
    sec = t % 60;

    /* the algorithm based on Gauss's formula */

    days = days - (31 + 28) + 719527;

    year = days * 400 / (365 * 400 + 100 - 4 + 1);
    yday = days - (365 * year + year / 4 - year / 100 + year / 400);

    mon = (yday + 31) * 12 / 367;
    mday = yday - (mon * 367 / 12 - 31);

    mon += 2;

    if (yday >= 306) {

        /*
         * there is no "yday" in Win32 SYSTEMTIME
         *
         * yday -= 306;
         */

        year++;
        mon -= 12;

        if (mday == 0) {
            /* Jaunary 31 */
            mon = 1;
            mday = 31;

        } else if (mon == 2) {

            if ((year % 4 == 0) && (year % 100 || (year % 400 == 0))) {
                if (mday > 29) {
                    mon = 3;
                    mday -= 29;
                }

            } else if (mday > 28) {
                mon = 3;
                mday -= 28;
            }
        }
/*
 *  there is no "yday" in Win32 SYSTEMTIME
 *
 *  } else {
 *      yday += 31 + 28;
 *
 *      if ((year % 4 == 0) && (year % 100 || (year % 400 == 0))) {
 *          yday++;
 *      }
 */
    }

    tp->ngx_tm_sec = (ngx_tm_sec_t) sec;
    tp->ngx_tm_min = (ngx_tm_min_t) min;
    tp->ngx_tm_hour = (ngx_tm_hour_t) hour;
    tp->ngx_tm_mday = (ngx_tm_mday_t) mday;
    tp->ngx_tm_mon = (ngx_tm_mon_t) mon;
    tp->ngx_tm_year = (ngx_tm_year_t) year;
    tp->ngx_tm_wday = (ngx_tm_wday_t) wday;
}
