[jboss-svn-commits] JBL Code SVN: r26440 - in labs/jbossrules/trunk: drools-core/src/main/java/org/drools/common and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri May 8 21:15:34 EDT 2009


Author: tirelli
Date: 2009-05-08 21:15:34 -0400 (Fri, 08 May 2009)
New Revision: 26440

Modified:
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooStatefulSession.java
Log:
JBRULES-2086: fixing deadlock problem

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java	2009-05-08 18:17:26 UTC (rev 26439)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java	2009-05-09 01:15:34 UTC (rev 26440)
@@ -5325,6 +5325,8 @@
         // Make sure that this rule is fired as the Package is updated, it also tests that InitialFactImpl is still in the network
         // even though the first rule didn't use it.
         ruleBase.addPackage( pkg );
+        
+        session.fireAllRules();
 
         assertEquals( "x",
                       list.get( 1 ) );

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java	2009-05-08 18:17:26 UTC (rev 26439)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java	2009-05-09 01:15:34 UTC (rev 26440)
@@ -33,6 +33,7 @@
 import java.util.Set;
 import java.util.Map.Entry;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import org.drools.PackageIntegrationException;
 import org.drools.RuleBase;
@@ -46,7 +47,6 @@
 import org.drools.event.RuleBaseEventSupport;
 import org.drools.impl.EnvironmentFactory;
 import org.drools.process.core.Process;
-import org.drools.reteoo.ReteooBuilder;
 import org.drools.rule.CompositeClassLoader;
 import org.drools.rule.DialectRuntimeRegistry;
 import org.drools.rule.Function;
@@ -65,59 +65,59 @@
  * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
  * @version $Id: RuleBaseImpl.java,v 1.5 2005/08/14 22:44:12 mproctor Exp $
  */
