Exemple #1
0
static void
GDKvmtrim(void *limit)
{
	int highload = 0;
	ssize_t prevmem = 0, prevrss = 0;

	(void) limit;

	do {
		int t;
		size_t rss;
		ssize_t rssdiff, memdiff;
		size_t cursize;

		/* sleep using catnaps so we can exit in a timely fashion */
		for (t = highload ? 500 : 5000; t > 0; t -= CATNAP) {
			MT_sleep_ms(CATNAP);
			if (GDKexiting())
				return;
		}
		rss = MT_getrss();
		rssdiff = (ssize_t) rss - (ssize_t) prevrss;
		cursize = GDKvm_cursize();
		memdiff = (ssize_t) cursize - (ssize_t) prevmem;
		MEMDEBUG THRprintf(GDKstdout, "alloc = " SZFMT " %+zd rss = " SZFMT " %+zd\n", cursize, memdiff, rss, rssdiff);
		prevmem = cursize;
		prevrss = rss;
		if (memdiff >= 0 && rssdiff < -32 * (ssize_t) MT_pagesize()) {
			BBPtrim(rss);
			highload = 1;
		} else {
			highload = 0;
		}
	} while (!GDKexiting());
}
Exemple #2
0
void mal_exit(void){
	str err;

	/*
	 * Before continuing we should make sure that all clients
	 * (except the console) have left the scene.
	 */
	MCstopClients(0);
#if 0
{
	int reruns=0, go_on;
	do{
		if ( (go_on = MCactiveClients()) )
			MT_sleep_ms(1000);
		mnstr_printf(mal_clients->fdout,"#MALexit: %d clients still active\n", go_on);
	} while (++reruns < SERVERSHUTDOWNDELAY && go_on > 1);
}
#endif
	stopHeartbeat();
#ifdef HAVE_JSONSTORE
	stopHttpdaemon();
#endif
	stopMALdataflow();
	stopProfiling();
	RECYCLEdrop(mal_clients); /* remove any left over intermediates */
	unloadLibraries();
#if 0
	/* skip this to solve random crashes, needs work */
	freeModuleList(mal_clients->nspace);

	finishNamespace();
	if( mal_clients->prompt)
		GDKfree(mal_clients->prompt);
	if( mal_clients->errbuf)
		GDKfree(mal_clients->errbuf);
	if( mal_clients->bak)
		GDKfree(mal_clients->bak);
	if( mal_clients->fdin){
		/* missing protection against closing stdin stream */
		(void) mnstr_close(mal_clients->fdin->s);
		(void) bstream_destroy(mal_clients->fdin);
	}
	if( mal_clients->fdout && mal_clients->fdout != GDKstdout) {
		(void) mnstr_close(mal_clients->fdout);
		(void) mnstr_destroy(mal_clients->fdout);
	}
#endif
	/* deregister everything that was registered, ignore errors */
	if ((err = msab_wildRetreat()) != NULL) {
		fprintf(stderr, "!%s", err);
		free(err);
	}
	/* the server will now be shut down */
	if ((err = msab_registerStop()) != NULL) {
		fprintf(stderr, "!%s", err);
		free(err);
	}
	GDKexit(0); 	/* properly end GDK */
}
Exemple #3
0
str
ALARMsleep(void *res, int *secs)
{
	(void) res;		/* fool compilers */
	if (*secs < 0)
		throw(MAL, "alarm.sleep", "negative delay");

	MT_sleep_ms(*secs * 1000);
	return MAL_SUCCEED;
}
Exemple #4
0
/*
 * Really really get the lock. Now!!
 */
