Marcus,
Checked in. Please cross-check.

Thanks,
dims

--- Marcus Crafter <[EMAIL PROTECTED]> wrote:
> Hi All,
> 
>       Hope all is well.
> 
>       During our recent load tests I've come across a thread-related bug in
>       the ProgramGenerator implementation. The symptoms are similar to the
>       sitemap recompilation issue we faced last week.
> 
>       If 2 simultaneous requests ask for the same xsp resource, which is not
>       compiled, or has changed, etc, then the that resource is created and
>       loaded twice. If the loading of the class occurs while the second
>       request is (re)compiling it, then very strange things happen.. :-)
> 
>       I've been able to reproduce this easily in our test environment, and
>       have attached a patch (using the Carsten method (TM) :-) ) which fixes
>       the problem. Hope it's all ok.
> 
>       Cheers,
> 
>       Marcus
> 
> -- 
>         .....
>      ,,$$$$$$$$$,      Marcus Crafter
>     ;$'      '$$$$:    Computer Systems Engineer
>     $:         $$$$:   Open Software Associates GmbH
>      $       o_)$$$:   82-84 Mainzer Landstrasse
>      ;$,    _/\ &&:'   60327 Frankfurt Germany
>        '     /( &&&
>            \_&&&&'     Email : [EMAIL PROTECTED]
>           &&&&.        Business Hours : +49 69 9757 200
>     &&&&&&&:
> 
> > Index: 
>src/org/apache/cocoon/components/language/generator/ProgramGeneratorImpl.java
> ===================================================================
> RCS file:
>
/home/cvspublic/xml-cocoon2/src/org/apache/cocoon/components/language/generator/ProgramGeneratorImpl.java,v
> retrieving revision 1.5.2.14
> diff -u -r1.5.2.14 ProgramGeneratorImpl.java
> --- src/org/apache/cocoon/components/language/generator/ProgramGeneratorImpl.java    
> 2001/08/22
> 03:57:58      1.5.2.14
> +++ src/org/apache/cocoon/components/language/generator/ProgramGeneratorImpl.java    
> 2001/08/29
> 15:47:06
> @@ -101,8 +101,9 @@
>      }
>  
>      /**
> -     * Set the global component manager. This metod also sets the
> -     * <code>ComponentSelector</code> used as language factory for both markup and 
>programming
> languages.
> +     * Set the global component manager. This method also sets the
> +     * <code>ComponentSelector</code> used as language factory for both markup
> +     * and programming languages.
>       * @param manager The global component manager
>       */
>      public void compose(ComponentManager manager) throws ComponentException {
> @@ -171,7 +172,7 @@
>              try {
>                  programInstance = (CompiledComponent) select(normalizedName);
>              } catch (Exception e) {
> -                getLogger().debug("The instance was not accessible, creating it 
>now.");
> +                getLogger().debug("The instance was not accessible from the 
>internal cache.
> Proceeding.");
>              }
>      
>              if ((programInstance == null) && this.preload) {
> @@ -187,32 +188,11 @@
>              }
>      
>              if (programInstance == null) {
> -                MarkupLanguage markupLanguage = null;
> -                ProgrammingLanguage programmingLanguage = null;
> -                try {
> -                    // Get markup and programming languages
> -                    markupLanguage =
> (MarkupLanguage)this.markupSelector.select(markupLanguageName);
> -                    programmingLanguage =
> (ProgrammingLanguage)this.languageSelector.select(programmingLanguageName);
> -                    programmingLanguage.setLanguageName(programmingLanguageName);
> -                    program = this.generateResource(newManager, fileName, 
>normalizedName,
> markupLanguage, programmingLanguage, resolver);
> -                } catch (LanguageException le) {
> -                    getLogger().debug("Language Exception", le);
> -                    throw new ProcessingException("Language Exception", le);
> -                } finally {
> -                    if (this.markupSelector != null) {
> -                        this.markupSelector.release(markupLanguage);
> -                    }
> -    
> -                    if (this.languageSelector != null) {
> -                        this.languageSelector.release(programmingLanguage);
> -                    }
> -                }
> -    
> -                try {
> -                    programInstance = (CompiledComponent) select(normalizedName);
> -                } catch (Exception cme) {
> -                    getLogger().debug("Can't load ServerPage", cme);
> -                }
> +             programInstance =
> +                    this.createResource(
> +                        newManager, fileName, normalizedName,
> +                        markupLanguageName, programmingLanguageName, resolver
> +                    );
>              }
>      
>              if (this.autoReload == false) {
> @@ -241,30 +221,80 @@
>      
>              if (programInstance == null) {
>                  if (program == null) {
> -                    MarkupLanguage markupLanguage = null;
> -                    ProgrammingLanguage programmingLanguage = null;
> -                    try {
> -                        // Get markup and programming languages
> -                        markupLanguage =
> (MarkupLanguage)this.markupSelector.select(markupLanguageName);
> -                        programmingLanguage =
> (ProgrammingLanguage)this.languageSelector.select(programmingLanguageName);
> -                        
>programmingLanguage.setLanguageName(programmingLanguageName);
> -                        program = this.generateResource(newManager, fileName, 
>normalizedName,
> markupLanguage, programmingLanguage, resolver);
> -                    } catch (LanguageException le) {
> -                        getLogger().debug("Language Exception", le);
> -                        throw new ProcessingException("Language Exception", le);
> -                    } finally {
> -                        this.markupSelector.release(markupLanguage);
> -                        this.languageSelector.release(programmingLanguage);
> -                    }
> -                }
> -                // Instantiate
> -                programInstance = (CompiledComponent) select(normalizedName);
> +                    programInstance =
> +                        this.createResource(
> +                            newManager, fileName, normalizedName, 
> +                            markupLanguageName, programmingLanguageName,
> +                            resolver
> +                        );
> +                } else
> +                    programInstance = (CompiledComponent) select(normalizedName);
>              }
>  
>              return programInstance;
>          } finally {
>              source.recycle();
>          }
> +    }
> +
> +    /**
> +     * Helper method to create resources in a threadsafe manner.
> +     */
> +    private CompiledComponent createResource(
> +        ComponentManager newManager,
> +        String fileName,
> +        String normalizedName,
> +        String markupLanguageName,
> +        String programmingLanguageName,
> +        SourceResolver resolver
> +    )
> +    throws Exception {
> +
> +        CompiledComponent programInstance = null;
> +        MarkupLanguage markupLanguage = null;
> +        ProgrammingLanguage programmingLanguage = null;
> +        Class program = null;
> +
> +        // prevent 2 requests from generating this resource simultaneously
> +        synchronized (this) {
> +            try {
> +                programInstance = (CompiledComponent) select(normalizedName);
> +            } catch (Exception e) {
> +
> +                getLogger().debug(
> +                     "Creating resource " +
> +                     normalizedName.replace(File.separatorChar, '.') +
> +                     ", using generator " + this
> +                );
> +
> +                try {
> +                    // Get markup and programming languages
> +                    markupLanguage =
> (MarkupLanguage)this.markupSelector.select(markupLanguageName);
> +                    programmingLanguage =
> (ProgrammingLanguage)this.languageSelector.select(programmingLanguageName);
> +                    programmingLanguage.setLanguageName(programmingLanguageName);
> +                    program = this.generateResource(newManager, fileName, 
>normalizedName,
> markupLanguage, programmingLanguage, resolver);
> +                } catch (LanguageException le) {
> +                    getLogger().debug("Language Exception", le);
> +                    throw new ProcessingException("Language Exception", le);
> +                } finally {
> +                    if (this.markupSelector != null) {
> +                        this.markupSelector.release(markupLanguage);
> +                    }
> +
> +                    if (this.languageSelector != null) {
> +                        this.languageSelector.release(programmingLanguage);
> +                    }
> +                }
> +
> +                try {
> +                    programInstance = (CompiledComponent) select(normalizedName);
> +                } catch (Exception cme) {
> +                    getLogger().debug("Can't load ServerPage", cme);
> +                }
> +            }
> +        }
> +
> +     return programInstance;
>      }
>  
>      private Class generateResource(ComponentManager newManager,
> Index: src/org/apache/cocoon/components/language/programming/java/JavaLanguage.java
> ===================================================================
> RCS file:
>
/home/cvspublic/xml-cocoon2/src/org/apache/cocoon/components/language/programming/java/JavaLanguage.java,v
> retrieving revision 1.2.2.4
> diff -u -r1.2.2.4 JavaLanguage.java
> --- src/org/apache/cocoon/components/language/programming/java/JavaLanguage.java     
> 2001/08/21
> 18:00:01      1.2.2.4
> +++ src/org/apache/cocoon/components/language/programming/java/JavaLanguage.java     
> 2001/08/29
> 15:47:06
> @@ -149,11 +149,10 @@
>        String pathname =
>          baseDirectory.getCanonicalPath() + File.separator +
>          name.substring(0, pos).replace(File.separatorChar, '/');
> +      String filename_abs =
> +        pathname + File.separator + filename + "." + this.getSourceExtension();
>  
> -      compiler.setFile(
> -        pathname + File.separator +
> -        filename + "." + this.getSourceExtension()
> -      );
> +      compiler.setFile(filename_abs);
> 
=== message truncated ===> 
---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, email: [EMAIL PROTECTED]


=====
Davanum Srinivas, JNI-FAQ Manager
http://www.jGuru.com/faq/JNI

__________________________________________________
Do You Yahoo!?
Make international calls for as low as $.04/minute with Yahoo! Messenger
http://phonecard.yahoo.com/

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to