-abstract public class AbstractRuleBase implements InternalRuleBase, Externalizable {
+abstract public class AbstractRuleBase
+    implements
+    InternalRuleBase,
+    Externalizable {
     // ------------------------------------------------------------
     // Instance members
     // ------------------------------------------------------------
-    private String id;
+    private String                                     id;
 
-    private int workingMemoryCounter;
+    private int                                        workingMemoryCounter;
 
-    private RuleBaseConfiguration config;
+    private RuleBaseConfiguration                      config;
 
-    protected Map<String, Package> pkgs;
+    protected Map<String, Package>                     pkgs;
 
-    private Map processes;
+    private Map                                        processes;
 
-    private Map agendaGroupRuleTotals;
+    private Map                                        agendaGroupRuleTotals;
 
-    private transient CompositeClassLoader rootClassLoader;
+    private transient CompositeClassLoader             rootClassLoader;
 
     /**
      * The fact handle factory.
      */
-    private FactHandleFactory factHandleFactory;
+    private FactHandleFactory                          factHandleFactory;
 
-    private transient Map<String, Class<?>> globals;
+    private transient Map<String, Class< ? >>          globals;
 
-    private ReloadPackageCompilationData reloadPackageCompilationData = null;
+    private ReloadPackageCompilationData               reloadPackageCompilationData = null;
 
-    private RuleBaseEventSupport eventSupport = new RuleBaseEventSupport(this);
+    private RuleBaseEventSupport                       eventSupport                 = new RuleBaseEventSupport( this );
 
-    private transient ObjectHashSet statefulSessions;
+    private transient ObjectHashSet                    statefulSessions;
 
-    // wms used for lock list during dynamic updates
-    private InternalWorkingMemory[] wms;
-
     // indexed used to track invariant lock
-    private int lastAquiredLock;
+    private int                                        lastAquiredLock;
 
     // lock for entire rulebase, used for dynamic updates
-    private final ReentrantLock lock = new ReentrantLock();
+    private final ReentrantReadWriteLock               lock                         = new ReentrantReadWriteLock();
 
     /**
      * This lock is used when adding to, or reading the <field>statefulSessions</field>
      */
-    private final ReentrantLock statefuleSessionLock = new ReentrantLock();
+    private final ReentrantLock                        statefuleSessionLock         = new ReentrantLock();
 
-    private int additionsSinceLock;
-    private int removalsSinceLock;
+    private int                                        additionsSinceLock;
+    private int                                        removalsSinceLock;
 
-    private transient Map<Class<?>, TypeDeclaration> classTypeDeclaration;
+    private transient Map<Class< ? >, TypeDeclaration> classTypeDeclaration;
 
-    private List<RuleBasePartitionId> partitionIDs;
+    private List<RuleBasePartitionId>                  partitionIDs;
 
-    private ClassFieldAccessorCache classFieldAccessorCache;
+    private ClassFieldAccessorCache                    classFieldAccessorCache;
 
     /**
      * Default constructor - for Externalizable. This should never be used by a user, as it
@@ -139,7 +139,7 @@
     public AbstractRuleBase(final String id,
                             final RuleBaseConfiguration config,
                             final FactHandleFactory factHandleFactory) {
-        if (id != null) {
+        if ( id != null ) {
             this.id = id;
         } else {
             this.id = "default";
@@ -148,20 +148,20 @@
         this.config.makeImmutable();
         this.factHandleFactory = factHandleFactory;
 
-        if (this.config.isSequential()) {
+        if ( this.config.isSequential() ) {
             this.agendaGroupRuleTotals = new HashMap();
         }
 
-        this.rootClassLoader = new CompositeClassLoader(this.config.getClassLoader());
+        this.rootClassLoader = new CompositeClassLoader( this.config.getClassLoader() );
         this.pkgs = new HashMap<String, Package>();
         this.processes = new HashMap();
-        this.globals = new HashMap<String, Class<?>>();
+        this.globals = new HashMap<String, Class< ? >>();
         this.statefulSessions = new ObjectHashSet();
 
-        this.classTypeDeclaration = new HashMap<Class<?>, TypeDeclaration>();
+        this.classTypeDeclaration = new HashMap<Class< ? >, TypeDeclaration>();
         this.partitionIDs = new ArrayList<RuleBasePartitionId>();
 
-        this.classFieldAccessorCache = new ClassFieldAccessorCache(this.rootClassLoader);
+        this.classFieldAccessorCache = new ClassFieldAccessorCache( this.rootClassLoader );
     }
 
     // ------------------------------------------------------------
@@ -177,39 +177,40 @@
         boolean isDrools = out instanceof DroolsObjectOutputStream;
         ByteArrayOutputStream bytes;
 
-        if (isDrools) {
+        if ( isDrools ) {
             droolsStream = out;
             bytes = null;
         } else {
             bytes = new ByteArrayOutputStream();
-            droolsStream = new DroolsObjectOutputStream(bytes);
+            droolsStream = new DroolsObjectOutputStream( bytes );
         }
 
-        droolsStream.writeObject(this.config);
-        droolsStream.writeObject(this.pkgs);
+        droolsStream.writeObject( this.config );
+        droolsStream.writeObject( this.pkgs );
 
         // Rules must be restored by an ObjectInputStream that can resolve using a given ClassLoader to handle seaprately by storing as
         // a byte[]
-        droolsStream.writeObject(this.id);
-        droolsStream.writeInt(this.workingMemoryCounter);
-        droolsStream.writeObject(this.processes);
-        droolsStream.writeObject(this.agendaGroupRuleTotals);
-        droolsStream.writeUTF(this.factHandleFactory.getClass().getName());
-        droolsStream.writeObject(buildGlobalMapForSerialization());
-        droolsStream.writeObject(this.partitionIDs);
+        droolsStream.writeObject( this.id );
+        droolsStream.writeInt( this.workingMemoryCounter );
+        droolsStream.writeObject( this.processes );
+        droolsStream.writeObject( this.agendaGroupRuleTotals );
+        droolsStream.writeUTF( this.factHandleFactory.getClass().getName() );
+        droolsStream.writeObject( buildGlobalMapForSerialization() );
+        droolsStream.writeObject( this.partitionIDs );
 
-        this.eventSupport.removeEventListener(RuleBaseEventListener.class);
-        droolsStream.writeObject(this.eventSupport);
-        if (!isDrools) {
+        this.eventSupport.removeEventListener( RuleBaseEventListener.class );
+        droolsStream.writeObject( this.eventSupport );
+        if ( !isDrools ) {
             bytes.close();
-            out.writeObject(bytes.toByteArray());
+            out.writeObject( bytes.toByteArray() );
         }
     }
 
     private Map<String, String> buildGlobalMapForSerialization() {
         Map<String, String> gl = new HashMap<String, String>();
-        for (Map.Entry<String, Class<?>> entry : this.globals.entrySet()) {
-            gl.put(entry.getKey(), entry.getValue().getName());
+        for ( Map.Entry<String, Class< ? >> entry : this.globals.entrySet() ) {
+            gl.put( entry.getKey(),
+                    entry.getValue().getName() );
         }
         return gl;
     }
@@ -220,32 +221,31 @@
      * A custom ObjectInputStream, able to resolve classes against the bytecode in the PackageCompilationData, is used to restore the Rules.
      */
     public void readExternal(final ObjectInput in) throws IOException,
-            ClassNotFoundException {
+                                                  ClassNotFoundException {
         // PackageCompilationData must be restored before Rules as it has the ClassLoader needed to resolve the generated code references in Rules
         DroolsObjectInput droolsStream;
         boolean isDrools = in instanceof DroolsObjectInput;
 
-        if (isDrools) {
+        if ( isDrools ) {
             droolsStream = (DroolsObjectInput) in;
         } else {
-            droolsStream = new DroolsObjectInputStream((ObjectInputStream) in);
+            droolsStream = new DroolsObjectInputStream( (ObjectInputStream) in );
 
         }
 
-        this.rootClassLoader = new CompositeClassLoader(droolsStream.getParentClassLoader());
-        droolsStream.setClassLoader(this.rootClassLoader);
-        droolsStream.setRuleBase(this);
+        this.rootClassLoader = new CompositeClassLoader( droolsStream.getParentClassLoader() );
+        droolsStream.setClassLoader( this.rootClassLoader );
+        droolsStream.setRuleBase( this );
 
-        this.classFieldAccessorCache = new ClassFieldAccessorCache(this.rootClassLoader);
+        this.classFieldAccessorCache = new ClassFieldAccessorCache( this.rootClassLoader );
 
         this.config = (RuleBaseConfiguration) droolsStream.readObject();
-        this.config.setClassLoader(droolsStream.getParentClassLoader());
+        this.config.setClassLoader( droolsStream.getParentClassLoader() );
 
         this.pkgs = (Map<String, Package>) droolsStream.readObject();
 
-
-        for (final Object object : this.pkgs.values()) {
-            ((Package) object).getDialectRuntimeRegistry().onAdd(this.rootClassLoader);
+        for ( final Object object : this.pkgs.values() ) {
+            ((Package) object).getDialectRuntimeRegistry().onAdd( this.rootClassLoader );
         }
 
         // PackageCompilationData must be restored before Rules as it has the ClassLoader needed to resolve the generated code references in Rules
@@ -256,19 +256,19 @@
         this.agendaGroupRuleTotals = (Map) droolsStream.readObject();
         Class cls = null;
         try {
-            cls = droolsStream.getParentClassLoader().loadClass(droolsStream.readUTF());
+            cls = droolsStream.getParentClassLoader().loadClass( droolsStream.readUTF() );
             this.factHandleFactory = (FactHandleFactory) cls.newInstance();
-        } catch (InstantiationException e) {
-            DroolsObjectInputStream.newInvalidClassException(cls,
-                    e);
-        } catch (IllegalAccessException e) {
-            DroolsObjectInputStream.newInvalidClassException(cls,
-                    e);
+        } catch ( InstantiationException e ) {
+            DroolsObjectInputStream.newInvalidClassException( cls,
+                                                              e );
+        } catch ( IllegalAccessException e ) {
+            DroolsObjectInputStream.newInvalidClassException( cls,
+                                                              e );
         }
 
-        for (final Object object : this.pkgs.values()) {
+        for ( final Object object : this.pkgs.values() ) {
             ((Package) object).getDialectRuntimeRegistry().onBeforeExecute();
-            ((Package) object).getClassFieldAccessorStore().setClassFieldAccessorCache(this.classFieldAccessorCache);
+            ((Package) object).getClassFieldAccessorStore().setClassFieldAccessorCache( this.classFieldAccessorCache );
             ((Package) object).getClassFieldAccessorStore().wire();
         }
 
@@ -276,15 +276,15 @@
 
         // read globals
         Map<String, String> globs = (Map<String, String>) droolsStream.readObject();
-        populateGlobalsMap(globs);
+        populateGlobalsMap( globs );
 
         this.partitionIDs = (List<RuleBasePartitionId>) droolsStream.readObject();
 
         this.eventSupport = (RuleBaseEventSupport) droolsStream.readObject();
-        this.eventSupport.setRuleBase(this);
+        this.eventSupport.setRuleBase( this );
         this.statefulSessions = new ObjectHashSet();
 
-        if (!isDrools) {
+        if ( !isDrools ) {
             droolsStream.close();
         }
     }
@@ -296,9 +296,10 @@
      * @throws ClassNotFoundException
      */
     private void populateGlobalsMap(Map<String, String> globs) throws ClassNotFoundException {
-        this.globals = new HashMap<String, Class<?>>();
-        for (Map.Entry<String, String> entry : globs.entrySet()) {
-            this.globals.put(entry.getKey(), this.rootClassLoader.loadClass(entry.getValue()));
+        this.globals = new HashMap<String, Class< ? >>();
+        for ( Map.Entry<String, String> entry : globs.entrySet() ) {
+            this.globals.put( entry.getKey(),
+                              this.rootClassLoader.loadClass( entry.getValue() ) );
         }
     }
 
@@ -308,12 +309,12 @@
      * @throws ClassNotFoundException
      */
     private void populateTypeDeclarationMaps() throws ClassNotFoundException {
-        this.classTypeDeclaration = new HashMap<Class<?>, TypeDeclaration>();
-        for (Package pkg : this.pkgs.values()) {
-            for (TypeDeclaration type : pkg.getTypeDeclarations().values()) {
-                type.setTypeClass(this.rootClassLoader.loadClass(type.getTypeClassName()));
-                this.classTypeDeclaration.put(type.getTypeClass(),
-                        type);
+        this.classTypeDeclaration = new HashMap<Class< ? >, TypeDeclaration>();
+        for ( Package pkg : this.pkgs.values() ) {
+            for ( TypeDeclaration type : pkg.getTypeDeclarations().values() ) {
+                type.setTypeClass( this.rootClassLoader.loadClass( type.getTypeClassName() ) );
+                this.classTypeDeclaration.put( type.getTypeClass(),
+                                               type );
             }
         }
     }
@@ -333,23 +334,23 @@
      * @see RuleBase
      */
     public StatefulSession newStatefulSession() {
-        return newStatefulSession(new SessionConfiguration(), EnvironmentFactory.newEnvironment());
+        return newStatefulSession( new SessionConfiguration(),
+                                   EnvironmentFactory.newEnvironment() );
     }
 
     public void disposeStatefulSession(final StatefulSession statefulSession) {
         try {
             statefuleSessionLock.lock();
 
-            this.statefulSessions.remove(statefulSession);
-            for (Object listener : statefulSession.getRuleBaseUpdateListeners()) {
-                this.removeEventListener((RuleBaseEventListener) listener);
+            this.statefulSessions.remove( statefulSession );
+            for ( Object listener : statefulSession.getRuleBaseUpdateListeners() ) {
+                this.removeEventListener( (RuleBaseEventListener) listener );
             }
         } finally {
             statefuleSessionLock.unlock();
         }
     }
 
-
     /**
      * @see RuleBase
      */
@@ -363,16 +364,16 @@
 
     public FactHandleFactory newFactHandleFactory(int id,
                                                   long counter) {
-        return this.factHandleFactory.newInstance(id,
-                counter);
+        return this.factHandleFactory.newInstance( id,
+                                                   counter );
     }
 
     public Process[] getProcesses() {
-        return (Process[]) this.processes.values().toArray(new Process[this.processes.size()]);
+        return (Process[]) this.processes.values().toArray( new Process[this.processes.size()] );
     }
 
     public Package[] getPackages() {
-        return this.pkgs.values().toArray(new Package[this.pkgs.size()]);
+        return this.pkgs.values().toArray( new Package[this.pkgs.size()] );
     }
 
     public Map<String, Package> getPackagesMap() {
@@ -398,41 +399,24 @@
     public void lock() {
         this.additionsSinceLock = 0;
         this.removalsSinceLock = 0;
-
         this.eventSupport.fireBeforeRuleBaseLocked();
-        this.lock.lock();
-
-        // INVARIANT: lastAquiredLock always contains the index of the last aquired lock +1
-        // in the working memory array
-        this.lastAquiredLock = 0;
-
-        this.wms = getWorkingMemories();
-
-        // Iterate each workingMemory and lock it
-        // This is so we don't update the Rete network during propagation
-        for (this.lastAquiredLock = 0; this.lastAquiredLock < this.wms.length; this.lastAquiredLock++) {            
-            this.wms[this.lastAquiredLock].getLock().lock();
-        }
-
+        this.lock.writeLock().lock();
         this.eventSupport.fireAfterRuleBaseLocked();
     }
 
     public void unlock() {
         this.eventSupport.fireBeforeRuleBaseUnlocked();
-
-        // Iterate each workingMemory and attempt to fire any rules, that were activated as a result
-
-        // as per the INVARIANT defined above, we need to iterate from lastAquiredLock-1 to 0.
-        for (this.lastAquiredLock--; this.lastAquiredLock > -1; this.lastAquiredLock--) {
-            this.wms[this.lastAquiredLock].getLock().unlock();
-        }
-
-        this.lock.unlock();
-
+        this.lock.writeLock().unlock();
         this.eventSupport.fireAfterRuleBaseUnlocked();
-
-        this.wms = null;
     }
+    
+    public void readLock() {
+        this.lock.readLock().lock();
+    }
+    
+    public void readUnlock() {
+        this.lock.readLock().unlock();
+    }
 
     /**
      * Add a <code>Package</code> to the network. Iterates through the
@@ -443,105 +427,95 @@
      * @param newPkg The package to add.
      */
     public void addPackages(final Collection<Package> newPkgs) {
-        synchronized (this.pkgs) {
-            boolean doUnlock = false;
-            // only acquire the lock if it hasn't been done explicitely
-            if (!this.lock.isHeldByCurrentThread() && (this.wms == null || this.wms.length == 0)) {
-                lock();
-                doUnlock = true;
-            }
-            try {
-                // we need to merge all byte[] first, so that the root classloader can resolve classes
-                for (Package newPkg : newPkgs) {
-                    newPkg.checkValidity();
-                    this.additionsSinceLock++;
-                    this.eventSupport.fireBeforePackageAdded(newPkg);
+        try {
+            lock();
+            // we need to merge all byte[] first, so that the root classloader can resolve classes
+            for ( Package newPkg : newPkgs ) {
+                newPkg.checkValidity();
+                this.additionsSinceLock++;
+                this.eventSupport.fireBeforePackageAdded( newPkg );
 
-                    Package pkg = this.pkgs.get(newPkg.getName());
-                    if (pkg == null) {
-                        pkg = new Package(newPkg.getName());
+                Package pkg = this.pkgs.get( newPkg.getName() );
+                if ( pkg == null ) {
+                    pkg = new Package( newPkg.getName() );
 
-                        // @TODO we really should have a single root cache
-                        pkg.setClassFieldAccessorCache(this.classFieldAccessorCache);
-                        pkgs.put(pkg.getName(),
-                                pkg);
-                    }
-
-                    // first merge anything related to classloader re-wiring
-                    pkg.getDialectRuntimeRegistry().merge(newPkg.getDialectRuntimeRegistry(), this.rootClassLoader);
+                    // @TODO we really should have a single root cache
+                    pkg.setClassFieldAccessorCache( this.classFieldAccessorCache );
+                    pkgs.put( pkg.getName(),
+                              pkg );
                 }
 
-                // now iterate again, this time onBeforeExecute will handle any wiring or cloader re-creating that needs to be done as part of the merge
-                for (Package newPkg : newPkgs) {
-                    Package pkg = this.pkgs.get(newPkg.getName());
-                    
-                    // this needs to go here, as functions will set a java dialect to dirty
-                    if (newPkg.getFunctions() != null) {
-                        for (Map.Entry<String, Function> entry : newPkg.getFunctions().entrySet()) {
-                            pkg.addFunction(entry.getValue());
-                        }
+                // first merge anything related to classloader re-wiring
+                pkg.getDialectRuntimeRegistry().merge( newPkg.getDialectRuntimeRegistry(),
+                                                       this.rootClassLoader );
+            }
+
+            // now iterate again, this time onBeforeExecute will handle any wiring or cloader re-creating that needs to be done as part of the merge
+            for ( Package newPkg : newPkgs ) {
+                Package pkg = this.pkgs.get( newPkg.getName() );
+
+                // this needs to go here, as functions will set a java dialect to dirty
+                if ( newPkg.getFunctions() != null ) {
+                    for ( Map.Entry<String, Function> entry : newPkg.getFunctions().entrySet() ) {
+                        pkg.addFunction( entry.getValue() );
                     }
-                    
-                    pkg.getDialectRuntimeRegistry().onBeforeExecute();
-                    // with the classloader recreated for all byte[] classes, we should now merge and wire any new accessors
-                    pkg.getClassFieldAccessorStore().merge(newPkg.getClassFieldAccessorStore());
                 }
 
-                for (Package newPkg : newPkgs) {
-                    Package pkg = this.pkgs.get(newPkg.getName());
+                pkg.getDialectRuntimeRegistry().onBeforeExecute();
+                // with the classloader recreated for all byte[] classes, we should now merge and wire any new accessors
+                pkg.getClassFieldAccessorStore().merge( newPkg.getClassFieldAccessorStore() );
+            }
 
-                    // we have to do this before the merging, as it does some classloader resolving
-                    TypeDeclaration lastType = null;
-                    try {
-                        // Add the type declarations to the RuleBase
-                        if (newPkg.getTypeDeclarations() != null) {
-                            // add type declarations
-                            for (TypeDeclaration type : newPkg.getTypeDeclarations().values()) {
-                                lastType = type;
-                                type.setTypeClass(this.rootClassLoader.loadClass(type.getTypeClassName()));
-                                // @TODO should we allow overrides? only if the class is not in use.
-                                if (!this.classTypeDeclaration.containsKey(type.getTypeClass())) {
-                                    // add to rulebase list of type declarations                        
-                                    this.classTypeDeclaration.put(type.getTypeClass(),
-                                            type);
-                                }
+            for ( Package newPkg : newPkgs ) {
+                Package pkg = this.pkgs.get( newPkg.getName() );
+
+                // we have to do this before the merging, as it does some classloader resolving
+                TypeDeclaration lastType = null;
+                try {
+                    // Add the type declarations to the RuleBase
+                    if ( newPkg.getTypeDeclarations() != null ) {
+                        // add type declarations
+                        for ( TypeDeclaration type : newPkg.getTypeDeclarations().values() ) {
+                            lastType = type;
+                            type.setTypeClass( this.rootClassLoader.loadClass( type.getTypeClassName() ) );
+                            // @TODO should we allow overrides? only if the class is not in use.
+                            if ( !this.classTypeDeclaration.containsKey( type.getTypeClass() ) ) {
+                                // add to rulebase list of type declarations                        
+                                this.classTypeDeclaration.put( type.getTypeClass(),
+                                                               type );
                             }
                         }
-                    } catch (ClassNotFoundException e) {
-                        throw new RuntimeDroolsException("unable to resolve Type Declaration class '" + lastType.getTypeName() + "'");
                     }
+                } catch ( ClassNotFoundException e ) {
+                    throw new RuntimeDroolsException( "unable to resolve Type Declaration class '" + lastType.getTypeName() + "'" );
+                }
 
-                    // now merge the new package into the existing one
-                    mergePackage(pkg,
-                            newPkg);
+                // now merge the new package into the existing one
+                mergePackage( pkg,
+                              newPkg );
 
-                    // add the rules to the RuleBase
-                    final Rule[] rules = newPkg.getRules();
-                    for (int i = 0; i < rules.length; ++i) {
-                        addRule(newPkg,
-                                rules[i]);
-                    }
+                // add the rules to the RuleBase
+                final Rule[] rules = newPkg.getRules();
+                for ( int i = 0; i < rules.length; ++i ) {
+                    addRule( newPkg,
+                             rules[i] );
+                }
 
-                    // add the flows to the RuleBase
-                    if (newPkg.getRuleFlows() != null) {
-                        final Map flows = newPkg.getRuleFlows();
-                        for (final Object object : flows.entrySet()) {
-                            final Entry flow = (Entry) object;
-                            this.processes.put(flow.getKey(),
-                                    flow.getValue());
-                        }
+                // add the flows to the RuleBase
+                if ( newPkg.getRuleFlows() != null ) {
+                    final Map flows = newPkg.getRuleFlows();
+                    for ( final Object object : flows.entrySet() ) {
+                        final Entry flow = (Entry) object;
+                        this.processes.put( flow.getKey(),
+                                            flow.getValue() );
                     }
-
-                    this.eventSupport.fireAfterPackageAdded(newPkg);
                 }
-            } finally {
-                // only unlock if it had been acquired implicitely
-                if (doUnlock) {
-                    unlock();
-                }
+
+                this.eventSupport.fireAfterPackageAdded( newPkg );
             }
+        } finally {
+            unlock();
         }
-
     }
 
     /**
@@ -554,41 +528,41 @@
                               final Package newPkg) {
         // Merge imports
         final Map<String, ImportDeclaration> imports = pkg.getImports();
-        imports.putAll(newPkg.getImports());
+        imports.putAll( newPkg.getImports() );
 
         String lastType = null;
         try {
             // merge globals
-            if (newPkg.getGlobals() != null && newPkg.getGlobals() != Collections.EMPTY_MAP) {
+            if ( newPkg.getGlobals() != null && newPkg.getGlobals() != Collections.EMPTY_MAP ) {
                 Map<String, String> globals = pkg.getGlobals();
                 // Add globals
-                for (final Map.Entry<String, String> entry : newPkg.getGlobals().entrySet()) {
+                for ( final Map.Entry<String, String> entry : newPkg.getGlobals().entrySet() ) {
                     final String identifier = entry.getKey();
                     final String type = entry.getValue();
                     lastType = type;
-                    if (globals.containsKey(identifier) && !globals.get(identifier).equals(type)) {
-                        throw new PackageIntegrationException(pkg);
+                    if ( globals.containsKey( identifier ) && !globals.get( identifier ).equals( type ) ) {
+                        throw new PackageIntegrationException( pkg );
                     } else {
-                        pkg.addGlobal(identifier,
-                                this.rootClassLoader.loadClass(type));
+                        pkg.addGlobal( identifier,
+                                       this.rootClassLoader.loadClass( type ) );
                         // this isn't a package merge, it's adding to the rulebase, but I've put it here for convienience
-                        this.globals.put(identifier,
-                                this.rootClassLoader.loadClass(type));
+                        this.globals.put( identifier,
+                                          this.rootClassLoader.loadClass( type ) );
                     }
                 }
             }
-        } catch (ClassNotFoundException e) {
-            throw new RuntimeDroolsException("Unable to resolve class '" + lastType + "'");
+        } catch ( ClassNotFoundException e ) {
+            throw new RuntimeDroolsException( "Unable to resolve class '" + lastType + "'" );
         }
 
         // merge the type declarations
-        if (newPkg.getTypeDeclarations() != null) {
+        if ( newPkg.getTypeDeclarations() != null ) {
             // add type declarations
-            for (TypeDeclaration type : newPkg.getTypeDeclarations().values()) {
+            for ( TypeDeclaration type : newPkg.getTypeDeclarations().values() ) {
                 // @TODO should we allow overrides? only if the class is not in use.
-                if (!pkg.getTypeDeclarations().containsKey(type.getTypeName())) {
+                if ( !pkg.getTypeDeclarations().containsKey( type.getTypeName() ) ) {
                     // add to package list of type declarations
-                    pkg.addTypeDeclaration(type);
+                    pkg.addTypeDeclaration( type );
                 }
             }
         }
@@ -596,37 +570,37 @@
         //Merge rules into the RuleBase package
         //as this is needed for individual rule removal later on
         final Rule[] newRules = newPkg.getRules();
-        for (int i = 0; i < newRules.length; i++) {
+        for ( int i = 0; i < newRules.length; i++ ) {
             final Rule newRule = newRules[i];
 
             // remove the rule if it already exists
-            if (pkg.getRule(newRule.getName()) != null) {
-                removeRule(pkg,
-                        pkg.getRule(newRule.getName()));
+            if ( pkg.getRule( newRule.getName() ) != null ) {
+                removeRule( pkg,
+                            pkg.getRule( newRule.getName() ) );
             }
 
-            pkg.addRule(newRule);
+            pkg.addRule( newRule );
         }
 
         //Merge The Rule Flows
-        if (newPkg.getRuleFlows() != null) {
+        if ( newPkg.getRuleFlows() != null ) {
             final Map flows = newPkg.getRuleFlows();
-            for (final Iterator iter = flows.values().iterator(); iter.hasNext();) {
+            for ( final Iterator iter = flows.values().iterator(); iter.hasNext(); ) {
                 final Process flow = (Process) iter.next();
-                pkg.addProcess(flow);
+                pkg.addProcess( flow );
             }
         }
 
-//        // this handles re-wiring any dirty Packages, it's done lazily to allow incremental 
-//        // additions without incurring the repeated cost.
-//        if ( this.reloadPackageCompilationData == null ) {
-//            this.reloadPackageCompilationData = new ReloadPackageCompilationData();
-//        }
-//        this.reloadPackageCompilationData.addDialectDatas( pkg.getDialectRuntimeRegistry() );
+        //        // this handles re-wiring any dirty Packages, it's done lazily to allow incremental 
+        //        // additions without incurring the repeated cost.
+        //        if ( this.reloadPackageCompilationData == null ) {
+        //            this.reloadPackageCompilationData = new ReloadPackageCompilationData();
+        //        }
+        //        this.reloadPackageCompilationData.addDialectDatas( pkg.getDialectRuntimeRegistry() );
     }
 
-    public TypeDeclaration getTypeDeclaration(Class<?> clazz) {
-        return this.classTypeDeclaration.get(clazz);
+    public TypeDeclaration getTypeDeclaration(Class< ? > clazz) {
+        return this.classTypeDeclaration.get( clazz );
     }
 
     public Collection<TypeDeclaration> getTypeDeclarations() {
@@ -635,129 +609,111 @@
 
     public void addRule(final Package pkg,
                         final Rule rule) throws InvalidPatternException {
-        synchronized (this.pkgs) {
-            this.eventSupport.fireBeforeRuleAdded(pkg,
-                    rule);
+        synchronized ( this.pkgs ) {
+            this.eventSupport.fireBeforeRuleAdded( pkg,
+                                                   rule );
             //        if ( !rule.isValid() ) {
             //            throw new IllegalArgumentException( "The rule called " + rule.getName() + " is not valid. Check for compile errors reported." );
             //        }
-            addRule(rule);
-            this.eventSupport.fireAfterRuleAdded(pkg,
-                    rule);
+            addRule( rule );
+            this.eventSupport.fireAfterRuleAdded( pkg,
+                                                  rule );
         }
     }
 
     protected abstract void addRule(final Rule rule) throws InvalidPatternException;
 
     public void removePackage(final String packageName) {
-        synchronized (this.pkgs) {
-            final Package pkg = this.pkgs.get(packageName);
-            if (pkg == null) {
-                throw new IllegalArgumentException("Package name '" + packageName + "' does not exist for this Rule Base.");
+        try {
+            lock();
+            final Package pkg = this.pkgs.get( packageName );
+            if ( pkg == null ) {
+                throw new IllegalArgumentException( "Package name '" + packageName + "' does not exist for this Rule Base." );
             }
+            this.removalsSinceLock++;
 
-            // only acquire the lock if it hasn't been done explicitely
-            boolean doUnlock = false;
-            if (!this.lock.isHeldByCurrentThread() && (this.wms == null || this.wms.length == 0)) {
-                lock();
-                doUnlock = true;
-            }
-            try {
-                this.removalsSinceLock++;
+            this.eventSupport.fireBeforePackageRemoved( pkg );
 
-                this.eventSupport.fireBeforePackageRemoved(pkg);
+            final Rule[] rules = pkg.getRules();
 
-                final Rule[] rules = pkg.getRules();
+            for ( int i = 0; i < rules.length; ++i ) {
+                removeRule( pkg,
+                            rules[i] );
+            }
 
-                for (int i = 0; i < rules.length; ++i) {
-                    removeRule(pkg,
-                            rules[i]);
+            // getting the list of referenced globals
+            final Set referencedGlobals = new HashSet();
+            for ( final Iterator it = this.pkgs.values().iterator(); it.hasNext(); ) {
+                final org.drools.rule.Package pkgref = (org.drools.rule.Package) it.next();
+                if ( pkgref != pkg ) {
+                    referencedGlobals.addAll( pkgref.getGlobals().keySet() );
                 }
-
-                // getting the list of referenced globals
-                final Set referencedGlobals = new HashSet();
-                for (final Iterator it = this.pkgs.values().iterator(); it.hasNext();) {
-                    final org.drools.rule.Package pkgref = (org.drools.rule.Package) it.next();
-                    if (pkgref != pkg) {
-                        referencedGlobals.addAll(pkgref.getGlobals().keySet());
-                    }
+            }
+            // removing globals declared inside the package that are not shared
+            for ( final Iterator it = pkg.getGlobals().keySet().iterator(); it.hasNext(); ) {
+                final String globalName = (String) it.next();
+                if ( !referencedGlobals.contains( globalName ) ) {
+                    this.globals.remove( globalName );
                 }
-                // removing globals declared inside the package that are not shared
-                for (final Iterator it = pkg.getGlobals().keySet().iterator(); it.hasNext();) {
-                    final String globalName = (String) it.next();
-                    if (!referencedGlobals.contains(globalName)) {
-                        this.globals.remove(globalName);
-                    }
-                }
-                //and now the rule flows
-                final Map flows = pkg.getRuleFlows();
-                for (final Iterator iter = flows.keySet().iterator(); iter.hasNext();) {
-                    removeProcess((String) iter.next());
-                }
-                // removing the package itself from the list
-                this.pkgs.remove(pkg.getName());
+            }
+            //and now the rule flows
+            final Map flows = pkg.getRuleFlows();
+            for ( final Iterator iter = flows.keySet().iterator(); iter.hasNext(); ) {
+                removeProcess( (String) iter.next() );
+            }
+            // removing the package itself from the list
+            this.pkgs.remove( pkg.getName() );
 
-                pkg.getDialectRuntimeRegistry().onRemove();
+            pkg.getDialectRuntimeRegistry().onRemove();
 
-                //clear all members of the pkg
-                pkg.clear();
+            //clear all members of the pkg
+            pkg.clear();
 
-                this.eventSupport.fireAfterPackageRemoved(pkg);
-
-                // only unlock if it had been acquired implicitely
-            } finally {
-                if (doUnlock) {
-                    unlock();
-                }
-            }
+            this.eventSupport.fireAfterPackageRemoved( pkg );
+        } finally {
+            unlock();
         }
     }
 
     public void removeRule(final String packageName,
                            final String ruleName) {
-        synchronized (this.pkgs) {
-            final Package pkg = this.pkgs.get(packageName);
-            if (pkg == null) {
-                throw new IllegalArgumentException("Package name '" + packageName + "' does not exist for this Rule Base.");
+        try {
+            lock();
+            final Package pkg = this.pkgs.get( packageName );
+            if ( pkg == null ) {
+                throw new IllegalArgumentException( "Package name '" + packageName + "' does not exist for this Rule Base." );
             }
 
-            final Rule rule = pkg.getRule(ruleName);
-            if (rule == null) {
-                throw new IllegalArgumentException("Rule name '" + ruleName + "' does not exist in the Package '" + packageName + "'.");
+            final Rule rule = pkg.getRule( ruleName );
+            if ( rule == null ) {
+                throw new IllegalArgumentException( "Rule name '" + ruleName + "' does not exist in the Package '" + packageName + "'." );
             }
 
-            // only acquire the lock if it hasn't been done explicitely
-            boolean doUnlock = false;
-            if (!this.lock.isHeldByCurrentThread() && (this.wms == null || this.wms.length == 0)) {
-                lock();
-                doUnlock = true;
-            }
             this.removalsSinceLock++;
 
-            removeRule(pkg,
-                    rule);
-            pkg.removeRule(rule);
-            if (this.reloadPackageCompilationData == null) {
+            removeRule( pkg,
+                        rule );
+            pkg.removeRule( rule );
+            if ( this.reloadPackageCompilationData == null ) {
                 this.reloadPackageCompilationData = new ReloadPackageCompilationData();
             }
-            this.reloadPackageCompilationData.addDialectDatas(pkg.getDialectRuntimeRegistry());
-
-            // only unlock if it had been acquired implicitely
-            if (doUnlock) {
-                unlock();
-            }
+            this.reloadPackageCompilationData.addDialectDatas( pkg.getDialectRuntimeRegistry() );
+        } finally {
+            unlock();
         }
     }
 
     public void removeRule(final Package pkg,
                            final Rule rule) {
-        synchronized (this.pkgs) {
-            this.eventSupport.fireBeforeRuleRemoved(pkg,
-                    rule);
-
-            removeRule(rule);
-            this.eventSupport.fireAfterRuleRemoved(pkg,
-                    rule);
+        try {
+            lock();
+            this.eventSupport.fireBeforeRuleRemoved( pkg,
+                                                     rule );
+            removeRule( rule );
+            this.eventSupport.fireAfterRuleRemoved( pkg,
+                                                    rule );
+        } finally {
+            unlock();
         }
     }
 
@@ -765,49 +721,49 @@
 
     public void removeFunction(final String packageName,
                                final String functionName) {
-        synchronized (this.pkgs) {
-            final Package pkg = this.pkgs.get(packageName);
-            if (pkg == null) {
-                throw new IllegalArgumentException("Package name '" + packageName + "' does not exist for this Rule Base.");
+        synchronized ( this.pkgs ) {
+            final Package pkg = this.pkgs.get( packageName );
+            if ( pkg == null ) {
+                throw new IllegalArgumentException( "Package name '" + packageName + "' does not exist for this Rule Base." );
             }
 
-            this.eventSupport.fireBeforeFunctionRemoved(pkg,
-                    functionName);
+            this.eventSupport.fireBeforeFunctionRemoved( pkg,
+                                                         functionName );
 
-            if (!pkg.getFunctions().containsKey(functionName)) {
-                throw new IllegalArgumentException("function name '" + packageName + "' does not exist in the Package '" + packageName + "'.");
+            if ( !pkg.getFunctions().containsKey( functionName ) ) {
+                throw new IllegalArgumentException( "function name '" + packageName + "' does not exist in the Package '" + packageName + "'." );
             }
 
-            pkg.removeFunction(functionName);
+            pkg.removeFunction( functionName );
 
-            if (this.reloadPackageCompilationData == null) {
+            if ( this.reloadPackageCompilationData == null ) {
                 this.reloadPackageCompilationData = new ReloadPackageCompilationData();
             }
-            this.reloadPackageCompilationData.addDialectDatas(pkg.getDialectRuntimeRegistry());
+            this.reloadPackageCompilationData.addDialectDatas( pkg.getDialectRuntimeRegistry() );
 
-            this.eventSupport.fireAfterFunctionRemoved(pkg,
-                    functionName);
+            this.eventSupport.fireAfterFunctionRemoved( pkg,
+                                                        functionName );
         }
     }
 
     public void addProcess(final Process process) {
-        synchronized (this.pkgs) {
-            this.processes.put(process.getId(),
-                    process);
+        synchronized ( this.pkgs ) {
+            this.processes.put( process.getId(),
+                                process );
         }
 
     }
 
     public void removeProcess(final String id) {
-        synchronized (this.pkgs) {
-            this.processes.remove(id);
+        synchronized ( this.pkgs ) {
+            this.processes.remove( id );
         }
     }
 
     public Process getProcess(final String id) {
         Process process;
-        synchronized (this.pkgs) {
-            process = (Process) this.processes.get(id);
+        synchronized ( this.pkgs ) {
+            process = (Process) this.processes.get( id );
         }
         return process;
     }
@@ -816,7 +772,7 @@
         try {
             statefuleSessionLock.lock();
 
-            this.statefulSessions.add(statefulSession);
+            this.statefulSessions.add( statefulSession );
         } finally {
             statefuleSessionLock.unlock();
         }
@@ -824,7 +780,7 @@
     }
 
     public Package getPackage(final String name) {
-        return this.pkgs.get(name);
+        return this.pkgs.get( name );
     }
 
     public StatefulSession[] getStatefulSessions() {
@@ -833,7 +789,7 @@
             statefuleSessionLock.lock();
             copyOfSessions = new StatefulSession[this.statefulSessions.size()];
 
-            this.statefulSessions.toArray(copyOfSessions);
+            this.statefulSessions.toArray( copyOfSessions );
         } finally {
             statefuleSessionLock.unlock();
         }
@@ -847,7 +803,7 @@
             statefuleSessionLock.lock();
             copyOfMemories = new InternalWorkingMemory[this.statefulSessions.size()];
 
-            this.statefulSessions.toArray(copyOfMemories);
+            this.statefulSessions.toArray( copyOfMemories );
         } finally {
             statefuleSessionLock.unlock();
         }
@@ -864,9 +820,9 @@
     }
 
     public void executeQueuedActions() {
-        synchronized (this.pkgs) {
-            if (this.reloadPackageCompilationData != null) {
-                this.reloadPackageCompilationData.execute(this);
+        synchronized ( this.pkgs ) {
+            if ( this.reloadPackageCompilationData != null ) {
+                this.reloadPackageCompilationData.execute( this );
                 this.reloadPackageCompilationData = null;
             }
         }
@@ -874,9 +830,9 @@
 
     public RuleBasePartitionId createNewPartitionId() {
         RuleBasePartitionId p;
-        synchronized (this.partitionIDs) {
-            p = new RuleBasePartitionId("P-" + this.partitionIDs.size());
-            this.partitionIDs.add(p);
+        synchronized ( this.partitionIDs ) {
+            p = new RuleBasePartitionId( "P-" + this.partitionIDs.size() );
+            this.partitionIDs.add( p );
         }
         return p;
     }
@@ -887,12 +843,12 @@
 
     public void addEventListener(final RuleBaseEventListener listener) {
         // no need for synchonization or locking because eventSupport is thread-safe
-        this.eventSupport.addEventListener(listener);
+        this.eventSupport.addEventListener( listener );
     }
 
     public void removeEventListener(final RuleBaseEventListener listener) {
         // no need for synchonization or locking because eventSupport is thread-safe
-        this.eventSupport.removeEventListener(listener);
+        this.eventSupport.removeEventListener( listener );
     }
 
     public List<RuleBaseEventListener> getRuleBaseEventListeners() {
@@ -901,8 +857,8 @@
     }
 
     public boolean isEvent(Class clazz) {
-        for (Package pkg : this.pkgs.values()) {
-            if (pkg.isEvent(clazz)) {
+        for ( Package pkg : this.pkgs.values() ) {
+            if ( pkg.isEvent( clazz ) ) {
                 return true;
             }
         }
@@ -910,9 +866,9 @@
     }
 
     public FactType getFactType(final String name) {
-        for (Package pkg : this.pkgs.values()) {
-            FactType type = pkg.getFactType(name);
-            if (type != null) {
+        for ( Package pkg : this.pkgs.values() ) {
+            FactType type = pkg.getFactType( name );
+            if ( type != null ) {
                 return type;
             }
         }
@@ -920,37 +876,37 @@
     }
 
     public static class ReloadPackageCompilationData
-            implements
-            RuleBaseAction {
-        private static final long serialVersionUID = 1L;
+        implements
+        RuleBaseAction {
+        private static final long           serialVersionUID = 1L;
         private Set<DialectRuntimeRegistry> set;
 
         public void readExternal(ObjectInput in) throws IOException,
-                ClassNotFoundException {
+                                                ClassNotFoundException {
             set = (Set<DialectRuntimeRegistry>) in.readObject();
         }
 
         public void writeExternal(ObjectOutput out) throws IOException {
-            out.writeObject(set);
+            out.writeObject( set );
         }
 
         public void addDialectDatas(final DialectRuntimeRegistry registry) {
-            if (this.set == null) {
+            if ( this.set == null ) {
                 this.set = new HashSet<DialectRuntimeRegistry>();
             }
-            if (!this.set.contains(registry)) this.set.add(registry);
+            if ( !this.set.contains( registry ) ) this.set.add( registry );
         }
 
         public void execute(final InternalRuleBase ruleBase) {
-            for (final DialectRuntimeRegistry registry : this.set) {
+            for ( final DialectRuntimeRegistry registry : this.set ) {
                 registry.onBeforeExecute();
             }
         }
     }
 
     public static interface RuleBaseAction
-            extends
-            Externalizable {
+        extends
+        Externalizable {
         public void execute(InternalRuleBase ruleBase);
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java	2009-05-08 18:17:26 UTC (rev 26439)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java	2009-05-09 01:15:34 UTC (rev 26440)
@@ -84,9 +84,9 @@
 import org.drools.rule.Rule;
 import org.drools.rule.TimeMachine;
 import org.drools.ruleflow.core.RuleFlowProcess;
-import org.drools.runtime.ExecutionResults;
 import org.drools.runtime.Environment;
 import org.drools.runtime.EnvironmentName;
+import org.drools.runtime.ExecutionResults;
 import org.drools.runtime.ExitPoint;
 import org.drools.runtime.Globals;
 import org.drools.runtime.KnowledgeRuntime;
@@ -164,7 +164,7 @@
     protected Queue<WorkingMemoryAction>                                      actionQueue;
 
     protected volatile boolean                                                evaluatingActionQueue;
-
+    
     protected ReentrantLock                                                   lock;
 
     protected boolean                                                         discardOnLogicalOverride;
@@ -541,6 +541,7 @@
         }
 
         try {
+            this.ruleBase.readLock();
             this.lock.lock();
             // Make sure the global has been declared in the RuleBase
             final Map globalDefintions = this.ruleBase.getGlobals();
@@ -556,6 +557,7 @@
             }
         } finally {
             this.lock.unlock();
+            this.ruleBase.readUnlock();
         }
     }
 
@@ -621,30 +623,6 @@
         this.agenda.halt();
     }
 
-    // /**
-    // * This is a synchronous call that will keep the engine running
-    // * until halt() is called. If no more activations exist, the engine
-    // * will wait until either halt is called or new activations are
-    // * created. In the later case, it will fire them.
-    // */
-    // public void runUntilHalt() {
-    // do {
-    // fireAllRules();
-    // synchronized( this.agenda ) {
-    // if( !halt && this.agenda.agendaSize() == 0 ) {
-    // try {
-    // this.agenda.wait();
-    // } catch (InterruptedException e) {
-    // // set status and continue
-    // Thread.currentThread().interrupted();
-    // break;
-    // }
-    // }
-    // }
-    // } while( !halt );
-    //    	
-    // }
-
     public synchronized int fireAllRules() throws FactException {
         return fireAllRules( null,
                              -1 );
@@ -885,6 +863,7 @@
         }
 
         try {
+            this.ruleBase.readLock();
             this.lock.lock();
             // check if the object already exists in the WM
             handle = (InternalFactHandle) this.objectStore.getHandleForObject( object );
@@ -1027,6 +1006,7 @@
 
         } finally {
             this.lock.unlock();
+            this.ruleBase.readUnlock();
         }
         return handle;
     }
@@ -1144,6 +1124,7 @@
                         final Rule rule,
                         final Activation activation) throws FactException {
         try {
+            this.ruleBase.readLock();
             this.lock.lock();
             this.ruleBase.executeQueuedActions();
 
@@ -1214,6 +1195,7 @@
             executeQueuedActions();
         } finally {
             this.lock.unlock();
+            this.ruleBase.readUnlock();
         }
     }
 
@@ -1227,6 +1209,7 @@
                               final Rule rule,
                               final Activation activation) {
         try {
+            this.ruleBase.readLock();
             this.lock.lock();
             this.ruleBase.executeQueuedActions();
 
@@ -1282,6 +1265,7 @@
             }
         } finally {
             this.lock.unlock();
+            this.ruleBase.readUnlock();
         }
     }
 
@@ -1298,6 +1282,7 @@
                              final Rule rule,
                              final Activation activation) {
         try {
+            this.ruleBase.readLock();
             this.lock.lock();
             this.ruleBase.executeQueuedActions();
 
@@ -1356,6 +1341,7 @@
 
         } finally {
             this.lock.unlock();
+            this.ruleBase.readUnlock();
         }
     }
 
@@ -1385,6 +1371,7 @@
                        final Rule rule,
                        final Activation activation) throws FactException {
         try {
+            this.ruleBase.readLock();
             this.lock.lock();
             this.ruleBase.executeQueuedActions();
             
@@ -1484,6 +1471,7 @@
             executeQueuedActions();
         } finally {
             this.lock.unlock();
+            this.ruleBase.readUnlock();
         }
     }
 
@@ -1872,6 +1860,7 @@
     }
     
     public void startBatchExecution() {
+        this.ruleBase.readLock();
         this.lock.lock();
         this.batchExecutionResult = new BatchExecutionResultImpl();
     }
@@ -1883,6 +1872,7 @@
     public void endBatchExecution() {
         this.batchExecutionResult = null;
         this.lock.unlock();
+        this.ruleBase.readUnlock();
     }    
 
     // public static class FactHandleInvalidation implements WorkingMemoryAction

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java	2009-05-08 18:17:26 UTC (rev 26439)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java	2009-05-09 01:15:34 UTC (rev 26440)
@@ -147,5 +147,16 @@
      * @return
      */
     List<RuleBasePartitionId> getPartitionIds();
+    
+    /**
+     * Acquires a read lock on the rulebase
+     */
+    public void readLock();
+    
+    /**
+     * Releases a read lock on the rulebase
+     */
+    public void readUnlock();
+    
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java	2009-05-08 18:17:26 UTC (rev 26439)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java	2009-05-09 01:15:34 UTC (rev 26440)
@@ -345,95 +345,6 @@
         return session;
     }
 
-    //    public StatefulSession readStatefulSession(final InputStream stream,
-    //                                               final boolean keepReference,
-    //                                               final Marshaller marshaller,
-    //                                               final SessionConfiguration sessionConfig,
-    //                                               Environment environment ) throws IOException,
-    //                                                                          ClassNotFoundException {
-    //
-    //        if ( this.config.isSequential() ) {
-    //            throw new RuntimeException( "Cannot have a stateful rule session, with sequential configuration set to true" );
-    //        }
-    //
-    ////        PlaceholderResolverStrategyFactory factory = new PlaceholderResolverStrategyFactory();
-    ////        factory.addPlaceholderResolverStrategy( new SerializablePlaceholderResolverStrategy() );
-    //
-    //        StatefulSession session = null;
-    //        synchronized ( this.pkgs ) {
-    //           // ExecutorService executor = ExecutorServiceFactory.createExecutorService( this.config.getExecutorService() );
-    //            
-    //            session = ( StatefulSession ) ((StatefulKnowledgeSessionImpl)marshaller.unmarshall( stream, sessionConfig, environment )).session;
-    //
-    ////            WMSerialisationInContext context = new WMSerialisationInContext( stream,
-    ////                                                                             this,
-    ////                                                                             RuleBaseNodes.getNodeMap( this ),
-    ////                                                                             factory );
-    ////
-    ////            session = InputPersister.readSession( context, nextWorkingMemoryCounter(), executor );
-    //
-    //            // executor.setCommandExecutor( new CommandExecutor( session ) );
-    //
-    //
-    //            if ( keepReference ) {
-    //                super.addStatefulSession( session );
-    //                for ( Iterator it = session.getRuleBaseUpdateListeners().iterator(); it.hasNext(); ) {
-    //                    addEventListener( (RuleBaseEventListener) it.next() );
-    //                }
-    //            }
-    //        }
-    //        return session;
-    //
-    //        //        final DroolsObjectInputStream streamWithLoader = new DroolsObjectInputStream( stream,
-    //        //                                                                                      this.packageClassLoader );
-    //        //        streamWithLoader.setRuleBase( this );
-    //        //
-    //        //        final StatefulSession session = (StatefulSession) streamWithLoader.readObject();
-    //        //
-    //        //        synchronized ( this.pkgs ) {
-    //        //            ((InternalWorkingMemory) session).setRuleBase( this );
-    //        //            ((InternalWorkingMemory) session).setId( (nextWorkingMemoryCounter()) );
-    //        //
-    //        //            ExecutorService executor = ExecutorServiceFactory.createExecutorService( this.config.getExecutorService() );
-    //        //            executor.setCommandExecutor( new CommandExecutor( session ) );
-    //        //            ((InternalWorkingMemory) session).setExecutorService( executor );
-    //        //
-    //        //            if ( keepReference ) {
-    //        //                addStatefulSession( session );
-    //        //                for ( Iterator it = session.getRuleBaseUpdateListeners().iterator(); it.hasNext(); ) {
-    //        //                    addEventListener( (RuleBaseEventListener) it.next() );
-    //        //                }
-    //        //            }
-    //        //
-    //        //            return session;
-    //        //        }
-    //    }
-    //
-    //    public void writeStatefulSession(final StatefulSession session,
-    //                                     final OutputStream stream,
-    //                                     Marshaller marshaller) throws IOException {
-    //        
-    ////        PlaceholderResolverStrategyFactory factory = new PlaceholderResolverStrategyFactory();
-    ////        factory.addPlaceholderResolverStrategy( new SerializablePlaceholderResolverStrategy() );
-    ////
-    ////        WMSerialisationOutContext context = new WMSerialisationOutContext( stream,
-    ////                                                                           this,
-    ////                                                                           (InternalWorkingMemory) session,
-    ////                                                                           RuleBaseNodes.getNodeMap( this ),
-    ////                                                                           factory );
-    ////        OutputPersister.writeSession( context );
-    //        marshaller.marshall( stream, session );
-    //        //((ReteooStatefulSession) session).write( context );
-    //        
-    //
-    //        //        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-    //        //        OutputPersister op = new OutputPersister( this,
-    //        //                                                  (InternalWorkingMemory) wm,
-    //        //                                                  baos,
-    //        //                                                  factory );
-    //        //        op.write();
-    //    }
-
     public StatelessSession newStatelessSession() {
 
         //orders the rules

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooStatefulSession.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooStatefulSession.java	2009-05-08 18:17:26 UTC (rev 26439)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooStatefulSession.java	2009-05-09 01:15:34 UTC (rev 26440)
@@ -4,14 +4,12 @@
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
-import java.io.ObjectInputStream;
 import java.io.ObjectOutput;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
+import org.drools.FactHandle;
 import org.drools.SessionConfiguration;
 import org.drools.StatefulSession;
 import org.drools.common.InternalAgenda;
@@ -24,11 +22,9 @@
 import org.drools.concurrent.RetractObject;
 import org.drools.concurrent.UpdateObject;
 import org.drools.impl.EnvironmentFactory;
-import org.drools.impl.KnowledgeBaseImpl;
 import org.drools.impl.StatefulKnowledgeSessionImpl;
 import org.drools.marshalling.Marshaller;
 import org.drools.marshalling.MarshallerFactory;
-import org.drools.FactHandle;
 import org.drools.runtime.Environment;
 import org.drools.spi.AgendaFilter;
 import org.drools.spi.FactHandleFactory;




More information about the jboss-svn-commits mailing list