static int
GDKgetHome(void)
{
	if (MT_pagesize() == 0 || GDKlockFile)
		return 0;
	while ((GDKlockFile = fopen(GDKLOCK, "r+")) == NULL) {
		GDKerror("GDKgetHome: PANIC on open %s. sleep(1)\n", GDKLOCK);
		MT_sleep_ms(1000);
	}
	if (MT_lockf(GDKLOCK, F_TLOCK, 4, 1) < 0) {
		IODEBUG THRprintf(GDKstdout, "#GDKgetHome: blocking on lock '%s'.\n", GDKLOCK);
		MT_lockf(GDKLOCK, F_LOCK, 4, 1);
	}
	return 1;
}
Exemple #5
0
str
ALARMsleep(int *res, int *secs)
{
	(void) res;		/* fool compilers */
	if (*secs < 0)
		throw(MAL, "alarm.sleep", "negative delay");

#ifdef __CYGWIN__
	/* CYGWIN cannot handle SIGALRM with sleep */
	{
		lng t = GDKusec() + (*secs)*1000000;

		while (GDKusec() < t)
			;
	}
#else
	MT_sleep_ms(*secs * 1000);
#endif
	return MAL_SUCCEED;
}
Exemple #6
0
str
SQLsession(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	str msg = MAL_SUCCEED;
	str logmsg;
	int cnt=0;

	(void) mb;
	(void) stk;
	(void) pci;
	if (SQLinitialized == 0 && (msg = SQLprelude(NULL)) != MAL_SUCCEED)
		return msg;
	msg = setScenario(cntxt, "sql");
	// Wait for any recovery process to be finished
	do {
		MT_sleep_ms(1000);
		logmsg = GDKgetenv("recovery");
		if( logmsg== NULL && ++cnt  == 5)
			throw(SQL,"SQLinit","#WARNING server not ready, recovery in progress\n");
    }while (logmsg == NULL);
	return msg;
}
Exemple #7
0
/* coverity[+kill] */
void
GDKexit(int status)
{
	if (ATOMIC_CAS_int(GDKstopped, 0, 1, GDKstoppedLock, "GDKexit") == 0) {
		MT_lock_set(&GDKthreadLock, "GDKexit");
		GDKnrofthreads = 0;
		MT_lock_unset(&GDKthreadLock, "GDKexit");
		if (GDKvmtrim_id)
			MT_join_thread(GDKvmtrim_id);
		MT_sleep_ms(CATNAP);

		/* Kill all threads except myself */
		if (status == 0) {
			MT_Id pid = MT_getpid();
			Thread t, s;

			for (t = GDKthreads, s = t + THREADS; t < s; t++) {
				if (t->pid) {
					MT_Id victim = t->pid;

					if (t->pid != pid)
						MT_kill_thread(victim);
				}
			}
		}
		(void) GDKgetHome();
#if 0
		/* we can't clean up after killing threads */
		BBPexit();
#endif
		GDKlog(GDKLOGOFF);
		GDKunlockHome();
#if !defined(ATOMIC_LOCK) && !defined(NDEBUG)
		TEMDEBUG GDKlockstatistics(1);
#endif
		MT_global_exit(status);
	}
}
Exemple #8
0
int
main(int argc, char **av)
{
	char *prog = *av;
	opt *set = NULL;
	int i, grpdebug = 0, debug = 0, setlen = 0, listing = 0;
	str err = MAL_SUCCEED;
	char prmodpath[FILENAME_MAX];
	const char *modpath = NULL;
	char *binpath = NULL;
	str *monet_script;
	char *dbpath = NULL;
	char *dbextra = NULL;
	int verbosity = 0;
	static struct option long_options[] = {
		{ "config", required_argument, NULL, 'c' },
		{ "dbpath", required_argument, NULL, 0 },
		{ "dbextra", required_argument, NULL, 0 },
		{ "daemon", required_argument, NULL, 0 },
		{ "debug", optional_argument, NULL, 'd' },
		{ "help", no_argument, NULL, '?' },
		{ "version", no_argument, NULL, 0 },
		{ "verbose", optional_argument, NULL, 'v' },
		{ "readonly", no_argument, NULL, 'r' },
		{ "single-user", no_argument, NULL, 0 },
		{ "set", required_argument, NULL, 's' },
		{ "threads", no_argument, NULL, 0 },
		{ "memory", no_argument, NULL, 0 },
		{ "properties", no_argument, NULL, 0 },
		{ "io", no_argument, NULL, 0 },
		{ "transactions", no_argument, NULL, 0 },
		{ "trace", optional_argument, NULL, 't' },
		{ "modules", no_argument, NULL, 0 },
		{ "algorithms", no_argument, NULL, 0 },
		{ "optimizers", no_argument, NULL, 0 },
		{ "performance", no_argument, NULL, 0 },
		{ "forcemito", no_argument, NULL, 0 },
		{ "heaps", no_argument, NULL, 0 },
		{ NULL, 0, NULL, 0 }
	};

#if defined(_MSC_VER) && defined(__cplusplus)
	set_terminate(mserver_abort);
#endif
#ifdef _MSC_VER
	_CrtSetReportMode(_CRT_ERROR, 0);
	_CrtSetReportMode(_CRT_ASSERT, 0);
	_set_invalid_parameter_handler(mserver_invalid_parameter_handler);
#ifdef _TWO_DIGIT_EXPONENT
	_set_output_format(_TWO_DIGIT_EXPONENT);
#endif
#endif
	if (setlocale(LC_CTYPE, "") == NULL) {
		fprintf(stderr, "cannot set locale\n");
		exit(1);
	}

	if (getcwd(monet_cwd, FILENAME_MAX - 1) == NULL) {
		perror("pwd");
		fprintf(stderr,"monet_init: could not determine current directory\n");
		exit(-1);
	}

	/* retrieve binpath early (before monet_init) because some
	 * implementations require the working directory when the binary was
	 * called */
	binpath = get_bin_path();

	if (!(setlen = mo_builtin_settings(&set)))
		usage(prog, -1);

	for (;;) {
		int option_index = 0;

		int c = getopt_long(argc, av, "c:d::rs:t::v::?",
				long_options, &option_index);

		if (c == -1)
			break;

		switch (c) {
		case 0:
			if (strcmp(long_options[option_index].name, "dbpath") == 0) {
				size_t optarglen = strlen(optarg);
				/* remove trailing directory separator */
				while (optarglen > 0 &&
				       (optarg[optarglen - 1] == '/' ||
					optarg[optarglen - 1] == '\\'))
					optarg[--optarglen] = '\0';
				dbpath = absolute_path(optarg);
				if( dbpath == NULL)
					fprintf(stderr, "#error: can not allocate memory for dbpath\n");
				else
					setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_dbpath", dbpath);
				break;
			}
			if (strcmp(long_options[option_index].name, "dbextra") == 0) {
				if (dbextra)
					fprintf(stderr, "#warning: ignoring multiple --dbextra arguments\n");
				else
					dbextra = optarg;
				break;
			}
#ifdef HAVE_CONSOLE
			if (strcmp(long_options[option_index].name, "daemon") == 0) {
				setlen = mo_add_option(&set, setlen, opt_cmdline, "monet_daemon", optarg);
				break;
			}
#endif
			if (strcmp(long_options[option_index].name, "single-user") == 0) {
				setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_single_user", "yes");
				break;
			}
			if (strcmp(long_options[option_index].name, "version") == 0) {
				monet_version();
				exit(0);
			}
			/* debugging options */
			if (strcmp(long_options[option_index].name, "properties") == 0) {
				grpdebug |= GRPproperties;
				break;
			}
			if (strcmp(long_options[option_index].name, "algorithms") == 0) {
				grpdebug |= GRPalgorithms;
				break;
			}
			if (strcmp(long_options[option_index].name, "optimizers") == 0) {
				grpdebug |= GRPoptimizers;
				break;
			}
			if (strcmp(long_options[option_index].name, "forcemito") == 0) {
				grpdebug |= GRPforcemito;
				break;
			}
			if (strcmp(long_options[option_index].name, "performance") == 0) {
				grpdebug |= GRPperformance;
				break;
			}
			if (strcmp(long_options[option_index].name, "io") == 0) {
				grpdebug |= GRPio;
				break;
			}
			if (strcmp(long_options[option_index].name, "memory") == 0) {
				grpdebug |= GRPmemory;
				break;
			}
			if (strcmp(long_options[option_index].name, "modules") == 0) {
				grpdebug |= GRPmodules;
				break;
			}
			if (strcmp(long_options[option_index].name, "transactions") == 0) {
				grpdebug |= GRPtransactions;
				break;
			}
			if (strcmp(long_options[option_index].name, "threads") == 0) {
				grpdebug |= GRPthreads;
				break;
			}
			if (strcmp(long_options[option_index].name, "trace") == 0) {
				mal_trace = 1;
				break;
			}
			if (strcmp(long_options[option_index].name, "heaps") == 0) {
				grpdebug |= GRPheaps;
				break;
			}
			usage(prog, -1);
			/* not reached */
		case 'c':
			/* coverity[var_deref_model] */
			setlen = mo_add_option(&set, setlen, opt_cmdline, "config", optarg);
			break;
		case 'd':
			if (optarg) {
				char *endarg;
				debug |= strtol(optarg, &endarg, 10);
				if (*endarg != '\0') {
					fprintf(stderr, "ERROR: wrong format for --debug=%s\n",
							optarg);
					usage(prog, -1);
				}
			} else {
				debug |= 1;
			}
			break;
		case 'r':
			setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_readonly", "yes");
			break;
		case 's': {
			/* should add option to a list */
			/* coverity[var_deref_model] */
			char *tmp = strchr(optarg, '=');

			if (tmp) {
				*tmp = '\0';
				setlen = mo_add_option(&set, setlen, opt_cmdline, optarg, tmp + 1);
			} else
				fprintf(stderr, "ERROR: wrong format %s\n", optarg);
			}
			break;
		case 't':
			mal_trace = 1;
			break;
		case 'v':
			if (optarg) {
				char *endarg;
				verbosity = (int) strtol(optarg, &endarg, 10);
				if (*endarg != '\0') {
					fprintf(stderr, "ERROR: wrong format for --verbose=%s\n",
							optarg);
					usage(prog, -1);
				}
			} else {
				verbosity++;
			}
			break;
		case '?':
			/* a bit of a hack: look at the option that the
			   current `c' is based on and see if we recognize
			   it: if -? or --help, exit with 0, else with -1 */
			usage(prog, strcmp(av[optind - 1], "-?") == 0 || strcmp(av[optind - 1], "--help") == 0 ? 0 : -1);
		default:
			fprintf(stderr, "ERROR: getopt returned character "
				"code '%c' 0%o\n", c, (uint8_t) c);
			usage(prog, -1);
		}
	}

	if (!(setlen = mo_system_config(&set, setlen)))
		usage(prog, -1);

	GDKsetdebug(debug | grpdebug);  /* add the algorithm tracers */
	if (debug)
		mo_print_options(set, setlen);
	GDKsetverbose(verbosity);

	monet_script = (str *) malloc(sizeof(str) * (argc + 1));
	if (monet_script == NULL) {
		fprintf(stderr, "!ERROR: cannot allocate memory for script \n");
		exit(1);
	}
	i = 0;
	while (optind < argc) {
		monet_script[i] = absolute_path(av[optind]);
		if (monet_script[i] == NULL) {
			fprintf(stderr, "!ERROR: cannot allocate memory for script \n");
			exit(1);
		}
		i++;
		optind++;
	}
	monet_script[i] = NULL;
	if (!dbpath) {
		dbpath = absolute_path(mo_find_option(set, setlen, "gdk_dbpath"));
		if (!dbpath) {
			fprintf(stderr, "!ERROR: cannot allocate memory for database directory \n");
			exit(1);
		}
	}
	if (BBPaddfarm(dbpath, 1 << PERSISTENT) != GDK_SUCCEED ||
	    BBPaddfarm(dbextra ? dbextra : dbpath, 1 << TRANSIENT) != GDK_SUCCEED) {
		fprintf(stderr, "!ERROR: cannot add farm\n");
		exit(1);
	}
	if (GDKcreatedir(dbpath) != GDK_SUCCEED) {
		fprintf(stderr, "!ERROR: cannot create directory for %s\n", dbpath);
		exit(1);
	}
	GDKfree(dbpath);
	if (monet_init(set, setlen) == 0) {
		mo_free_options(set, setlen);
		if (GDKerrbuf && *GDKerrbuf)
			fprintf(stderr, "%s\n", GDKerrbuf);
		exit(1);
	}
	mo_free_options(set, setlen);

	if (GDKsetenv("monet_version", GDKversion()) != GDK_SUCCEED ||
	    GDKsetenv("monet_release",
#ifdef MONETDB_RELEASE
		      MONETDB_RELEASE
#else
		      "unreleased"
#endif
		    ) != GDK_SUCCEED) {
		fprintf(stderr, "!ERROR: GDKsetenv failed\n");
		exit(1);
	}

	if ((modpath = GDKgetenv("monet_mod_path")) == NULL) {
		/* start probing based on some heuristics given the binary
		 * location:
		 * bin/mserver5 -> ../
		 * libX/monetdb5/lib/
		 * probe libX = lib, lib32, lib64, lib/64 */
		size_t pref;
		/* "remove" common prefix of configured BIN and LIB
		 * directories from LIBDIR */
		for (pref = 0; LIBDIR[pref] != 0 && BINDIR[pref] == LIBDIR[pref]; pref++)
			;
		const char *libdirs[] = {
			&LIBDIR[pref],
			"lib",
			"lib64",
			"lib/64",
			"lib32",
			NULL,
		};
		struct stat sb;
		if (binpath != NULL) {
			char *p = strrchr(binpath, DIR_SEP);
			if (p != NULL)
				*p = '\0';
			p = strrchr(binpath, DIR_SEP);
			if (p != NULL) {
				*p = '\0';
				for (i = 0; libdirs[i] != NULL; i++) {
					int len = snprintf(prmodpath, sizeof(prmodpath), "%s%c%s%cmonetdb5",
									   binpath, DIR_SEP, libdirs[i], DIR_SEP);
					if (len == -1 || len >= FILENAME_MAX)
						continue;
					if (stat(prmodpath, &sb) == 0) {
						modpath = prmodpath;
						break;
					}
				}
			} else {
				printf("#warning: unusable binary location, "
					   "please use --set monet_mod_path=/path/to/... to "
					   "allow finding modules\n");
				fflush(NULL);
			}
		} else {
			printf("#warning: unable to determine binary location, "
				   "please use --set monet_mod_path=/path/to/... to "
				   "allow finding modules\n");
			fflush(NULL);
		}
		if (modpath != NULL &&
		    GDKsetenv("monet_mod_path", modpath) != GDK_SUCCEED) {
			fprintf(stderr, "!ERROR: GDKsetenv failed\n");
			exit(1);
		}
	}

	/* configure sabaoth to use the right dbpath and active database */
	msab_dbpathinit(GDKgetenv("gdk_dbpath"));
	/* wipe out all cruft, if left over */
	if ((err = msab_wildRetreat()) != NULL) {
		/* just swallow the error */
		free(err);
	}
	/* From this point, the server should exit cleanly.  Discussion:
	 * even earlier?  Sabaoth here registers the server is starting up. */
	if ((err = msab_registerStarting()) != NULL) {
		/* throw the error at the user, but don't die */
		fprintf(stderr, "!%s\n", err);
		free(err);
	}

#ifdef HAVE_SIGACTION
	{
		struct sigaction sa;

		(void) sigemptyset(&sa.sa_mask);
		sa.sa_flags = 0;
		sa.sa_handler = handler;
		if (sigaction(SIGINT, &sa, NULL) == -1 ||
		    sigaction(SIGQUIT, &sa, NULL) == -1 ||
		    sigaction(SIGTERM, &sa, NULL) == -1) {
			fprintf(stderr, "!unable to create signal handlers\n");
		}
	}
#else
#ifdef _MSC_VER
	if (!SetConsoleCtrlHandler(winhandler, TRUE))
		fprintf(stderr, "!unable to create console control handler\n");
#else
	if(signal(SIGINT, handler) == SIG_ERR)
		fprintf(stderr, "!unable to create signal handlers\n");
#ifdef SIGQUIT
	if(signal(SIGQUIT, handler) == SIG_ERR)
		fprintf(stderr, "!unable to create signal handlers\n");
#endif
	if(signal(SIGTERM, handler) == SIG_ERR)
		fprintf(stderr, "!unable to create signal handlers\n");
#endif
#endif

	{
		str lang = "mal";
		/* we inited mal before, so publish its existence */
		if ((err = msab_marchScenario(lang)) != NULL) {
			/* throw the error at the user, but don't die */
			fprintf(stderr, "!%s\n", err);
			free(err);
		}
	}

	{
		/* unlock the vault, first see if we can find the file which
		 * holds the secret */
		char secret[1024];
		char *secretp = secret;
		FILE *secretf;
		size_t len;

		if (GDKgetenv("monet_vault_key") == NULL) {
			/* use a default (hard coded, non safe) key */
			snprintf(secret, sizeof(secret), "%s", "Xas632jsi2whjds8");
		} else {
			if ((secretf = fopen(GDKgetenv("monet_vault_key"), "r")) == NULL) {
				fprintf(stderr,
					"unable to open vault_key_file %s: %s\n",
					GDKgetenv("monet_vault_key"), strerror(errno));
				/* don't show this as a crash */
				msab_registerStop();
				exit(1);
			}
			len = fread(secret, 1, sizeof(secret), secretf);
			secret[len] = '\0';
			len = strlen(secret); /* secret can contain null-bytes */
			if (len == 0) {
				fprintf(stderr, "vault key has zero-length!\n");
				/* don't show this as a crash */
				msab_registerStop();
				exit(1);
			} else if (len < 5) {
				fprintf(stderr, "#warning: your vault key is too short "
								"(%zu), enlarge your vault key!\n", len);
			}
			fclose(secretf);
		}
		if ((err = AUTHunlockVault(secretp)) != MAL_SUCCEED) {
			/* don't show this as a crash */
			msab_registerStop();
			fprintf(stderr, "%s\n", err);
			freeException(err);
			exit(1);
		}
	}
	/* make sure the authorisation BATs are loaded */
	if ((err = AUTHinitTables(NULL)) != MAL_SUCCEED) {
		/* don't show this as a crash */
		msab_registerStop();
		fprintf(stderr, "%s\n", err);
		freeException(err);
		exit(1);
	}
	if (mal_init()) {
		/* don't show this as a crash */
		msab_registerStop();
		return 0;
	}

	if((err = MSinitClientPrg(mal_clients, "user", "main")) != MAL_SUCCEED) {
		msab_registerStop();
		fprintf(stderr, "%s\n", err);
		freeException(err);
		exit(1);
	}

	emergencyBreakpoint();
	for (i = 0; monet_script[i]; i++) {
		str msg = evalFile(monet_script[i], listing);
		/* check for internal exception message to terminate */
		if (msg) {
			if (strcmp(msg, "MALException:client.quit:Server stopped.") == 0)
				mal_exit(0);
			fprintf(stderr, "#%s: %s\n", monet_script[i], msg);
			freeException(msg);
		}
		GDKfree(monet_script[i]);
		monet_script[i] = 0;
	}
	free(monet_script);

	if ((err = msab_registerStarted()) != NULL) {
		/* throw the error at the user, but don't die */
		fprintf(stderr, "!%s\n", err);
		free(err);
	}

#ifdef HAVE_CONSOLE
	if (!monet_daemon) {
		MSserveClient(mal_clients);
	} else
#endif
	while (!interrupted && !GDKexiting()) {
		MT_sleep_ms(100);
	}

	/* mal_exit calls exit, so statements after this call will
	 * never get reached */
	mal_exit(0);

	return 0;
}
Exemple #9
0
int
main(int argc, char **argv)
{
	int i;
	char *err = NULL;
	/*char name[MYBUFSIZ + 1];*/
	char hostname[1024];
	static SOCKET sockfd;
	Actuator ac = NULL;
	int option_index = 0;

	static struct option long_options[13] = {
		{ "port", 1, 0, 'p' },
		{ "actuator", 1, 0, 'a' },
		{ "active", 0, 0, 'a' },
		{ "passive", 0, 0, 'p' },
		{ "statistics", 0, 0, 's' },
		{ "protocol", 1, 0, 'p' },
		{ "events", 1, 0, 'e' },
		{ "host", 1, 0, 'h' },
		{ "help", 1, 0, '?' },
		{ "timestamp", 0, 0, 't' },
		{ "trace", 0, 0, 't' },
		{ 0, 0, 0, 0 }
	};
	THRdata[0] = (void *) file_wastream(stdout, "stdout");
	THRdata[1] = (void *) file_rastream(stdin, "stdin");
	for (i = 0; i < THREADS; i++) {
		GDKthreads[i].tid = i + 1;
	}

	for (;;) {
		/*	int option_index=0;*/
		int c = getopt_long(argc, argv, "p:a:a:p:s:p:e:h:?:t:t:0", long_options, &option_index);

		if (c == -1)
			break;

		switch (c) {
		case 't':
			if (strcmp(long_options[option_index].name, "trace") == 0) {
				trace = optarg ? atol(optarg) : 1;
			} else if (strcmp(long_options[option_index].name, "timestamp") == 0) {
				timestamp = optarg ? atol(optarg) : 1;
			} else {
				usage();
				exit(0);
			}
			break;
		case 'e':
			if (strcmp(long_options[option_index].name, "events") == 0) {
				events = optarg ? atol(optarg) : 1;
			} else {
				usage();
				exit(0);
			}
			break;
		case 'a':
			if (strcmp(long_options[option_index].name, "active") == 0) {
				mode = ACTIVE;
				break;
			} else
				actuator = optarg ? optarg : "dummy";
			break;
		case 'p':
			if (strcmp(long_options[option_index].name, "port") == 0) {
				port = optarg ? atol(optarg) : -1;
				break;
			} else if (strcmp(long_options[option_index].name, "passive") == 0) {
				mode = PASSIVE;
				break;
			} else if (strcmp(long_options[option_index].name, "protocol") == 0) {
				if (strcmp(optarg, "TCP") == 0 || strcmp(optarg, "tcp") == 0) {
					protocol = TCP;
					break;
				}
				if (strcmp(optarg, "UDP") == 0 || strcmp(optarg, "udp") == 0) {
					protocol = UDP;
					break;
				}
			}
			break;
		case 's':
			if (strcmp(long_options[option_index].name, "statistics") == 0) {
				statistics = optarg ? atol(optarg) : 100;
				break;
			} else {
				usage();
				exit(0);
			}
			break;
		case 'h':
			host = optarg;
			break;
		case '?':
		default:
			usage();
			exit(0);
		}
	}

	signal(SIGABRT, stopListening);
#ifdef SIGPIPE
	signal(SIGPIPE, stopListening);
#endif
#ifdef SIGHUP
	signal(SIGHUP, stopListening);
#endif
	signal(SIGTERM, stopListening);
	signal(SIGINT, stopListening);

	/* display properties */
	if (trace) {
		mnstr_printf(ACout, "--host=%s\n", host);
		mnstr_printf(ACout, "--port=%d\n", port);
		mnstr_printf(ACout, "--actuator=%s\n", actuator);
		mnstr_printf(ACout, "--events=%d\n", events);
		mnstr_printf(ACout, "--timestamp=%d\n", timestamp);
		mnstr_printf(ACout, "--statistics=%d\n", statistics);
		mnstr_printf(ACout, "--%s\n", mode == ACTIVE ? "active" : "passive");
	}
	strncpy(hostname, host, 1024);
	if (strcmp(host, "localhost") == 0)
		gethostname(hostname, 1024);
	host = hostname;


	ac = ACnew(actuator);
	/*name[0] = 0;*/
	err = NULL;
	if (mode == PASSIVE) {
		ac->fromServer = udp_rastream(host, port, actuator);
		if (ac->fromServer == 0) {
			mnstr_printf(ACout, "Failed to access stream %s:%d\n", host, port);
			return 0;
		}
		consumeStream(ac);
#ifdef _DEBUG_ACTUATOR_
		mnstr_printf(ACout, "stream consumed\n");
#endif
	}

	if (mode == ACTIVE)
		do {
			err = socket_client_connect(&sockfd, host, port);
			if (err) {
				mnstr_printf(ACout, "actuator connect fails: %s\n", err);
				MT_sleep_ms(1000);
			}
		} while (err);

	if (mode == PASSIVE)
	{
		err = socket_server_listen(sockfd, &(ac->newsockfd));
		if (err) {
			mnstr_printf(ACout, "ACTUATOR:server listen fails:%s\n", err);
			return 0;
		}
	}
	do {
		if (mode == PASSIVE) {
#ifdef _DEBUG_ACTUATOR_
			mnstr_printf(ACout, "Actuator listens\n");
#endif

			if (protocol == UDP)
				ac->fromServer = udp_rastream(host, port, actuator);
			else
				ac->fromServer = socket_rastream(ac->newsockfd, actuator);
			if (ac->fromServer == NULL) {
				perror("Actuator: Could not open stream");
				mnstr_printf(ACout, "stream %s.%d.%s\n", host, port, actuator);
				return 0;
			}
			consumeStream(ac);
		} else if (mode == ACTIVE) {
#ifdef _DEBUG_ACTUATOR_
			mnstr_printf(ACout, "Actuator connects\n");
#endif
			err = socket_client_connect(&(ac->newsockfd), host, port);
			if (err) {
				mnstr_printf(ACout, "ACTUATOR:start client:%s\n", err);
				continue;
			}

#ifdef _DEBUG_ACTUATOR_
			mnstr_printf(ACout, "Initialize stream\n");
#endif
			if (protocol == UDP)
				ac->fromServer = udp_rastream(host, port, actuator);
			else
				ac->fromServer = socket_rastream(ac->newsockfd, actuator);

			if (ac->fromServer == NULL) {
				perror("Actuator: Could not open stream");
				mnstr_printf(ACout, "stream %s.%d.%s\n", host, port, actuator);
				continue;
			}
		}
		consumeStream(ac);
	} while (mode == PASSIVE && (events == -1 || tuples < events));
	socket_close(sockfd);
	terminate(ac);
	return 0;
}
Exemple #10
0
static void
produceDataStream(Sensor se)
{
	char buf[MYBUFSIZ + 1], *tuple, *c, *d;
	FILE *fd;
	int i, snr;
	int multiply=1000, usec = 0; 
	time_t lasttime = 0, tm = 0;
	struct tm stm;

	/* read a events of messages from a file or standard input.
	   It is processed multiple times.
	   The header is the delay imposed */

	snr = 0;
	do {
		if ( datafile == 0){
			fd = stdin;
		} else {
			fd = fopen(datafile, "r");
			if (fd == NULL) {
				mnstr_printf(SEout, "Could not open file '%s'\n", datafile);
				close_stream(se->toServer);
				se->toServer = NULL;
				return;
			}
		}

		/* read the event requests and sent when the becomes */
		while (fgets(buf, MYBUFSIZ, fd) != 0) {
			int newdelay = delay;
			tuple = buf;

			if ( timecolumn >= 0 ) {
				/* calculate the difference with previous event */
				/* use a simplistic csv file format */
				c= buf;
				for ( i = timecolumn; i> 0; i--){
					if ( (d=strchr(c,(int)','))){
						c= d+1;
					}
				}
				/* convert time to epoch in seconds*/
				memset(&stm, 0, sizeof(struct tm));
				if ( c ){
					c = strptime(c,"%Y-%m-%d %H:%M:%S", &stm);
					tm = mktime(&stm);
					if ( *c == '.') {
						/* microseconds */
						usec = atoi(c+1);
						if ( usec)
							multiply = 1;
					}
				} 
				/* calculate time differential in seconds */
				if ( lasttime )
					newdelay = (int) difftime(tm,lasttime) * multiply + usec;
				lasttime = tm;
				if (trace && newdelay)
					mnstr_printf(SEout, "delayed %d\n", newdelay);
				MT_sleep_ms(newdelay);
			} else
			if (delay > 0) {
				/* wait */
				MT_sleep_ms(delay);
			}
			if (delay < 0) {
				mnstr_printf(SEout, "%s", tuple);
				mnstr_printf(SEout, "send it?");
				getchar();
			}
			if (trace)
				mnstr_printf(SEout, "%s", tuple);
			if ((mnstr_write(se->toServer, tuple, 1, strlen(tuple))) == -1 && (errno == EPIPE)) {
				mnstr_printf(SEout, "errno:%s\n", strerror(errno));
				return;
			}
		}
		fclose(fd);
		snr++;
	} while (snr != events);
}
Exemple #11
0
static void
produceStream(Sensor se)
{
	int b;
	int slen;
	char buf[MYBUFSIZ + 1]; /* compose an event message locally first */
	char tuple[MYBUFSIZ + 1];  /* scratch area for a single tuple element */
	int tlen, maxtuple = MYBUFSIZ;
	int buflen;
	int numberOFtuples = 0;

#ifdef SENSOR_DEBUG
	mnstr_printf(SEout, "#Start producing the stream\n");
	mnstr_printf(SEout, "#%d events, batchsize is %d, columns are %d\n", events, batchsize, columns);
#endif

	/* create scratch space for a single tuple, this should be enough for integer fields */
	buflen = 0;
	while (numberOFtuples < (events * batchsize) || events == -1) {
		int i;
		lng currenttsmp = 0;

		if (delay > 0) {
			/* wait */
			MT_sleep_ms(delay);
		}

		if (delay < 0) {
			mnstr_printf(SEout, "#send next?");
			getchar();
		}

		buf[0] = 0;
		slen = 0;
		tlen = 0;
		if (batchsize > 1) {
			snprintf(tuple, maxtuple, "#%d\n", batchsize);
			tlen += (int) strlen(tuple + tlen);
			strncpy(buf, tuple, tlen);
			slen += tlen;
		}
		/* construct a single event record batch */
		for (b = batchsize; b > 0; b--) {
			/* the first column is used for event identifier tagging */
			tlen = 0;
			if (autoincrement) {
				snprintf(tuple + tlen, maxtuple - tlen, "%d", autoincrement);
				tlen += (int) strlen(tuple + tlen);
				autoincrement++;
			}
			/* if timestamp is set then the next colum will contain
			   the wall-clock microstamp. This reduces the number of
			   additional columns to be produced by 1 */
			if (timestamp) {
				currenttsmp = GDKusec();

				snprintf(tuple + tlen, maxtuple - tlen, "%s" LLFMT "", (autoincrement ? separator[protocol] : ""), currenttsmp);
				tlen += (int) strlen(tuple + tlen);
				if (tlen >= maxtuple) {
					mnstr_printf(SEout, "Buffer not large enough to handle request.\n");
					mnstr_printf(SEout, "recompile with larger constant \n");
					return;
				}
			}

			/* we only generate integer based events for now */
			for (i = (timestamp ? 1 : 0) + (autoincrement ? 1 : 0); i < columns; i++) {
				if (i)
					snprintf(tuple + tlen, maxtuple - tlen, "%s%d", separator[protocol], rand());
				else
					snprintf(tuple + tlen, maxtuple - tlen, "%d", rand());
				tlen += (int) strlen(tuple + tlen);
			}
			snprintf(tuple + tlen, maxtuple - tlen, "\n");
			tlen += (int) strlen(tuple + tlen);
			/* now add the tuple to the buffer if there is room left*/
			if (MYBUFSIZ - buflen <= tlen) {
				mnstr_printf(SEout, "Buffer not large enough to handle request.\n");
				mnstr_printf(SEout, "recompile with larger constant \n");
				return;
			}
			strncpy(buf + slen, tuple, tlen);
			slen += tlen;
			numberOFtuples++;
		}
		/* the batch has now been created, it should be shipped */
		/* watch out, the buffer is not NULL terminated */
		if (mnstr_write(se->toServer, buf, 1, slen) == -1 &&
			((errno == EPIPE) || (errno == ECONNRESET))) {
			mnstr_printf(SEout, "errno:%s %d\n", strerror(errno), errno);
			close_stream(se->toServer);
			se->toServer = NULL;
			return;
		}
		if (trace) {
			buf[slen] = 0;
			mnstr_printf(SEout, "%s", buf);
			/*mnstr_flush(SEout);*/
		}
	}
	/* you should not close the stream to quickly
	   because then you may loose part of the input */

	if (protocol != DEB) {
		mnstr_printf(SEout, "Columns: %d\n", columns);
		mnstr_printf(SEout, "Batch size: %d\n", batchsize);
		mnstr_printf(SEout, "total Number of batches: %d\n", events);
		mnstr_printf(SEout, "Delay: %d\n", delay);
	}
	mnstr_printf(SEout, "ready to close connection?");
	(void) getchar();
	close_stream(se->toServer);
	se->toServer = NULL;
}
Exemple #12
0
int
main(int argc, char **av)
{
	char *prog = *av;
	opt *set = NULL;
	int idx = 0, grpdebug = 0, debug = 0, setlen = 0, listing = 0, i = 0;
	str dbinit = NULL;
	str err = MAL_SUCCEED;
	char prmodpath[1024];
	char *modpath = NULL;
	char *binpath = NULL;
	str *monet_script;

	static struct option long_options[] = {
		{ "config", 1, 0, 'c' },
		{ "dbpath", 1, 0, 0 },
		{ "dbinit", 1, 0, 0 },
		{ "daemon", 1, 0, 0 },
		{ "debug", 2, 0, 'd' },
		{ "help", 0, 0, '?' },
		{ "version", 0, 0, 0 },
		{ "readonly", 0, 0, 'r' },
		{ "single-user", 0, 0, 0 },
		{ "set", 1, 0, 's' },
		{ "threads", 0, 0, 0 },
		{ "memory", 0, 0, 0 },
		{ "properties", 0, 0, 0 },
		{ "io", 0, 0, 0 },
		{ "transactions", 0, 0, 0 },
		{ "modules", 0, 0, 0 },
		{ "algorithms", 0, 0, 0 },
		{ "optimizers", 0, 0, 0 },
		{ "performance", 0, 0, 0 },
#if 0
		{ "xproperties", 0, 0, 0 },
#endif
		{ "forcemito", 0, 0, 0 },
		{ "heaps", 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};

#if defined(_MSC_VER) && defined(__cplusplus)
	set_terminate(mserver_abort);
#endif
	if (setlocale(LC_CTYPE, "") == NULL) {
		GDKfatal("cannot set locale\n");
	}

#ifdef HAVE_MALLOPT
	if (malloc_init) {
/* for (Red Hat) Linux (6.2) unused and ignored at least as of glibc-2.1.3-15 */
/* for (Red Hat) Linux (8) used at least as of glibc-2.2.93-5 */
		if (mallopt(M_MXFAST, 192)) {
			fprintf(stderr, "!monet: mallopt(M_MXFAST,192) fails.\n");
		}
#ifdef M_BLKSZ
		if (mallopt(M_BLKSZ, 8 * 1024)) {
			fprintf(stderr, "!monet: mallopt(M_BLKSZ,8*1024) fails.\n");
		}
#endif
	}
	malloc_init = 0;
#else
	(void) malloc_init; /* still unused */
#endif

	if (getcwd(monet_cwd, PATHLENGTH - 1) == NULL) {
		perror("pwd");
		GDKfatal("monet_init: could not determine current directory\n");
	}

	/* retrieve binpath early (before monet_init) because some
	 * implementations require the working directory when the binary was
	 * called */
	binpath = get_bin_path();

	if (!(setlen = mo_builtin_settings(&set)))
		usage(prog, -1);

	for (;;) {
		int option_index = 0;

		int c = getopt_long(argc, av, "c:d::rs:?",
				long_options, &option_index);

		if (c == -1)
			break;

		switch (c) {
		case 0:
			if (strcmp(long_options[option_index].name, "dbpath") == 0) {
				size_t optarglen = strlen(optarg);
				/* remove trailing directory separator */
				while (optarglen > 0 &&
				       (optarg[optarglen - 1] == '/' ||
					optarg[optarglen - 1] == '\\'))
					optarg[--optarglen] = '\0';
				setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_dbpath", optarg);
				break;
			}
			if (strcmp(long_options[option_index].name, "dbinit") == 0) {
				if (dbinit)
					fprintf(stderr, "#warning: ignoring multiple --dbinit argument\n");
				else
					dbinit = optarg;
				break;
			}
#ifdef HAVE_CONSOLE
			if (strcmp(long_options[option_index].name, "daemon") == 0) {
				setlen = mo_add_option(&set, setlen, opt_cmdline, "monet_daemon", optarg);
				break;
			}
#endif
			if (strcmp(long_options[option_index].name, "single-user") == 0) {
				setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_single_user", "yes");
				break;
			}
			if (strcmp(long_options[option_index].name, "version") == 0) {
				monet_version();
				exit(0);
			}
			/* debugging options */
			if (strcmp(long_options[option_index].name, "properties") == 0) {
				grpdebug |= GRPproperties;
				break;
			}
			if (strcmp(long_options[option_index].name, "algorithms") == 0) {
				grpdebug |= GRPalgorithms;
				break;
			}
			if (strcmp(long_options[option_index].name, "optimizers") == 0) {
				grpdebug |= GRPoptimizers;
				break;
			}
#if 0
			if (strcmp(long_options[option_index].name, "xproperties") == 0) {
				grpdebug |= GRPxproperties;
				break;
			}
#endif
			if (strcmp(long_options[option_index].name, "forcemito") == 0) {
				grpdebug |= GRPforcemito;
				break;
			}
			if (strcmp(long_options[option_index].name, "performance") == 0) {
				grpdebug |= GRPperformance;
				break;
			}
			if (strcmp(long_options[option_index].name, "io") == 0) {
				grpdebug |= GRPio;
				break;
			}
			if (strcmp(long_options[option_index].name, "memory") == 0) {
				grpdebug |= GRPmemory;
				break;
			}
			if (strcmp(long_options[option_index].name, "modules") == 0) {
				grpdebug |= GRPmodules;
				break;
			}
			if (strcmp(long_options[option_index].name, "transactions") == 0) {
				grpdebug |= GRPtransactions;
				break;
			}
			if (strcmp(long_options[option_index].name, "threads") == 0) {
				grpdebug |= GRPthreads;
				break;
			}
			if (strcmp(long_options[option_index].name, "heaps") == 0) {
				grpdebug |= GRPheaps;
				break;
			}
			usage(prog, -1);
		/* not reached */
		case 'c':
			setlen = mo_add_option(&set, setlen, opt_cmdline, "config", optarg);
			break;
		case 'd':
			if (optarg) {
				debug |= strtol(optarg, NULL, 10);
			} else {
				debug |= 1;
			}
			break;
		case 'r':
			setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_readonly", "yes");
			break;
		case 's': {
			/* should add option to a list */
			char *tmp = strchr(optarg, '=');

			if (tmp) {
				*tmp = '\0';
				setlen = mo_add_option(&set, setlen, opt_cmdline, optarg, tmp + 1);
			} else {
				fprintf(stderr, "ERROR: wrong format %s\n", optarg);
			}
		}
		break;
		case '?':
			/* a bit of a hack: look at the option that the
			   current `c' is based on and see if we recognize
			   it: if -? or --help, exit with 0, else with -1 */
			usage(prog, strcmp(av[optind - 1], "-?") == 0 || strcmp(av[optind - 1], "--help") == 0 ? 0 : -1);
		default:
			fprintf(stderr, "ERROR: getopt returned character "
							"code '%c' 0%o\n", c, c);
			usage(prog, -1);
		}
	}

	if (!(setlen = mo_system_config(&set, setlen)))
		usage(prog, -1);

	if (debug || grpdebug) {
		long_str buf;

		if (debug)
			mo_print_options(set, setlen);
		debug |= grpdebug;  /* add the algorithm tracers */
		snprintf(buf, sizeof(long_str) - 1, "%d", debug);
		setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_debug", buf);
	}

	monet_script = (str *) malloc(sizeof(str) * (argc + 1));
	if (monet_script) {
		monet_script[idx] = NULL;
		while (optind < argc) {
			monet_script[idx] = absolute_path(av[optind]);
			monet_script[idx + 1] = NULL;
			optind++;
			idx++;
		}
	}

	if (monet_init(set, setlen) == 0) {
		mo_free_options(set, setlen);
		return 0;
	}
	mo_free_options(set, setlen);

	GDKsetenv("monet_version", VERSION);
	GDKsetenv("monet_release", MONETDB_RELEASE);

	if ((modpath = GDKgetenv("monet_mod_path")) == NULL) {
		/* start probing based on some heuristics given the binary
		 * location:
		 * bin/mserver5 -> ../
		 * libX/monetdb5/lib/
		 * probe libX = lib, lib32, lib64, lib/64 */
		char *libdirs[] = { "lib", "lib64", "lib/64", "lib32", NULL };
		size_t i;
		struct stat sb;
		if (binpath != NULL) {
			char *p = strrchr(binpath, DIR_SEP);
			if (p != NULL)
				*p = '\0';
			p = strrchr(binpath, DIR_SEP);
			if (p != NULL) {
				*p = '\0';
				for (i = 0; libdirs[i] != NULL; i++) {
					snprintf(prmodpath, sizeof(prmodpath), "%s%c%s%cmonetdb5",
							binpath, DIR_SEP, libdirs[i], DIR_SEP);
					if (stat(prmodpath, &sb) == 0) {
						modpath = prmodpath;
						break;
					}
				}
			} else {
				printf("#warning: unusable binary location, "
					   "please use --set monet_mod_path=/path/to/... to "
					   "allow finding modules\n");
				fflush(NULL);
			}
		} else {
			printf("#warning: unable to determine binary location, "
				   "please use --set monet_mod_path=/path/to/... to "
				   "allow finding modules\n");
			fflush(NULL);
		}
		if (modpath != NULL)
			GDKsetenv("monet_mod_path", modpath);
	}

	/* configure sabaoth to use the right dbpath and active database */
	msab_dbpathinit(GDKgetenv("gdk_dbpath"));
	/* wipe out all cruft, if left over */
	if ((err = msab_wildRetreat()) != NULL) {
		/* just swallow the error */
		free(err);
	}
	/* From this point, the server should exit cleanly.  Discussion:
	 * even earlier?  Sabaoth here registers the server is starting up. */
	if ((err = msab_registerStarting()) != NULL) {
		/* throw the error at the user, but don't die */
		fprintf(stderr, "!%s\n", err);
		free(err);
	}

#ifdef HAVE_SIGACTION
	{
		struct sigaction sa;

		sigemptyset(&sa.sa_mask);
		sa.sa_flags = 0;
		sa.sa_handler = handler;
		if (
				sigaction(SIGINT, &sa, NULL) == -1 ||
				sigaction(SIGQUIT, &sa, NULL) == -1 ||
				sigaction(SIGTERM, &sa, NULL) == -1)
		{
			fprintf(stderr, "!unable to create signal handlers\n");
		}
	}
#else
	signal(SIGINT, handler);
#ifdef SIGQUIT
	signal(SIGQUIT, handler);
#endif
	signal(SIGTERM, handler);
#endif

	{
		str lang = "mal";
		/* we inited mal before, so publish its existence */
		if ((err = msab_marchScenario(lang)) != NULL) {
			/* throw the error at the user, but don't die */
			fprintf(stderr, "!%s\n", err);
			free(err);
		}
	}

	{
		/* unlock the vault, first see if we can find the file which
		 * holds the secret */
		char secret[1024];
		char *secretp = secret;
		FILE *secretf;
		size_t len;

		if (GDKgetenv("monet_vault_key") == NULL) {
			/* use a default (hard coded, non safe) key */
			snprintf(secret, sizeof(secret), "%s", "Xas632jsi2whjds8");
		} else {
			if ((secretf = fopen(GDKgetenv("monet_vault_key"), "r")) == NULL) {
				snprintf(secret, sizeof(secret),
						"unable to open vault_key_file %s: %s",
						GDKgetenv("monet_vault_key"), strerror(errno));
				/* don't show this as a crash */
				msab_registerStop();
				GDKfatal("%s", secret);
			}
			len = fread(secret, 1, sizeof(secret), secretf);
			secret[len] = '\0';
			len = strlen(secret); /* secret can contain null-bytes */
			if (len == 0) {
				snprintf(secret, sizeof(secret), "vault key has zero-length!");
				/* don't show this as a crash */
				msab_registerStop();
				GDKfatal("%s", secret);
			} else if (len < 5) {
				fprintf(stderr, "#warning: your vault key is too short "
								"(" SZFMT "), enlarge your vault key!\n", len);
			}
			fclose(secretf);
		}
		if ((err = AUTHunlockVault(&secretp)) != MAL_SUCCEED) {
			/* don't show this as a crash */
			msab_registerStop();
			GDKfatal("%s", err);
		}
	}
	/* make sure the authorisation BATs are loaded */
	if ((err = AUTHinitTables()) != MAL_SUCCEED) {
		/* don't show this as a crash */
		msab_registerStop();
		GDKfatal("%s", err);
	}
	if (mal_init()) {
		/* don't show this as a crash */
		msab_registerStop();
		return 0;
	}

	if (GDKgetenv("mal_listing"))
		sscanf(GDKgetenv("mal_listing"), "%d", &listing);

	MSinitClientPrg(mal_clients, "user", "main");
	if (dbinit == NULL)
		dbinit = GDKgetenv("dbinit");
	if (dbinit)
		callString(mal_clients, dbinit, listing);

	emergencyBreakpoint();
	if (monet_script)
		for (i = 0; monet_script[i]; i++) {
			str msg = evalFile(mal_clients, monet_script[i], listing);
			/* check for internal exception message to terminate */
			if (msg) {
				if (strcmp(msg, "MALException:client.quit:Server stopped.") == 0)
					mal_exit();
				fprintf(stderr, "#%s: %s\n", monet_script[i], msg);
				GDKfree(msg);
			}
			GDKfree(monet_script[i]);
			monet_script[i] = 0;
		}

	if ((err = msab_registerStarted()) != NULL) {
		/* throw the error at the user, but don't die */
		fprintf(stderr, "!%s\n", err);
		free(err);
	}

	if (monet_script)
		free(monet_script);
#ifdef HAVE_CONSOLE
	if (!monet_daemon) {
		MSserveClient(mal_clients);
	} else
#endif
	while (1)
		MT_sleep_ms(5000);

	/* mal_exit calls MT_global_exit, so statements after this call will
	 * never get reached */
	mal_exit();

	return 0;
}
Exemple #13
0
static void
DFLOWworker(void *T)
{
	struct worker *t = (struct worker *) T;
	DataFlow flow;
	FlowEvent fe = 0, fnxt = 0;
	int id = (int) (t - workers);
	Thread thr;
	str error = 0;
	int i,last;
	Client cntxt;
	InstrPtr p;

	thr = THRnew("DFLOWworker");

	GDKsetbuf(GDKmalloc(GDKMAXERRLEN)); /* where to leave errors */
	GDKerrbuf[0] = 0;
	MT_lock_set(&dataflowLock, "DFLOWworker");
	cntxt = t->cntxt;
	MT_lock_unset(&dataflowLock, "DFLOWworker");
	if (cntxt) {
		/* wait until we are allowed to start working */
		MT_sema_down(&t->s, "DFLOWworker");
	}
	while (1) {
		if (fnxt == 0) {
			MT_lock_set(&dataflowLock, "DFLOWworker");
			cntxt = t->cntxt;
			MT_lock_unset(&dataflowLock, "DFLOWworker");
			fe = q_dequeue(todo, cntxt);
			if (fe == NULL) {
				if (cntxt) {
					/* we're not done yet with work for the current
					 * client (as far as we know), so give up the CPU
					 * and let the scheduler enter some more work, but
					 * first compensate for the down we did in
					 * dequeue */
					MT_sema_up(&todo->s, "DFLOWworker");
					MT_sleep_ms(1);
					continue;
				}
				/* no more work to be done: exit */
				break;
			}
		} else
			fe = fnxt;
		if (ATOMIC_GET(exiting, exitingLock, "DFLOWworker")) {
			break;
		}
		fnxt = 0;
		assert(fe);
		flow = fe->flow;
		assert(flow);

		/* whenever we have a (concurrent) error, skip it */
		if (flow->error) {
			q_enqueue(flow->done, fe);
			continue;
		}

		/* skip all instructions when we have encontered an error */
		if (flow->error == 0) {
#ifdef USE_MAL_ADMISSION
			if (MALadmission(fe->argclaim, fe->hotclaim)) {
				fe->hotclaim = 0;   /* don't assume priority anymore */
				if (todo->last == 0)
					MT_sleep_ms(DELAYUNIT);
				q_requeue(todo, fe);
				continue;
			}
#endif
			error = runMALsequence(flow->cntxt, flow->mb, fe->pc, fe->pc + 1, flow->stk, 0, 0);
			PARDEBUG fprintf(stderr, "#executed pc= %d wrk= %d claim= " LLFMT "," LLFMT " %s\n",
							 fe->pc, id, fe->argclaim, fe->hotclaim, error ? error : "");
#ifdef USE_MAL_ADMISSION
			/* release the memory claim */
			MALadmission(-fe->argclaim, -fe->hotclaim);
#endif
			/* update the numa information. keep the thread-id producing the value */
			p= getInstrPtr(flow->mb,fe->pc);
			for( i = 0; i < p->argc; i++)
				flow->mb->var[getArg(p,i)]->worker = thr->tid;

			MT_lock_set(&flow->flowlock, "DFLOWworker");
			fe->state = DFLOWwrapup;
			MT_lock_unset(&flow->flowlock, "DFLOWworker");
			if (error) {
				MT_lock_set(&flow->flowlock, "DFLOWworker");
				/* only collect one error (from one thread, needed for stable testing) */
				if (!flow->error)
					flow->error = error;
				MT_lock_unset(&flow->flowlock, "DFLOWworker");
				/* after an error we skip the rest of the block */
				q_enqueue(flow->done, fe);
				continue;
			}
		}

		/* see if you can find an eligible instruction that uses the
		 * result just produced. Then we can continue with it right away.
		 * We are just looking forward for the last block, which means we
		 * are safe from concurrent actions. No other thread can steal it,
		 * because we hold the logical lock.
		 * All eligible instructions are queued
		 */
#ifdef USE_MAL_ADMISSION
		{
		InstrPtr p = getInstrPtr(flow->mb, fe->pc);
		assert(p);
		fe->hotclaim = 0;
		for (i = 0; i < p->retc; i++)
			fe->hotclaim += getMemoryClaim(flow->mb, flow->stk, p, i, FALSE);
		}
#endif
		MT_lock_set(&flow->flowlock, "DFLOWworker");

		for (last = fe->pc - flow->start; last >= 0 && (i = flow->nodes[last]) > 0; last = flow->edges[last])
			if (flow->status[i].state == DFLOWpending &&
				flow->status[i].blocks == 1) {
				flow->status[i].state = DFLOWrunning;
				flow->status[i].blocks = 0;
				flow->status[i].hotclaim = fe->hotclaim;
				flow->status[i].argclaim += fe->hotclaim;
				fnxt = flow->status + i;
				break;
			}
		MT_lock_unset(&flow->flowlock, "DFLOWworker");

		q_enqueue(flow->done, fe);
		if ( fnxt == 0) {
			int last;
			MT_lock_set(&todo->l, "DFLOWworker");
			last = todo->last;
			MT_lock_unset(&todo->l, "DFLOWworker");
			if (last == 0)
				profilerHeartbeatEvent("wait", 0);
		}
	}
	GDKfree(GDKerrbuf);
	GDKsetbuf(0);
	THRdel(thr);
	MT_lock_set(&dataflowLock, "DFLOWworker");
	t->flag = EXITED;
	MT_lock_unset(&dataflowLock, "DFLOWworker");
}