summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_lib.c
blob: aba07dda40f3fd4d496827f541149307efd0131d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

/*
 * Copyright (C) Igor Sysoev
 * Copyright (C) NGINX, Inc.
 */

#include <nxt_main.h>


nxt_uint_t    nxt_ncpu = 1;
nxt_uint_t    nxt_pagesize;
nxt_task_t    nxt_main_task;
nxt_atomic_t  nxt_task_ident;

nxt_thread_declare_data(nxt_thread_t, nxt_thread_context);


#if (NXT_DEBUG && NXT_FREEBSD)
/*
 * Fill memory with 0xA5 after malloc() and with 0x5A before free().
 * malloc() options variable has to override the libc symbol, otherwise
 * it has no effect.
 */
#if __FreeBSD_version < 1000011
const char *_malloc_options = "J";
#else
const char *malloc_conf = "junk:true";
#endif
#endif


nxt_int_t
nxt_lib_start(const char *app, char **argv, char ***envp)
{
    int           n;
    nxt_int_t     flags;
    nxt_bool_t    update;
    nxt_thread_t  *thread;

    flags = nxt_stderr_start();

    nxt_log_start(app);

    nxt_pid = getpid();
    nxt_ppid = getppid();
    nxt_euid = geteuid();
    nxt_egid = getegid();

#if (NXT_DEBUG)

    nxt_main_log.level = NXT_LOG_DEBUG;

#if (NXT_HAVE_MALLOPT)
    /* Fill memory with 0xAA after malloc() and with 0x55 before free(). */
    mallopt(M_PERTURB, 0x55);
#endif

#if (NXT_MACOSX)
    /* Fill memory with 0xAA after malloc() and with 0x55 before free(). */
    setenv("MallocScribble", "1", 0);
#endif

#endif /* NXT_DEBUG */

    /* Thread log is required for nxt_malloc() in nxt_strerror_start(). */

    nxt_thread_init_data(nxt_thread_context);
    thread = nxt_thread();
    thread->log = &nxt_main_log;

    thread->handle = nxt_thread_handle();
    thread->time.signal = -1;
    nxt_thread_time_update(thread);

    nxt_main_task.thread = thread;
    nxt_main_task.log = thread->log;
    nxt_main_task.ident = nxt_task_next_ident();

    if (nxt_strerror_start() != NXT_OK) {
        return NXT_ERROR;
    }

    if (flags != -1) {
        nxt_debug(&nxt_main_task, "stderr flags: 0x%04Xd", flags);
    }

#ifdef _SC_NPROCESSORS_ONLN
    /* Linux, FreeBSD, Solaris, MacOSX. */
    n = sysconf(_SC_NPROCESSORS_ONLN);

#elif (NXT_HPUX)
    n = mpctl(MPC_GETNUMSPUS, NULL, NULL);

#else
    n = 0;

#endif

    nxt_debug(&nxt_main_task, "ncpu: %d", n);

    if (n > 1) {
        nxt_ncpu = n;
    }

    nxt_thread_spin_init(nxt_ncpu, 0);

    nxt_random_init(&thread->random);

    nxt_pagesize = getpagesize();

    nxt_debug(&nxt_main_task, "pagesize: %ui", nxt_pagesize);

    if (argv != NULL) {
        update = (argv[0] == app);

        nxt_process_arguments(&nxt_main_task, argv, envp);

        if (update) {
            nxt_log_start(nxt_process_argv[0]);
        }
    }

    return NXT_OK;
}


void
nxt_lib_stop(void)
{
    /* TODO: stop engines */

#if 0

    for ( ;; ) {
        nxt_thread_pool_t  *tp;

        nxt_thread_spin_lock(&rt->lock);

        tp = rt->thread_pools;
        rt->thread_pools = (tp != NULL) ? tp->next : NULL;

        nxt_thread_spin_unlock(&rt->lock);

        if (tp == NULL) {
            break;
        }

        nxt_thread_pool_destroy(tp);
    }

#else

    exit(0);
    nxt_unreachable();

#endif
}