gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r3070 - in freeway: . native src/org/gnu/freeway/cwrappers


From: mdonoughe
Subject: [GNUnet-SVN] r3070 - in freeway: . native src/org/gnu/freeway/cwrappers src/org/gnu/freeway/cwrappers/util src/org/gnu/freeway/server src/org/gnu/freeway/services/impl src/org/gnu/freeway/util
Date: Tue, 27 Jun 2006 20:42:44 -0700 (PDT)

Author: mdonoughe
Date: 2006-06-27 20:42:38 -0700 (Tue, 27 Jun 2006)
New Revision: 3070

Modified:
   freeway/build.sh
   freeway/native/org_gnu_freeway_server_CPluginLoader.c
   freeway/src/org/gnu/freeway/cwrappers/ConstCString.java
   freeway/src/org/gnu/freeway/cwrappers/util/SwitchTableGenerator.java
   freeway/src/org/gnu/freeway/server/CPluginLoader.java
   freeway/src/org/gnu/freeway/server/CoreAPI.java
   freeway/src/org/gnu/freeway/services/impl/StatsService.java
   freeway/src/org/gnu/freeway/util/NativeService.java
Log:
only loads libraries once
ConstCString no longer creates empty char arrays
sets some stats


Modified: freeway/build.sh
===================================================================
--- freeway/build.sh    2006-06-27 14:21:05 UTC (rev 3069)
+++ freeway/build.sh    2006-06-28 03:42:38 UTC (rev 3070)
@@ -3,4 +3,4 @@
 # Build Freeway and it's C libraries.
 #
 
-ant && make && cp native/.libs/lib*.so* build/ && cp 
etc/support/clib/.libs/lib*.so* build/
+ant && javah -classpath build/classes -d native 
org.gnu.freeway.server.CPluginLoader && make && cp native/.libs/lib*.so* build/ 
&& cp etc/support/clib/.libs/lib*.so* build/

Modified: freeway/native/org_gnu_freeway_server_CPluginLoader.c
===================================================================
--- freeway/native/org_gnu_freeway_server_CPluginLoader.c       2006-06-27 
14:21:05 UTC (rev 3069)
+++ freeway/native/org_gnu_freeway_server_CPluginLoader.c       2006-06-28 
03:42:38 UTC (rev 3070)
@@ -43,7 +43,11 @@
 typedef struct ModuleList {
   void * modulePtr;
   void * moduleFptrStruct;
-  char * name; /* for debugging */
+  char * prefix;
+  char * name;
+  unsigned int refs;
+  char protocolInit;
+  Mutex mutex; //stop initialization races
   struct ModuleList * next;
 } ModuleList;
 
@@ -68,9 +72,89 @@
  */
 static ModuleList * modules;
 static ActiveThreadList * threads;
