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 342 : mal_version(void) 52 : { 53 342 : return MONETDB5_VERSION; 54 : } 55 : 56 : /* 57 : * Initialization of the MAL context 58 : */ 59 : 60 : int 61 351 : mal_init(char *modules[], bool embedded, const char *initpasswd, 62 : const char *caller_revision) 63 : { 64 : /* Any error encountered here terminates the process 65 : * with a message sent to stderr 66 : */ 67 351 : str err; 68 : 69 351 : mal_startup(); 70 : /* check that library that we're linked against is compatible with 71 : * the one we were compiled with */ 72 351 : int maj, min, patch; 73 351 : const char *version = GDKlibversion(); 74 351 : sscanf(version, "%d.%d.%d", &maj, &min, &patch); 75 351 : if (maj != GDK_VERSION_MAJOR || min < GDK_VERSION_MINOR) { 76 0 : TRC_CRITICAL(MAL_SERVER, 77 : "Linked GDK library not compatible with the one this was compiled with\n"); 78 0 : TRC_CRITICAL(MAL_SERVER, "Linked version: %s, compiled version: %s\n", 79 : version, GDK_VERSION); 80 0 : return -1; 81 : } 82 : 83 351 : if (caller_revision) { 84 340 : const char *p = mercurial_revision(); 85 340 : if (p && strcmp(p, caller_revision) != 0) { 86 0 : TRC_CRITICAL(MAL_SERVER, 87 : "incompatible versions: caller is %s, MAL is %s\n", 88 : caller_revision, p); 89 0 : return -1; 90 : } 91 : } 92 : 93 351 : if (!MCinit()) 94 : return -1; 95 351 : initNamespace(); 96 : 97 351 : err = malBootstrap(modules, embedded, initpasswd); 98 350 : if (err != MAL_SUCCEED) { 99 0 : mal_client_reset(); 100 0 : TRC_CRITICAL(MAL_SERVER, "%s\n", err); 101 0 : freeException(err); 102 0 : return -1; 103 : } 104 350 : initProfiler(); 105 350 : initHeartbeat(); 106 350 : return 0; 107 : } 108 : 109 : /* 110 : * Upon exit we should attempt to remove all allocated memory explicitly. 111 : * This seemingly superfluous action is necessary to simplify analysis of 112 : * memory leakage problems later on and to allow an embedded server to 113 : * restart the server properly. 114 : * 115 : * It is the responsibility of the enclosing application to finish/cease all 116 : * activity first. 117 : * This function should be called after you have issued sql_reset(); 118 : */ 119 : void 120 349 : mal_reset(void) 121 : { 122 349 : GDKprepareExit(); 123 349 : MCstopClients(0); 124 349 : setHeartbeat(-1); 125 349 : stopProfiler(0); 126 349 : AUTHreset(); 127 349 : if (!GDKinmemory(0) && !GDKembedded()) { 128 339 : str err = 0; 129 : 130 339 : if ((err = msab_wildRetreat()) !=NULL) { 131 0 : TRC_ERROR(MAL_SERVER, "%s\n", err); 132 0 : free(err); 133 : } 134 339 : if ((err = msab_registerStop()) !=NULL) { 135 0 : TRC_ERROR(MAL_SERVER, "%s\n", err); 136 0 : free(err); 137 : } 138 : } 139 349 : mal_dataflow_reset(); 140 349 : mal_client_reset(); 141 349 : mal_linker_reset(); 142 349 : mal_resource_reset(); 143 349 : mal_runtime_reset(); 144 349 : mal_module_reset(); 145 349 : mal_atom_reset(); 146 : 147 349 : memset((char *) monet_cwd, 0, sizeof(monet_cwd)); 148 349 : memset((char *) monet_characteristics, 0, sizeof(monet_characteristics)); 149 349 : mal_namespace_reset(); 150 349 : GDKreset(0); // terminate all other threads 151 349 : } 152 : 153 : 154 : /* stopping clients should be done with care, as they may be in the mids of 155 : * transactions. One safe place is between MAL instructions, which would 156 : * abort the transaction by raising an exception. All sessions are 157 : * terminate this way. 158 : * We should also ensure that no new client enters the scene while shutting down. 159 : * For this we mark the client records as BLOCKCLIENT. 160 : */ 161 : 162 : void 163 339 : mal_exit(int status) 164 : { 165 339 : mal_reset(); 166 339 : printf("# mserver5 exiting\n"); 167 339 : exit(status); /* properly end GDK */ 168 : }