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 305 : mal_version(void) 52 : { 53 305 : return MONETDB5_VERSION; 54 : } 55 : 56 : /* 57 : * Initialization of the MAL context 58 : */ 59 : 60 : int 61 314 : 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 314 : str err; 68 : 69 314 : mal_startup(); 70 : /* check that library that we're linked against is compatible with 71 : * the one we were compiled with */ 72 314 : int maj, min, patch; 73 314 : const char *version = GDKlibversion(); 74 314 : sscanf(version, "%d.%d.%d", &maj, &min, &patch); 75 314 : 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 314 : if (caller_revision) { 84 303 : const char *p = mercurial_revision(); 85 303 : 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 314 : if (!MCinit()) 94 : return -1; 95 314 : initNamespace(); 96 : 97 314 : err = malBootstrap(modules, embedded, initpasswd); 98 297 : 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 297 : initProfiler(); 105 297 : initHeartbeat(); 106 297 : 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 296 : mal_reset(void) 121 : { 122 296 : GDKprepareExit(); 123 296 : MCstopClients(0); 124 296 : setHeartbeat(-1); 125 296 : stopProfiler(0); 126 296 : AUTHreset(); 127 296 : if (!GDKinmemory(0) && !GDKembedded()) { 128 286 : str err = 0; 129 : 130 286 : if ((err = msab_wildRetreat()) !=NULL) { 131 0 : TRC_ERROR(MAL_SERVER, "%s\n", err); 132 0 : free(err); 133 : } 134 286 : if ((err = msab_registerStop()) !=NULL) { 135 0 : TRC_ERROR(MAL_SERVER, "%s\n", err); 136 0 : free(err); 137 : } 138 : } 139 296 : mal_dataflow_reset(); 140 296 : mal_client_reset(); 141 296 : mal_linker_reset(); 142 296 : mal_resource_reset(); 143 296 : mal_runtime_reset(); 144 296 : mal_module_reset(); 145 296 : mal_atom_reset(); 146 : 147 296 : memset((char *) monet_cwd, 0, sizeof(monet_cwd)); 148 296 : memset((char *) monet_characteristics, 0, sizeof(monet_characteristics)); 149 296 : mal_namespace_reset(); 150 : /* No need to clean up the namespace, it will simply be extended 151 : * upon restart mal_namespace_reset(); */ 152 296 : GDKreset(0); // terminate all other threads 153 296 : } 154 : 155 : 156 : /* stopping clients should be done with care, as they may be in the mids of 157 : * transactions. One safe place is between MAL instructions, which would 158 : * abort the transaction by raising an exception. All sessions are 159 : * terminate this way. 160 : * We should also ensure that no new client enters the scene while shutting down. 161 : * For this we mark the client records as BLOCKCLIENT. 162 : */ 163 : 164 : void 165 286 : mal_exit(int status) 166 : { 167 286 : mal_reset(); 168 286 : printf("# mserver5 exiting\n"); 169 286 : exit(status); /* properly end GDK */ 170 : }