Jelajahi Sumber

HPCC-8030 R/Java/JavaScript/Python language support in ECL

More Java threading/signal issues.

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 12 tahun lalu
induk
melakukan
5d94f6e8af

+ 1 - 9
dali/base/daclient.cpp

@@ -34,7 +34,6 @@
 extern bool registerClientProcess(ICommunicator *comm, IGroup *& retcoven,unsigned timeout,DaliClientRole role);
 extern void stopClientProcess();
 
-static bool restoreSEH=false;
 static bool daliClientIsActive = false;
 static INode * daliClientLoggingParent = 0;
 
@@ -89,13 +88,10 @@ IDaliClient_Exception *createClientException(DaliClientError err, const char *ms
 
 
 
-bool initClientProcess(IGroup *servergrp, DaliClientRole role, unsigned short mpport, const char *clientVersion, const char *minServerVersion, unsigned timeout, bool enableSEH)
+bool initClientProcess(IGroup *servergrp, DaliClientRole role, unsigned short mpport, const char *clientVersion, const char *minServerVersion, unsigned timeout)
 {
     assertex(servergrp);
     daliClientIsActive = true;
-    restoreSEH = enableSEH;
-    if (enableSEH)
-      EnableSEHtoExceptionMapping();
     startMPServer(mpport);
     Owned<ICommunicator> comm(createCommunicator(servergrp,true));
     IGroup * covengrp;
@@ -134,10 +130,6 @@ void closedownClientProcess()
     stopClientProcess();
     closeCoven();
     stopMPServer();
-    if (restoreSEH) {
-        DisableSEHtoExceptionMapping();
-        restoreSEH = false;
-    }
     daliClientIsActive = false;
 }
 

+ 1 - 1
dali/base/daclient.hpp

@@ -26,7 +26,7 @@
 #include "mpcomm.hpp"
 #include "dasds.hpp"
 
-extern da_decl bool initClientProcess(IGroup *servergrp, DaliClientRole role, unsigned short mpport=0, const char *clientVersion=NULL, const char *minServerVersion=NULL, unsigned timeout=MP_WAIT_FOREVER,bool enableSEH=true); 
+extern da_decl bool initClientProcess(IGroup *servergrp, DaliClientRole role, unsigned short mpport=0, const char *clientVersion=NULL, const char *minServerVersion=NULL, unsigned timeout=MP_WAIT_FOREVER);
 extern da_decl bool reinitClientProcess(IGroup *servergrp, DaliClientRole role, const char *clientVersion=NULL, const char *minServerVersion=NULL, unsigned timeout=MP_WAIT_FOREVER); 
 extern da_decl void closedownClientProcess();
 extern da_decl bool daliClientActive();

+ 2 - 1
ecl/eclagent/eclagent.cpp

@@ -3246,7 +3246,7 @@ extern int HTHOR_API eclagent_main(int argc, const char *argv[], StringBuffer *
             {
                 MTIME_SECTION(timer, "SDS_Initialize");
                 Owned<IGroup> serverGroup = createIGroup(daliServers.str(), DALI_SERVER_PORT);
-                initClientProcess(serverGroup, DCR_EclAgent, 0, NULL, NULL, MP_WAIT_FOREVER, false);
+                initClientProcess(serverGroup, DCR_EclAgent, 0, NULL, NULL, MP_WAIT_FOREVER);
             }
 #ifdef MONITOR_ECLAGENT_STATUS  
             serverstatus = new CSDSServerStatus("ECLagent");
@@ -3407,6 +3407,7 @@ void usage(const char * exeName)
 
 int STARTQUERY_API start_query(int argc, const char *argv[])
 {
+    EnableSEHtoExceptionMapping();
     InitModuleObjects();
 
     for (int idx = 1; idx < argc; idx++)

+ 1 - 0
ecl/eclagent/eclagentmain.cpp

@@ -71,6 +71,7 @@ int main(int argc, const char *argv[])
     }
     else
     {
+        EnableSEHtoExceptionMapping();
         InitModuleObjects();
         int ret = 0;
         try

+ 17 - 11
plugins/javaembed/javaembed.cpp

@@ -20,7 +20,6 @@
 #include "eclrtl.hpp"
 #include "jexcept.hpp"
 #include "jthread.hpp"
-#include "jmutex.hpp"
 #include "hqlplugins.hpp"
 
 #ifdef _WIN32
@@ -64,11 +63,16 @@ extern "C" EXPORT bool getECLPluginDefinition(ECLPluginDefinitionBlock *pb)
 namespace javaembed {
 
 // Use a global object to ensure that the Java VM  is initialized once only.
-// We create it lazily for two reasons:
-// 1. So that we only get a JVM if we need onr (even if we have loaded the plugin)
+// We would like to create it lazily for two reasons:
+// 1. So that we only get a JVM if we need one (even if we have loaded the plugin)
 // 2. It's important for the JVM to be initialized AFTER we have set up signal handlers, as it
 //    likes to set its own (in particular, it seems to intercept and ignore some SIGSEGV during the
 //    garbage collection).
+// Unfortunately, it seems that the design of the JNI interface is such that JNI_CreateJavaVM has to be called on the 'main thread'.
+// So we can't achieve 1, and 2 requires that we create via the INIT_MODLE mechanism (rather than just a static object), and that
+// any engines that call InitModuleObjects() or load plugins dynamically do so AFTER setting any signal handlers or calling
+// EnableSEHtoExceptionMapping
+//
 
 static class JavaGlobalState
 {
@@ -99,15 +103,17 @@ public:
         // We don't attempt to destroy the Java VM, as it's buggy...
     }
     JavaVM *javaVM;       /* denotes a Java VM */
-} *globalState = NULL;
+} *globalState;
 
-static CriticalSection globalStateCrit;
-static JavaGlobalState *queryGlobalState()
+MODULE_INIT(INIT_PRIORITY_STANDARD)
 {
-    CriticalBlock b(globalStateCrit);
-    if (!globalState)
-        globalState = new JavaGlobalState;  // Never released. But we don't care - JavaVM does not work if you destroy and try to recreate
-    return globalState;
+    globalState = new JavaGlobalState;
+    return true;
+}
+MODULE_EXIT()
+{
+    delete globalState;
+    globalState = NULL;
 }
 
 // There is a singleton JavaThreadContext per thread. This allows us to
@@ -120,7 +126,7 @@ public:
 public:
     JavaThreadContext()
     {
-        jint res = queryGlobalState()->javaVM->AttachCurrentThread((void **) &JNIenv, NULL);
+        jint res = globalState->javaVM->AttachCurrentThread((void **) &JNIenv, NULL);
         assertex(res >= 0);
         javaClass = NULL;
         javaMethodID = NULL;

+ 4 - 2
roxie/ccd/ccdmain.cpp

@@ -433,6 +433,10 @@ public:
 
 int STARTQUERY_API start_query(int argc, const char *argv[])
 {
+    EnableSEHtoExceptionMapping();
+    setTerminateOnSEH();
+    init_signals();
+    // We need to do the above BEFORE we call InitModuleObjects
     InitModuleObjects();
     getDaliServixPort();
     init_signals();
@@ -492,8 +496,6 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
 #endif
     srand( (unsigned)time( NULL ) );
     ccdChannels = createPTree("Channels");
-    EnableSEHtoExceptionMapping();
-    setTerminateOnSEH();
 
     char currentDirectory[_MAX_DIR];
     if (!getcwd(currentDirectory, sizeof(currentDirectory)))

TEMPAT SAMPAH
testing/ecl/JavaCat.class