Line data Source code
1 : /* 2 : * SPDX-License-Identifier: MPL-2.0 3 : * 4 : * This Source Code Form is subject to the terms of the Mozilla Public 5 : * License, v. 2.0. If a copy of the MPL was not distributed with this 6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 : * 8 : * Copyright 2024 MonetDB Foundation; 9 : * Copyright August 2008 - 2023 MonetDB B.V.; 10 : * Copyright 1997 - July 2008 CWI. 11 : */ 12 : 13 : /* (author) M. Kersten */ 14 : #include "monetdb_config.h" 15 : #include "mal.h" 16 : 17 : char monet_cwd[FILENAME_MAX] = { 0 }; 18 : 19 : char monet_characteristics[4096]; 20 : stream *maleventstream = 0; 21 : 22 : /* The compile time debugging flags are turned into bit masks, akin to GDK */ 23 : lng MALdebug; 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_internal.h" 39 : #include "mal_runtime.h" 40 : #include "mal_resource.h" 41 : #include "mal_atom.h" 42 : #include "mutils.h" 43 : 44 : MT_Lock mal_contextLock = MT_LOCK_INITIALIZER(mal_contextLock); 45 : MT_Lock mal_profileLock = MT_LOCK_INITIALIZER(mal_profileLock); 46 : MT_Lock mal_copyLock = MT_LOCK_INITIALIZER(mal_copyLock); 47 : MT_Lock mal_delayLock = MT_LOCK_INITIALIZER(mal_delayLock); 48 : 49 : 50 : const char * 51 331 : mal_version(void) 52 : { 53 331 : return MONETDB5_VERSION; 54 : } 55 : 56 : static void 57 114 : MALprintinfo(void) 58 : { 59 114 : MCprintinfo(); 60 114 : } 61 : 62 : /* 63 : * Initialization of the MAL context 64 : */ 65 : 66 : int 67 340 : mal_init(char *modules[], bool embedded, const char *initpasswd, 68 : const char *caller_revision) 69 : { 70 : /* Any error encountered here terminates the process 71 : * with a message sent to stderr 72 : */ 73 340 : str err; 74 : 75 340 : mal_startup(); 76 : /* check that library that we're linked against is compatible with 77 : * the one we were compiled with */ 78 340 : int maj, min, patch; 79 340 : const char *version = GDKlibversion(); 80 340 : sscanf(version, "%d.%d.%d", &maj, &min, &patch); 81 340 : if (maj != GDK_VERSION_MAJOR || min < GDK_VERSION_MINOR) { 82 0 : TRC_CRITICAL(MAL_SERVER, 83 : "Linked GDK library not compatible with the one this was compiled with\n"); 84 0 : TRC_CRITICAL(MAL_SERVER, "Linked version: %s, compiled version: %s\n", 85 : version, GDK_VERSION); 86 0 : return -1; 87 : } 88 : 89 340 : if (caller_revision) { 90 329 : const char *p = mercurial_revision(); 91 329 : if (p && strcmp(p, caller_revision) != 0) { 92 0 : TRC_CRITICAL(MAL_SERVER, 93 : "incompatible versions: caller is %s, MAL is %s\n", 94 : caller_revision, p); 95 0 : return -1; 96 : } 97 : } 98 : 99 340 : if (!MCinit()) 100 : return -1; 101 340 : initNamespace(); 102 : 103 340 : GDKprintinforegister(MALprintinfo); 104 : 105 340 : err = malBootstrap(modules, embedded, initpasswd); 106 339 : if (err != MAL_SUCCEED) { 107 0 : mal_client_reset(); 108 0 : TRC_CRITICAL(MAL_SERVER, "%s\n", err); 109 0 : freeException(err); 110 0 : return -1; 111 : } 112 339 : initProfiler(); 113 339 : initHeartbeat(); 114 339 : return 0; 115 : } 116 : 117 : /* 118 : * Upon exit we should attempt to remove all allocated memory explicitly. 119 : * This seemingly superflous action is necessary to simplify analyis of 120 : * memory leakage problems later ons and to allow an embedded server to 121 : * restart the server properly. 122 : * 123 : * It is the responsibility of the enclosing application to finish/cease all 124 : * activity first. 125 : * This function should be called after you have issued sql_reset(); 126 : */ 127 : void 128 338 : mal_reset(void) 129 : { 130 338 : GDKprepareExit(); 131 338 : MCstopClients(0); 132 338 : setHeartbeat(-1); 133 338 : stopProfiler(0); 134 338 : AUTHreset(); 135 338 : if (!GDKinmemory(0) && !GDKembedded()) { 136 328 : str err = 0; 137 : 138 328 : if ((err = msab_wildRetreat()) !=NULL) { 139 0 : TRC_ERROR(MAL_SERVER, "%s\n", err); 140 0 : free(err); 141 : } 142 328 : if ((err = msab_registerStop()) !=NULL) { 143 0 : TRC_ERROR(MAL_SERVER, "%s\n", err); 144 0 : free(err); 145 : } 146 : } 147 338 : mal_dataflow_reset(); 148 338 : mal_client_reset(); 149 338 : mal_linker_reset(); 150 338 : mal_resource_reset(); 151 338 : mal_runtime_reset(); 152 338 : mal_module_reset(); 153 338 : mal_atom_reset(); 154 : 155 338 : memset((char *) monet_cwd, 0, sizeof(monet_cwd)); 156 338 : memset((char *) monet_characteristics, 0, sizeof(monet_characteristics)); 157 338 : mal_namespace_reset(); 158 : /* No need to clean up the namespace, it will simply be extended 159 : * upon restart mal_namespace_reset(); */ 160 338 : GDKreset(0); // terminate all other threads 161 338 : } 162 : 163 : 164 : /* stopping clients should be done with care, as they may be in the mids of 165 : * transactions. One safe place is between MAL instructions, which would 166 : * abort the transaction by raising an exception. All sessions are 167 : * terminate this way. 168 : * We should also ensure that no new client enters the scene while shutting down. 169 : * For this we mark the client records as BLOCKCLIENT. 170 : */ 171 : 172 : void 173 328 : mal_exit(int status) 174 : { 175 328 : mal_reset(); 176 328 : exit(status); /* properly end GDK */ 177 : }