1 | /* |
2 | * This Source Code Form is subject to the terms of the Mozilla Public |
3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
5 | * |
6 | * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V. |
7 | */ |
8 | |
9 | /* (author) M. Kersten */ |
10 | #include "monetdb_config.h" |
11 | #include "mal.h" |
12 | |
13 | char monet_cwd[FILENAME_MAX] = { 0 }; |
14 | char monet_characteristics[4096]; |
15 | stream *maleventstream = 0; |
16 | |
17 | /* The compile time debugging flags are turned into bit masks, akin to GDK */ |
18 | lng MALdebug; |
19 | lng OPTdebug; |
20 | |
21 | #ifdef HAVE_HGE |
22 | int have_hge; |
23 | #endif |
24 | |
25 | #include "mal_stack.h" |
26 | #include "mal_linker.h" |
27 | #include "mal_authorize.h" |
28 | #include "mal_session.h" |
29 | #include "mal_scenario.h" |
30 | #include "mal_parser.h" |
31 | #include "mal_interpreter.h" |
32 | #include "mal_namespace.h" /* for initNamespace() */ |
33 | #include "mal_profiler.h" |
34 | #include "mal_client.h" |
35 | #include "msabaoth.h" |
36 | #include "mal_dataflow.h" |
37 | #include "mal_private.h" |
38 | #include "mal_runtime.h" |
39 | #include "mal_resource.h" |
40 | #include "wlc.h" |
41 | #include "mal_atom.h" |
42 | #include "opt_pipes.h" |
43 | #include "tablet.h" |
44 | |
45 | MT_Lock mal_contextLock = MT_LOCK_INITIALIZER("mal_contextLock" ); |
46 | MT_Lock mal_remoteLock = MT_LOCK_INITIALIZER("mal_remoteLock" ); |
47 | MT_Lock mal_profileLock = MT_LOCK_INITIALIZER("mal_profileLock" ); |
48 | MT_Lock mal_copyLock = MT_LOCK_INITIALIZER("mal_copyLock" ); |
49 | MT_Lock mal_delayLock = MT_LOCK_INITIALIZER("mal_delayLock" ); |
50 | MT_Lock mal_oltpLock = MT_LOCK_INITIALIZER("mal_oltpLock" ); |
51 | |
52 | /* |
53 | * Initialization of the MAL context |
54 | */ |
55 | |
56 | int mal_init(void){ |
57 | /* Any error encountered here terminates the process |
58 | * with a message sent to stderr |
59 | */ |
60 | if (!MCinit()) |
61 | return -1; |
62 | #ifndef NDEBUG |
63 | if (!mdbInit()) { |
64 | mal_client_reset(); |
65 | return -1; |
66 | } |
67 | #endif |
68 | initNamespace(); |
69 | initParser(); |
70 | #ifndef HAVE_EMBEDDED |
71 | initHeartbeat(); |
72 | #endif |
73 | str err = malBootstrap(); |
74 | if (err != MAL_SUCCEED) { |
75 | mal_client_reset(); |
76 | #ifndef NDEBUG |
77 | mdbExit(); |
78 | #endif |
79 | fprintf(stderr, "%s" , err); |
80 | freeException(err); |
81 | return -1; |
82 | } |
83 | initProfiler(); |
84 | return 0; |
85 | } |
86 | |
87 | /* |
88 | * Upon exit we should attempt to remove all allocated memory explicitly. |
89 | * This seemingly superflous action is necessary to simplify analyis of |
90 | * memory leakage problems later ons and to allow an embedded server to |
91 | * restart the server properly. |
92 | * |
93 | * It is the responsibility of the enclosing application to finish/cease all |
94 | * activity first. |
95 | * This function should be called after you have issued sql_reset(); |
96 | */ |
97 | void mserver_reset(void) |
98 | { |
99 | str err = 0; |
100 | |
101 | GDKprepareExit(); |
102 | WLCreset(); |
103 | MCstopClients(0); |
104 | setHeartbeat(-1); |
105 | stopProfiler(0); |
106 | AUTHreset(); |
107 | if (!GDKinmemory()) { |
108 | if ((err = msab_wildRetreat()) != NULL) { |
109 | fprintf(stderr, "!%s" , err); |
110 | free(err); |
111 | } |
112 | if ((err = msab_registerStop()) != NULL) { |
113 | fprintf(stderr, "!%s" , err); |
114 | free(err); |
115 | } |
116 | } |
117 | mal_factory_reset(); |
118 | mal_dataflow_reset(); |
119 | mal_client_reset(); |
120 | mal_linker_reset(); |
121 | mal_resource_reset(); |
122 | mal_runtime_reset(); |
123 | mal_module_reset(); |
124 | mal_atom_reset(); |
125 | opt_pipes_reset(); |
126 | #ifndef NDEBUG |
127 | mdbExit(); |
128 | #endif |
129 | |
130 | memset((char*)monet_cwd, 0, sizeof(monet_cwd)); |
131 | memset((char*)monet_characteristics,0, sizeof(monet_characteristics)); |
132 | mal_namespace_reset(); |
133 | /* No need to clean up the namespace, it will simply be extended |
134 | * upon restart mal_namespace_reset(); */ |
135 | GDKreset(0); // terminate all other threads |
136 | } |
137 | |
138 | |
139 | /* stopping clients should be done with care, as they may be in the mids of |
140 | * transactions. One safe place is between MAL instructions, which would |
141 | * abort the transaction by raising an exception. All sessions are |
142 | * terminate this way. |
143 | * We should also ensure that no new client enters the scene while shutting down. |
144 | * For this we mark the client records as BLOCKCLIENT. |
145 | * |
146 | * Beware, mal_exit is also called during a SIGTERM from the monetdb tool |
147 | */ |
148 | |
149 | void mal_exit(int status) |
150 | { |
151 | mserver_reset(); |
152 | exit(status); /* properly end GDK */ |
153 | } |
154 | |