Changeset: 441cf4e76086 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/441cf4e76086
Modified Files:
        clients/Tests/exports.stable.out
        monetdb5/mal/mal.c
        monetdb5/mal/mal_interpreter.c
        monetdb5/mal/mal_interpreter.h
        monetdb5/mal/mal_private.h
Branch: default
Log Message:

Make Client cntxt available through a thread-local variable

This way not only 'pattern' but also 'command' MAL operators
can access it.


diffs (157 lines):

diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -1008,6 +1008,7 @@ int getBitConstant(MalBlkPtr mb, bit val
 int getBlockBegin(MalBlkPtr mb, int pc);
 int getBlockExit(MalBlkPtr mb, int pc);
 int getBteConstant(MalBlkPtr mb, bte val);
+Client getClientContext(void);
 int getDblConstant(MalBlkPtr mb, dbl val);
 lng getDiskReads(void);
 lng getDiskSpace(void);
diff --git a/monetdb5/mal/mal.c b/monetdb5/mal/mal.c
--- a/monetdb5/mal/mal.c
+++ b/monetdb5/mal/mal.c
@@ -40,6 +40,82 @@ MT_Lock     mal_profileLock = MT_LOCK_IN
 MT_Lock     mal_copyLock = MT_LOCK_INITIALIZER(mal_copyLock);
 MT_Lock     mal_delayLock = MT_LOCK_INITIALIZER(mal_delayLock);
 
+
+
+#ifdef HAVE_PTHREAD_H
+
+static pthread_key_t tl_client_key;
+
+static int
+initialize_tl_client_key(void)
+{
+       static bool initialized = false;
+       if (initialized)
+               return 0;
+
+       if (pthread_key_create(&tl_client_key, NULL) != 0)
+               return -1;
+
+       initialized = true;
+       return 0;
+}
+
+/* declared in mal_interpreter.h so MAL operators can access it */
+Client
+getClientContext(void)
+{
+       return (Client) pthread_getspecific(tl_client_key);
+}
+
+/* declared in mal_private.h so only the MAL interpreter core can access it */
+void
+setClientContext(Client cntxt)
+{
+       if (pthread_setspecific(tl_client_key, cntxt) != 0)
+               GDKfatal("Failed to set thread local Client context");
+}
+
+#elif defined(Win32)
+
+static DWORD tl_client_key = 0;
+
+static int
+initialize_tl_client_key(void)
+{
+       static bool initialized = false;
+       if (initialized)
+               return 0;
+
+       DWORD key = TlsAlloc();
+       if (key == TLS_OUT_OF_INDEXES)
+               return -1;
+
+       tl_client_key = key;
+       initialized = true;
+       return 0;
+}
+
+/* declared in mal_interpreter.h so MAL operators can access it */
+Client
+getClientContext(void)
+{
+       return (Client) TlsGetValue(tl_client_key);
+}
+
+/* declared in mal_private.h so only the MAL interpreter core can access it */
+void
+setClientContext(Client cntxt)
+{
+       if (TlsSetValue(tl_client_key, cntxt) != 0)
+               GDKfatal("Failed to set thread local Client context");
+}
+
+#else
+
+#error "no pthreads and no Win32, don't know what to do"
+
+#endif
+
 const char *
 mal_version(void)
 {
@@ -70,6 +146,9 @@ mal_init(char *modules[], bool embedded)
                return -1;
        }
 
+       if (initialize_tl_client_key() != 0)
+               return -1;
+
        if ((err = AUTHinitTables(NULL)) != MAL_SUCCEED) {
                freeException(err);
                return -1;
diff --git a/monetdb5/mal/mal_interpreter.c b/monetdb5/mal/mal_interpreter.c
--- a/monetdb5/mal/mal_interpreter.c
+++ b/monetdb5/mal/mal_interpreter.c
@@ -523,6 +523,8 @@ str runMALsequence(Client cntxt, MalBlkP
        /* save, in case this function is called recursively */
        QryCtx *qry_ctx_save = MT_thread_get_qry_ctx();
        MT_thread_set_qry_ctx(&qry_ctx);
+       Client outer_cntxt = getClientContext();
+       setClientContext(cntxt);
 
        while (stkpc < mb->stop && stkpc != stoppc) {
                // incomplete block being executed, requires at least signature 
and end statement
@@ -1232,7 +1234,11 @@ str runMALsequence(Client cntxt, MalBlkP
                        stkpc= mb->stop;
                }
        }
+
+       /* restore saved values */
        MT_thread_set_qry_ctx(qry_ctx_save);
+       setClientContext(outer_cntxt);
+
 
        /* if we could not find the exception variable, cascade a new one */
        /* don't add 'exception not caught' extra message for MAL sequences 
besides main function calls */
diff --git a/monetdb5/mal/mal_interpreter.h b/monetdb5/mal/mal_interpreter.h
--- a/monetdb5/mal/mal_interpreter.h
+++ b/monetdb5/mal/mal_interpreter.h
@@ -33,6 +33,9 @@ mal_export void garbageCollector(Client 
 mal_export str malCommandCall(MalStkPtr stk, InstrPtr pci);
 mal_export int isNotUsedIn(InstrPtr p, int start, int a);
 
+/* defined in mal.c */
+mal_export Client getClientContext(void);
+
 mal_export ptr getArgReference(MalStkPtr stk, InstrPtr pci, int k);
 #if !defined(NDEBUG) && defined(__GNUC__)
 /* for ease of programming and debugging (assert reporting a useful
diff --git a/monetdb5/mal/mal_private.h b/monetdb5/mal/mal_private.h
--- a/monetdb5/mal/mal_private.h
+++ b/monetdb5/mal/mal_private.h
@@ -41,6 +41,9 @@ str yieldFactory(MalBlkPtr mb, InstrPtr 
        __attribute__((__visibility__("hidden")));
 str callFactory(Client cntxt, MalBlkPtr mb, ValPtr argv[],char flag)
        __attribute__((__visibility__("hidden")));
+
+void setClientContext(Client cntxt)
+       __attribute__((__visibility__("hidden")));
 #endif
 
 str malAtomDefinition(const char *name,int tpe)
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to