Changeset: cc42e97a3bca for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=cc42e97a3bca Added Files: gdk/gdk_interprocess.c gdk/gdk_interprocess.h java/tests/Test_PSgetObject.java sql/jdbc/tests/Tests/Test_PSgetObject.SQL.bat sql/jdbc/tests/Tests/Test_PSgetObject.SQL.sh sql/jdbc/tests/Tests/Test_PSgetObject.stable.err sql/jdbc/tests/Tests/Test_PSgetObject.stable.out Removed Files: gdk/interprocess.c gdk/interprocess.h Modified Files: gdk/Makefile.ag gdk/gdk.h gdk/gdk_batop.c gdk/gdk_group.c java/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java monetdb5/extras/pyapi/connection.c monetdb5/extras/pyapi/pyapi.c sql/jdbc/tests/Tests/All sql/test/pg_regress/Tests/point.sql sql/test/pg_regress/Tests/point.stable.err sql/test/pg_regress/Tests/point.stable.out testing/Mtest.py.in Branch: jit Log Message:
Merge with default diffs (truncated from 1728 to 300 lines): diff --git a/gdk/Makefile.ag b/gdk/Makefile.ag --- a/gdk/Makefile.ag +++ b/gdk/Makefile.ag @@ -30,9 +30,10 @@ lib_gdk = { gdk_imprints.c gdk_imprints.h \ gdk_join.c gdk_project.c \ gdk_unique.c \ + gdk_interprocess.c gdk_interprocess.h \ gdk_firstn.c \ bat.feps bat1.feps bat2.feps \ - libbat.rc interprocess.c interprocess.h + libbat.rc LIBS = ../common/options/libmoptions \ ../common/stream/libstream \ ../common/utils/libmutils \ diff --git a/gdk/gdk.h b/gdk/gdk.h --- a/gdk/gdk.h +++ b/gdk/gdk.h @@ -582,11 +582,9 @@ typedef oid var_t; /* type used for hea #define SIZEOF_VAR_T SIZEOF_OID #define VARFMT OIDFMT -#if SIZEOF_VAR_T == SIZEOF_INT /* a type compatible with var_t */ -#define TYPE_var TYPE_int +#if SIZEOF_VAR_T == SIZEOF_INT #define VAR_MAX ((var_t) INT_MAX) #else -#define TYPE_var TYPE_lng #define VAR_MAX ((var_t) LLONG_MAX) #endif @@ -893,7 +891,7 @@ typedef struct BATiter { oid tvid; } BATiter; -/* macros's to hide complexity of BAT structure */ +/* macros to hide complexity of the BAT structure */ #define batPersistence S.persistence #define batCopiedtodisk S.copiedtodisk #define batDirty S.dirty diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c --- a/gdk/gdk_batop.c +++ b/gdk/gdk_batop.c @@ -189,16 +189,18 @@ insert_string_bat(BAT *b, BAT *n, int fo tt = TYPE_sht; tp = &tsv; break; -#if SIZEOF_VAR_T == 8 case 4: tt = TYPE_int; tp = &tiv; break; +#if SIZEOF_VAR_T == 8 + case 8: + tt = TYPE_lng; + tp = &v; + break; #endif default: - tt = TYPE_var; - tp = &v; - break; + assert(0); } b->tvarsized = 0; b->ttype = tt; diff --git a/gdk/gdk_group.c b/gdk/gdk_group.c --- a/gdk/gdk_group.c +++ b/gdk/gdk_group.c @@ -560,14 +560,16 @@ BATgroup_internal(BAT **groups, BAT **ex case 2: t = TYPE_sht; break; -#if SIZEOF_VAR_T == 8 case 4: t = TYPE_int; break; +#if SIZEOF_VAR_T == 8 + case 8: + t = TYPE_lng; + break; #endif default: - t = TYPE_var; - break; + assert(0); } } diff --git a/gdk/gdk_interprocess.c b/gdk/gdk_interprocess.c new file mode 100644 --- /dev/null +++ b/gdk/gdk_interprocess.c @@ -0,0 +1,377 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 1997 - July 2008 CWI, August 2008 - 2016 MonetDB B.V. + */ + +#include "gdk_interprocess.h" + +#ifdef HAVE_FORK + +#include "gdk.h" +#include "gdk_private.h" + +#include <stdlib.h> +#include <assert.h> +#include <string.h> + +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/wait.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sched.h> +#include <errno.h> +#include <sys/sem.h> +#include <time.h> + +static size_t interprocess_unique_id = 1; +static key_t base_key = 800000000; + +gdk_return interprocess_init_semaphore(int id, int count, int flags, int *semid, str *msg); + +// Regular ftok produces too many collisions +static gdk_return +ftok_enhanced(int id, key_t * return_key) +{ + *return_key = base_key + id; + return GDK_SUCCEED; +} + +#define interprocess_create_error(...) { \ + *msg = (char*) GDKzalloc(500 * sizeof(char)); \ + snprintf(*msg, 500, __VA_ARGS__); \ + errno = 0; \ +} + +//! Obtain a set of unique identifiers that can be used to create memory mapped files or semaphores +/* offset: The amount of unique identifiers necessary + * return: The first unique identifier reserved. The consecutive [offset] identifiers are also reserved. + * (ex. if offset = 5 and the return value is 10, then the identifiers 10-14 are reserved) +*/ +size_t +GDKuniqueid(size_t offset) +{ + // TODO: lock this here instead of in pyapi + size_t id; + + id = interprocess_unique_id; + interprocess_unique_id += offset; + return id; +} + +//! Create a memory mapped file if it does not exist and open it +/* id: The unique identifier of the memory mapped file (use GDKuniquemmapid to get a unique identifier) + * size: Minimum required size of the file + * return_ptr: Return value pointing into the file + * msg: Error message (only set if function returns GDK_FAIL) + * return: GDK_SUCCEED if successful, GDK_FAIL if not successful (with msg set to error message) +*/ +gdk_return +GDKinitmmap(size_t id, size_t size, void **return_ptr, size_t *return_size, str *msg) +{ + char address[100]; + void *ptr; + int fd; + int mod = MMAP_READ | MMAP_WRITE | MMAP_SEQUENTIAL | MMAP_SYNC | MAP_SHARED; + char *path = NULL; + GDKmmapfile(address, 100, id); + + /* round up to multiple of GDK_mmap_pagesize with a + * minimum of one + size = (maxsize + GDK_mmap_pagesize - 1) & ~(GDK_mmap_pagesize - 1); + if (size == 0) + size = GDK_mmap_pagesize; */ + fd = GDKfdlocate(0, address, "wb", "tmp"); + if (fd < 0) { + interprocess_create_error("Failure in GDKfdlocate: %s", strerror(errno)); + goto cleanup; + } + path = GDKfilepath(0, BATDIR, address, "tmp"); + if (path == NULL) { + interprocess_create_error("Failure in GDKfilepath: %s", strerror(errno)); + goto cleanup; + } + close(fd); + if (GDKextend(path, size) != GDK_SUCCEED) { + interprocess_create_error("Failure in GDKextend: %s", strerror(errno)); + goto cleanup; + } + ptr = GDKmmap(path, mod, size); + if (ptr == NULL) { + interprocess_create_error("Failure in GDKmmap: %s", strerror(errno)); + goto cleanup; + } + GDKfree(path); + if (return_ptr != NULL) { + *return_ptr = ptr; + } + if (return_size != NULL) { + *return_size = size; + } + return GDK_SUCCEED; + cleanup: + if (path) + GDKfree(path); + return GDK_FAIL; +} + +//! Release a memory mapped file that was created through GDKinitmmap +/* ptr: Pointer to the file + * size: Size of the file + * id: Identifier of the file + * msg: Error message (only set if function returns GDK_FAIL) + * return: GDK_SUCCEED if successful, GDK_FAIL if not successful (with msg set to error message) +*/ +gdk_return +GDKreleasemmap(void *ptr, size_t size, size_t id, str *msg) +{ + char address[100]; + char *path; + int ret; + GDKmmapfile(address, 100, id); + if (GDKmunmap(ptr, size) != GDK_SUCCEED) { + interprocess_create_error("Failure in GDKmunmap: %s", strerror(errno)); + return GDK_FAIL; + } + path = GDKfilepath(0, BATDIR, address, "tmp"); + if (path == NULL) { + interprocess_create_error("Failure in GDKfilepath: %s", strerror(errno)); + return GDK_FAIL; + } + ret = remove(path); + GDKfree(path); + if (ret < 0) { + interprocess_create_error("Failure in GDKfree: %s", strerror(errno)); + return GDK_FAIL; + } + return GDK_SUCCEED; +} + +//! snprintf the file name of a memory mapped file (as created by GDKinitmmap) +/* buffer: The buffer to write the name to + * max: The maxsize of the buffer (should be at least ~10 characters) + * id: Identifier of the file +*/ +gdk_return +GDKmmapfile(str buffer, size_t max, size_t id) +{ + snprintf(buffer, max, "pymmap%zu", id); + return GDK_SUCCEED; +} + +gdk_return +interprocess_init_semaphore(int id, int count, int flags, int *semid, str *msg) +{ + key_t key; + if (ftok_enhanced(id, &key) != GDK_SUCCEED) { + interprocess_create_error("Failure in ftok_enhanced: %s", strerror(errno)); + return GDK_FAIL; + } + *semid = semget(key, count, flags | 0666); + if (*semid < 0) { + interprocess_create_error("Failure in semget: %s", strerror(errno)); + return GDK_FAIL; + } + return GDK_SUCCEED; +} + +//! Create an interprocess semaphore +/* id: identifier (obtain from GDKuniqueid) + * count: amount of semaphores + * semid: identifier of the created semaphore (only set if function returns GDK_SUCCEED) + * msg: Error message (only set if function returns GDK_FAIL) + */ +gdk_return +GDKcreatesem(int id, int count, int *semid, str *msg) +{ + return interprocess_init_semaphore(id, count, IPC_CREAT, semid, msg); +} + +//! Get an interprocess semaphore that was already created using GDKcreatesem +/* id: identifier (obtain from GDKuniqueid) + * count: amount of semaphores + * semid: identifier of the semaphore (only set if function returns GDK_SUCCEED) + * msg: Error message (only set if function returns GDK_FAIL) + */ +gdk_return +GDKgetsem(int id, int count, int *semid, str *msg) +{ + return interprocess_init_semaphore(id, count, 0, semid, msg); +} _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list