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 326 : mal_version(void) 52 : { 53 326 : 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 335 : 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 335 : str err; 74 : 75 : /* check that library that we're linked against is compatible with 76 : * the one we were compiled with */ 77 335 : int maj, min, patch; 78 335 : const char *version = GDKlibversion(); 79 335 : sscanf(version, "%d.%d.%d", &maj, &min, &patch); 80 335 : if (maj != GDK_VERSION_MAJOR || min < GDK_VERSION_MINOR) { 81 0 : TRC_CRITICAL(MAL_SERVER, 82 : "Linked GDK library not compatible with the one this was compiled with\n"); 83 0 : TRC_CRITICAL(MAL_SERVER, "Linked version: %s, compiled version: %s\n", 84 : version, GDK_VERSION); 85 0 : return -1; 86 : } 87 : 88 335 : if (caller_revision) { 89 324 : const char *p = mercurial_revision(); 90 324 : if (p && strcmp(p, caller_revision) != 0) { 91 0 : TRC_CRITICAL(MAL_SERVER, 92 : "incompatible versions: caller is %s, MAL is %s\n", 93 : caller_revision, p); 94 0 : return -1; 95 : } 96 : } 97 : 98 335 : if (!MCinit()) 99 : return -1; 100 335 : initNamespace(); 101 : 102 335 : GDKprintinforegister(MALprintinfo); 103 : 104 335 : err = malBootstrap(modules, embedded, initpasswd); 105 334 : if (err !=MAL_SUCCEED) { 106 0 : mal_client_reset(); 107 0 : TRC_CRITICAL(MAL_SERVER, "%s\n", err); 108 0 : freeException(err); 109 0 : return -1; 110 : } 111 334 : initProfiler(); 112 334 : initHeartbeat(); 113 334 : return 0; 114 : } 115 : 116 : /* 117 : * Upon exit we should attempt to remove all allocated memory explicitly. 118 : * This seemingly superflous action is necessary to simplify analyis of 119 : * memory leakage problems later ons and to allow an embedded server to 120 : * restart the server properly. 121 : * 122 : * It is the responsibility of the enclosing application to finish/cease all 123 : * activity first. 124 : * This function should be called after you have issued sql_reset(); 125 : */ 126 : void 127 333 : mal_reset(void) 128 : { 129 333 : GDKprepareExit(); 130 333 : MCstopClients(0); 131 333 : setHeartbeat(-1); 132 333 : stopProfiler(0); 133 333 : AUTHreset(); 134 333 : if (!GDKinmemory(0) && !GDKembedded()) { 135 323 : str err = 0; 136 : 137 323 : if ((err = msab_wildRetreat()) !=NULL) { 138 0 : TRC_ERROR(MAL_SERVER, "%s\n", err); 139 0 : free(err); 140 : } 141 323 : if ((err = msab_registerStop()) !=NULL) { 142 0 : TRC_ERROR(MAL_SERVER, "%s\n", err); 143 0 : free(err); 144 : } 145 : } 146 333 : mal_dataflow_reset(); 147 333 : mal_client_reset(); 148 333 : mal_linker_reset(); 149 333 : mal_resource_reset(); 150 333 : mal_runtime_reset(); 151 333 : mal_module_reset(); 152 333 : mal_atom_reset(); 153 : 154 333 : memset((char *) monet_cwd, 0, sizeof(monet_cwd)); 155 333 : memset((char *) monet_characteristics, 0, sizeof(monet_characteristics)); 156 333 : mal_namespace_reset(); 157 : /* No need to clean up the namespace, it will simply be extended 158 : * upon restart mal_namespace_reset(); */ 159 333 : GDKreset(0); // terminate all other threads 160 333 : } 161 : 162 : 163 : /* stopping clients should be done with care, as they may be in the mids of 164 : * transactions. One safe place is between MAL instructions, which would 165 : * abort the transaction by raising an exception. All sessions are 166 : * terminate this way. 167 : * We should also ensure that no new client enters the scene while shutting down. 168 : * For this we mark the client records as BLOCKCLIENT. 169 : */ 170 : 171 : void 172 323 : mal_exit(int status) 173 : { 174 323 : mal_reset(); 175 323 : exit(status); /* properly end GDK */ 176 : }