xref: /unit/src/nxt_lib.c (revision 138:59fc46dd5e1d)
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #include <nxt_main.h>
8 
9 
10 nxt_uint_t    nxt_ncpu = 1;
11 nxt_uint_t    nxt_pagesize;
12 nxt_task_t    nxt_main_task;
13 nxt_atomic_t  nxt_task_ident;
14 
15 nxt_thread_declare_data(nxt_thread_t, nxt_thread_context);
16 
17 
18 #if (NXT_DEBUG && NXT_FREEBSD)
19 /*
20  * Fill memory with 0xA5 after malloc() and with 0x5A before free().
21  * malloc() options variable has to override the libc symbol, otherwise
22  * it has no effect.
23  */
24 #if __FreeBSD_version < 1000011
25 const char *_malloc_options = "J";
26 #else
27 const char *malloc_conf = "junk:true";
28 #endif
29 #endif
30 
31 
32 nxt_int_t
33 nxt_lib_start(const char *app, char **argv, char ***envp)
34 {
35     int           n;
36     nxt_int_t     flags;
37     nxt_bool_t    update;
38     nxt_thread_t  *thread;
39 
40     flags = nxt_stderr_start();
41 
42     nxt_log_start(app);
43 
44     nxt_pid = getpid();
45     nxt_ppid = getppid();
46 
47 #if (NXT_DEBUG)
48 
49     nxt_main_log.level = NXT_LOG_DEBUG;
50 
51 #if (NXT_LINUX)
52     /* Fill memory with 0xAA after malloc() and with 0x55 before free(). */
53     mallopt(M_PERTURB, 0x55);
54 #endif
55 
56 #if (NXT_MACOSX)
57     /* Fill memory with 0xAA after malloc() and with 0x55 before free(). */
58     setenv("MallocScribble", "1", 0);
59 #endif
60 
61 #endif /* NXT_DEBUG */
62 
63     /* Thread log is required for nxt_malloc() in nxt_strerror_start(). */
64 
65     nxt_thread_init_data(nxt_thread_context);
66     thread = nxt_thread();
67     thread->log = &nxt_main_log;
68 
69     thread->handle = nxt_thread_handle();
70     thread->time.signal = -1;
71     nxt_thread_time_update(thread);
72 
73     nxt_main_task.thread = thread;
74     nxt_main_task.log = thread->log;
75     nxt_main_task.ident = nxt_task_next_ident();
76 
77     if (nxt_strerror_start() != NXT_OK) {
78         return NXT_ERROR;
79     }
80 
81     if (flags != -1) {
82         nxt_debug(&nxt_main_task, "stderr flags: 0x%04Xd", flags);
83     }
84 
85 #ifdef _SC_NPROCESSORS_ONLN
86     /* Linux, FreeBSD, Solaris, MacOSX. */
87     n = sysconf(_SC_NPROCESSORS_ONLN);
88 
89 #elif (NXT_HPUX)
90     n = mpctl(MPC_GETNUMSPUS, NULL, NULL);
91 
92 #endif
93 
94     nxt_debug(&nxt_main_task, "ncpu: %ui", n);
95 
96     if (n > 1) {
97         nxt_ncpu = n;
98     }
99 
100     nxt_thread_spin_init(nxt_ncpu, 0);
101 
102     nxt_random_init(&thread->random);
103 
104     nxt_pagesize = getpagesize();
105 
106     nxt_debug(&nxt_main_task, "pagesize: %ui", nxt_pagesize);
107 
108     if (argv != NULL) {
109         update = (argv[0] == app);
110 
111         nxt_process_arguments(&nxt_main_task, argv, envp);
112 
113         if (update) {
114             nxt_log_start(nxt_process_argv[0]);
115         }
116     }
117 
118     return NXT_OK;
119 }
120 
121 
122 void
123 nxt_lib_stop(void)
124 {
125     /* TODO: stop engines */
126 
127 #if (NXT_THREADS0)
128 
129     for ( ;; ) {
130         nxt_thread_pool_t  *tp;
131 
132         nxt_thread_spin_lock(&rt->lock);
133 
134         tp = rt->thread_pools;
135         rt->thread_pools = (tp != NULL) ? tp->next : NULL;
136 
137         nxt_thread_spin_unlock(&rt->lock);
138 
139         if (tp == NULL) {
140             break;
141         }
142 
143         nxt_thread_pool_destroy(tp);
144     }
145 
146 #else
147 
148     exit(0);
149     nxt_unreachable();
150 
151 #endif
152 }
153