+Mutex modulesLock;
 Mutex threadsLock;
 
 /**
+ * get a ModuleList structure. will attempt to load the library if needed
+ * @param the prefix
+ * @param the name of the library
+ * @return the ModuleList or NULL if the library cannot be loaded
+ */
+ModuleList * getModule(char * prefix, char * name) {
+  //Look for an already loaded module
+  ModuleList * pos;
+  void * temp;
+  MUTEX_LOCK(&modulesLock);
+  pos = modules;
+  while(pos != NULL) {
+    if(pos->prefix == NULL || pos->name == NULL)
+      continue;
+    if(strcmp(prefix, pos->prefix) != 0)
+      continue;
+    if(strcmp(name, pos->name) == 0)
+      break;
+    pos = pos->next;
+  }
+  if(pos != NULL) {
+    pos->refs++;
+    MUTEX_UNLOCK(&modulesLock);
+    return pos;
+  }
+  //Load a new module
+fprintf(stderr, "Loading new dynamic library %s %s\n", prefix, name);
+  temp = loadDynamicLibrary(prefix, name);
+  if(temp == NULL) {
+    MUTEX_UNLOCK(&modulesLock);
+    return NULL;
+  }
+  pos = MALLOC(sizeof(ModuleList));
+  pos->modulePtr = temp;
+  pos->moduleFptrStruct = NULL;
+  pos->prefix = STRDUP(prefix);
+  pos->name = STRDUP(name);
+  pos->refs = 1;
+  pos->protocolInit = 0;
+  MUTEX_CREATE(&pos->mutex); //does not need locked here
+  pos->next = modules;
+  modules = pos;
+  MUTEX_UNLOCK(&modulesLock);
+  return pos;
+}
+
+/**
+ * decrement the references count on a ModuleList. module will be destroyed if 
the count reaches 0
+ * @param target ModuleList
+ */
+void releaseModule(ModuleList * module) {
+  MUTEX_LOCK(&modulesLock);
+  module->refs--;
+  if(module->refs != 0) {
+    MUTEX_UNLOCK(&modulesLock);
+    //module still in use
+    return;
+  }
+  //Look for this module in the list
+  ModuleList * pos;
+  pos = modules;
+  if(pos != module) {
+    while(pos->next != NULL && pos->next != module) {
+      pos = pos->next;
+    }
+    if(pos->next != NULL)
+      pos->next = pos->next->next;
+  } else {
+    modules = modules->next;
+  }
+  MUTEX_UNLOCK(&modulesLock);
+  unloadDynamicLibrary(module->modulePtr);
+  FREE(module->prefix);
+  FREE(module->name);
+  MUTEX_DESTROY(&module->mutex);
+  FREE(module);
+}
+
+/**
  * add an entry for this thread in ActiveThreadList
  * @param our JNIEnv
  * @param our jcapi
@@ -322,7 +406,7 @@
 }
 
 static void * jrequestService(const char * name) {
-fprintf(stderr, "in jrequestService\n");
+fprintf(stderr, "in jrequestService %s\n", name);
   ActiveThreadList * t;
   jstring mname;
   jmethodID method;
@@ -685,41 +769,30 @@
   (JNIEnv *env, jobject cls, jstring serviceName, jobject capi) {
        registerThread(env, capi);
        const char *strServiceName;
-       void * modulePtr;
        ModuleList * m;
-       void * fptr;
        ServiceInitMethod mptr;
        jclass UnsatisfiedLinkError;
 
        strServiceName = (*env)->GetStringUTFChars(env, serviceName, NULL);
-       if (! strServiceName)
-               return 0;
-       modulePtr = loadDynamicLibrary(DSO_PREFIX, strServiceName);
-       if (! modulePtr) 
+       GNUNET_ASSERT(strServiceName != NULL);
+       m = getModule(DSO_PREFIX, strServiceName);
+       if (m == NULL) 
                goto ULE;
-       mptr = bindDynamicMethod(modulePtr,
-                                 "provide_",
-                                strServiceName);
-       if (mptr == NULL) 
-               goto ULE;
-        m = MALLOC(sizeof(ModuleList));
-        m->modulePtr = modulePtr;
-       m->moduleFptrStruct = NULL;
-        m->name = STRDUP(strServiceName);
-       m->next = modules;
-       modules = m;
-        fptr = mptr(&jcapi);
-       /* by JNI API definition, these are no longer valid
-          after we return! */
-       if (fptr == NULL) {
-         FREE(m->name);
-         /* FIXME: concurrent modification of modules... */
-         modules = m->next;
-         FREE(m);
-         goto ULE;
+       if(m->moduleFptrStruct == NULL) {
+               mptr = bindDynamicMethod(m->modulePtr,
+                                       "provide_",
+                                       strServiceName);
+               if (mptr == NULL) {
+                       releaseModule(m);
+                       goto ULE;
+               }
+               m->moduleFptrStruct = mptr(&jcapi);
+               if (m->moduleFptrStruct == NULL) {
+                 releaseModule(m);
+                 goto ULE;
+               }
+               (*env)->ReleaseStringUTFChars(env, serviceName, strServiceName);
        }
-       m->moduleFptrStruct = fptr;
-       (*env)->ReleaseStringUTFChars(env, serviceName, strServiceName);
        unregisterThread();
        return (jlong) (long) m;
 ULE:        
@@ -735,35 +808,38 @@
   (JNIEnv *env, jobject cls, jstring protocolName, jobject capi) {
        registerThread(env, capi);
        const char *strProtocolName;
-       void * modulePtr;
        int ok;
         ModuleList * m;
         ApplicationInitMethod mptr;
        jclass UnsatisfiedLinkError;
        strProtocolName = (*env)->GetStringUTFChars(env, protocolName, NULL);
-       if (! strProtocolName)
-               return 0;
-       modulePtr = loadDynamicLibrary(DSO_PREFIX, strProtocolName);
-       if (! modulePtr)
+       if (strProtocolName == NULL)
+               return SYSERR;
+       m = getModule(DSO_PREFIX, strProtocolName);
+       if (m == NULL)
                goto ULE;
-       mptr = bindDynamicMethod(modulePtr,
-                                 "initialize_",
+       MUTEX_LOCK(&m->mutex);
+       if(m->protocolInit) {
+               MUTEX_UNLOCK(&m->mutex);
+               releaseModule(m);
+               return SYSERR;
+       }
+       mptr = bindDynamicMethod(m->modulePtr,
+                                        "initialize_",
                                 strProtocolName);
-       if (mptr == NULL)
+       if (mptr == NULL) {
+               MUTEX_UNLOCK(&m->mutex);
+               releaseModule(m);
                goto ULE;
-       m = MALLOC(sizeof(ModuleList));
-        m->modulePtr = modulePtr;
+       }
+       ok = mptr(&jcapi);
        m->moduleFptrStruct = NULL;
-        m->name = STRDUP(strProtocolName);
-       m->next = modules;
-       modules = m;
-        ok = mptr(&jcapi);
-       m->moduleFptrStruct = NULL;
        if (ok == SYSERR) {
-         FREE(m->name);
-         /* FIXME: concurrent modification of modules... */
-         modules = m->next;
-         FREE(m);
+               MUTEX_UNLOCK(&m->mutex);
+               releaseModule(m);
+       } else {
+               m->protocolInit = 1;
+               MUTEX_UNLOCK(&m->mutex);
        }
        (*env)->ReleaseStringUTFChars(env, protocolName, strProtocolName);
        unregisterThread();
@@ -780,6 +856,7 @@
 JNIEXPORT jint JNICALL Java_org_gnu_freeway_server_CPluginLoader_cInitUtil
 (JNIEnv * env, jclass cls, jobjectArray args) {
   MUTEX_CREATE(&threadsLock);
+  MUTEX_CREATE(&modulesLock);
   registerThread(env, 0);
   char * * jargs = NULL;
   int jargLength;
@@ -811,7 +888,7 @@
 }
 
 JNIEXPORT jobject JNICALL Java_org_gnu_freeway_server_CPluginLoader_cCallC
-(JNIEnv *env, jobject cls, jlong modulePtr, jobject capi, jint functionOffset, 
jint functionType, jobjectArray arguments) {
+(JNIEnv *env, jclass cls, jlong modulePtr, jobject capi, jint functionOffset, 
jint functionType, jobjectArray arguments) {
   ActiveThreadList * t = registerThread(env, capi);
   ModuleList * m = (ModuleList*) (long) modulePtr;
   jobject oret = 0;
@@ -877,7 +954,8 @@
   GNUNET_ASSERT(strLibPrefix != NULL);
   const char * strDsoName = (*env)->GetStringUTFChars(env, dsoName, NULL);
   GNUNET_ASSERT(strDsoName != NULL);
-  long returnValue = (long) loadDynamicLibrary(strLibPrefix, strDsoName);
+  long returnValue = (long) getModule(strLibPrefix, strDsoName);
+  //long returnValue = (long) loadDynamicLibrary(strLibPrefix, strDsoName);
   (*env)->ReleaseStringUTFChars(env, libPrefix, strLibPrefix);
   (*env)->ReleaseStringUTFChars(env, dsoName, strDsoName);
   unregisterThread();
@@ -887,7 +965,8 @@
 JNIEXPORT void JNICALL 
Java_org_gnu_freeway_server_CPluginLoader_cUnloadDynamicLibrary
   (JNIEnv *env, jobject cls, jlong libHandle) {
   registerThread(env, 0);
-  unloadDynamicLibrary((void *)(long)libHandle);
+  //unloadDynamicLibrary((void *)(long)libHandle);
+  releaseModule((void *)(long)libHandle);
   unregisterThread();
 }
 

Modified: freeway/src/org/gnu/freeway/cwrappers/ConstCString.java
===================================================================
--- freeway/src/org/gnu/freeway/cwrappers/ConstCString.java     2006-06-27 
14:21:05 UTC (rev 3069)
+++ freeway/src/org/gnu/freeway/cwrappers/ConstCString.java     2006-06-28 
03:42:38 UTC (rev 3070)
@@ -50,9 +50,11 @@
                } catch(UnsupportedEncodingException e) {
                        //TODO: what happens here?
                }
-               string = (byte[]) 
Array.newInstance(string.getClass().getComponentType(), string.length + 1);
-               string[string.length - 1] = 0;
-               return string;
+               byte[] string0 = (byte[]) 
Array.newInstance(string.getClass().getComponentType(), string.length + 1);
+               System.arraycopy(string, 0, string0, 0, string.length);
+               string0[string.length] = 0;
+               
+               return string0;
        }
 
        /* (non-Javadoc)

Modified: freeway/src/org/gnu/freeway/cwrappers/util/SwitchTableGenerator.java
===================================================================
--- freeway/src/org/gnu/freeway/cwrappers/util/SwitchTableGenerator.java        
2006-06-27 14:21:05 UTC (rev 3069)
+++ freeway/src/org/gnu/freeway/cwrappers/util/SwitchTableGenerator.java        
2006-06-28 03:42:38 UTC (rev 3070)
@@ -600,8 +600,8 @@
                int ic = 0;
                for(Iterator i = order.iterator(); i.hasNext(); )
                        writer.write(((String) 
methodList.get(i.next())).replace("__FUNCTIONINDEX__", Integer.toString(ic++)) 
+ "\n\n");
-               writer.write("  public " + stripPackage(c.getName()) + "() 
{\n");
-               writer.write("          super();\n");
+               writer.write("  public " + stripPackage(c.getName()) + "(" + 
cleanClassName("org.gnu.freeway.server.CPluginLoader", imports) + " loader) 
{\n");
+               writer.write("          super(loader);\n");
                writer.write("  }\n");
                writer.write("}\n");
        }

Modified: freeway/src/org/gnu/freeway/server/CPluginLoader.java
===================================================================
--- freeway/src/org/gnu/freeway/server/CPluginLoader.java       2006-06-27 
14:21:05 UTC (rev 3069)
+++ freeway/src/org/gnu/freeway/server/CPluginLoader.java       2006-06-28 
03:42:38 UTC (rev 3070)
@@ -23,6 +23,8 @@
 import java.lang.reflect.Method;
 
 import org.gnu.freeway.cwrappers.util.SwitchTableGenerator;
+import org.gnu.freeway.util.LoggedObject;
+import org.gnu.freeway.util.NativeService;
 import org.gnu.freeway.util.net.CSNativeMessage;
 import org.gnu.freeway.util.net.CSSession;
 
@@ -31,7 +33,7 @@
  * @brief
  * @author mdonoughe
  */
-public class CPluginLoader {
+public class CPluginLoader extends LoggedObject {
 
        static {
                System.loadLibrary("org_gnu_freeway_server_CPluginLoader");
@@ -55,6 +57,7 @@
        private static native void cUnloadDynamicLibrary(long libhandle);
 
        public CPluginLoader() {
+               super(true);
        }
        
        /**
@@ -67,10 +70,13 @@
         * @param serviceName
         * @return null on error
         */
-       public Object createService(String serviceName) {
+       public NativeService createService(String serviceName) {
+               if(!serviceName.endsWith("Service"))
+                       serviceName = serviceName.substring(0, 1).toUpperCase() 
+ serviceName.substring(1) + "Service";
                try {
-                       Class api = 
Class.forName("org.gnu.freeway.services.impl." + serviceName);
-                       return api.getConstructor(new Class[] { 
CPluginLoader.class}).newInstance(new Object[] { this });
+                       NativeService ret = (NativeService) 
Class.forName("org.gnu.freeway.services.impl." + 
serviceName).getConstructor(new Class[] { CPluginLoader.class}).newInstance(new 
Object[] { this });
+                       ret.init();
+                       return ret;
                } catch (ClassNotFoundException cnfe) {
                        return null;
                } catch (IllegalAccessException iae) {

Modified: freeway/src/org/gnu/freeway/server/CoreAPI.java
===================================================================
--- freeway/src/org/gnu/freeway/server/CoreAPI.java     2006-06-27 14:21:05 UTC 
(rev 3069)
+++ freeway/src/org/gnu/freeway/server/CoreAPI.java     2006-06-28 03:42:38 UTC 
(rev 3070)
@@ -23,6 +23,7 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import org.gnu.freeway.Server;
+import org.gnu.freeway.util.NativeService;
 import org.gnu.freeway.util.net.CSMessage;
 import org.gnu.freeway.util.net.CSNativeMessage;
 import org.gnu.freeway.util.net.CSSession;
@@ -124,15 +125,16 @@
        }
        
        public CPluginLoader.Handle requestService(CString iname) {
-               CPluginLoader loader = new CPluginLoader();
-               String rpos = iname.getValue();
-               String pos = getConfigurationString("MODULES", rpos);
-               if(pos == null)
-                       pos = rpos;
+               //CPluginLoader loader = new CPluginLoader();
+               //String rpos = iname.getValue();
+               //String pos = getConfigurationString("MODULES", rpos);
+               //if(pos == null)
+               //      pos = rpos;
                
-               String name = "module_" + pos;
+               //String name = "module_" + pos;
                
-               ServiceDesc nxt = null;
+               //handling modules in C space because we do all loading there 
anyway
+               /*ServiceDesc nxt = null;
                for(Iterator i = shutdownList.iterator(); i.hasNext(); nxt = 
(ServiceDesc) i.next()) {
                        if(name.equals(nxt.getDsoName())) {
                                if(nxt.getServiceCount() > 0) {
@@ -145,34 +147,38 @@
                                                return null;
                                        }
                                        nxt.setServicePtr(mptr); 
//mptr(&applicationCore)*/
-                                       
nxt.setServicePtr(loader.loadService(name));
+                                       
/*nxt.setServicePtr(loader.loadService(name));
                                        if(nxt.getServicePtr() != null)
                                                nxt.incrementServiceCount();
                                        return nxt.getServicePtr();
                                }
                        }
-               }
+               }*/
                
-               CPluginLoader.Handle library = 
CPluginLoader.loadDynamicLibrary(DSO_PREFIX, name);
+               //CPluginLoader.Handle library = 
CPluginLoader.loadDynamicLibrary(DSO_PREFIX, name);
                
-               if(library == null)
-                       return null;
+               //if(library == null)
+               //      return null;
                
                /*CPluginLoader.Handle mptr = 
CPluginLoader.bindDynamicMethod(library, "provide_", name);
                if(mptr == null) {
                        CPluginLoader.unloadDynamicLibrary(library);
                        return null;
                }*/
-               nxt = new ServiceDesc(name, library, NO.getValue(), 1, null);
-               shutdownList.add(nxt);
+               //nxt = new ServiceDesc(name, library, NO.getValue(), 1, null);
+               //shutdownList.add(nxt);
                //CPluginLoader.Handle api = mptr; //mptr(&applicationCore)
-               CPluginLoader.Handle api = loader.loadService(name);
-               if(api != null) {
+               //CPluginLoader.Handle api = loader.loadService(name);
+               /*if(api != null) {
                        nxt.setServicePtr(api);
                } else {
                        nxt.setServiceCount(0);
-               }
-               return api;
+               }*/
+               //return api;
+               NativeService ret = new 
CPluginLoader().createService(iname.getValue());
+               if(ret == null)
+                       return new CPluginLoader.Handle(0);
+               return ret.handle;
        }
        
        public CInt releaseService(CPluginLoader.Handle service) {

Modified: freeway/src/org/gnu/freeway/services/impl/StatsService.java
===================================================================
--- freeway/src/org/gnu/freeway/services/impl/StatsService.java 2006-06-27 
14:21:05 UTC (rev 3069)
+++ freeway/src/org/gnu/freeway/services/impl/StatsService.java 2006-06-28 
03:42:38 UTC (rev 3070)
@@ -3,10 +3,12 @@
 
 import org.gnu.freeway.util.Service;
 import org.gnu.freeway.util.NativeService;
+import org.gnu.freeway.util.ServiceException;
 import org.gnu.freeway.cwrappers.CInt;
 import org.gnu.freeway.cwrappers.ConstCLong;
 import org.gnu.freeway.cwrappers.CLong;
 import org.gnu.freeway.cwrappers.ConstCInt;
+import org.gnu.freeway.cwrappers.CString;
 import org.gnu.freeway.cwrappers.ConstCString;
 import org.gnu.freeway.server.CPluginLoader;
 
@@ -28,7 +30,24 @@
                loader.callC(handle, 3, 42, new Object[] {arg0, arg1});
        }
 
-       public StatsService() {
-               super();
+       public void init() throws ServiceException {
+               super.init();
+               System.err.println("Loaded stats service.");
+               CInt c = create(new CString("test"));
+               System.err.println("created stat \"test\":" + c.getValue());
+               set(c, new CLong(12345));
+               c = create(new CString("test2"));
+               System.err.println("created stat \"test2\":" + c.getValue());
+               set(c, new CLong(54321));
+               c = create(new CString("-1"));
+               System.err.println("created stat \"-1\":" + c.getValue());
+               set(c, new CLong(-1));
+               c = create(new CString("-2"));
+               System.err.println("created stat \"-2\":" + c.getValue());
+               set(c, new CLong(-2));
        }
+       
+       public StatsService(CPluginLoader loader) {
+               super(loader);
+       }
 }

Modified: freeway/src/org/gnu/freeway/util/NativeService.java
===================================================================
--- freeway/src/org/gnu/freeway/util/NativeService.java 2006-06-27 14:21:05 UTC 
(rev 3069)
+++ freeway/src/org/gnu/freeway/util/NativeService.java 2006-06-28 03:42:38 UTC 
(rev 3070)
@@ -29,12 +29,12 @@
 public abstract class NativeService extends AbstractService implements Service 
{
 
        protected CPluginLoader loader;
-       protected CPluginLoader.Handle handle;
+       public CPluginLoader.Handle handle;
        
-       protected NativeService() {
+       protected NativeService(CPluginLoader loader) {
                super();
                setDebug(true);
-               loader = new CPluginLoader();
+               this.loader = loader;
        }
        
        protected void finalize() throws Throwable {





reply via email to

[Prev in Thread] Current Thread [Next in Thread]