[jboss-cvs] JBossAS SVN: r84336 - in projects: jboss-threads and 34 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Feb 17 18:09:48 EST 2009
Author: david.lloyd at jboss.com
Date: 2009-02-17 18:09:48 -0500 (Tue, 17 Feb 2009)
New Revision: 84336
Added:
projects/jboss-threads/
projects/jboss-threads/branches/
projects/jboss-threads/tags/
projects/jboss-threads/trunk/
projects/jboss-threads/trunk/COPYING.txt
projects/jboss-threads/trunk/jbossmc/
projects/jboss-threads/trunk/jbossmc/pom.xml
projects/jboss-threads/trunk/jbossmc/src/
projects/jboss-threads/trunk/jbossmc/src/main/
projects/jboss-threads/trunk/jbossmc/src/main/java/
projects/jboss-threads/trunk/jbossmc/src/main/java/org/
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/DirectExecutorMetaData.java
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ExceptionHandlerRefMetaData.java
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/InterruptHandlerRefMetaData.java
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/NotatingExecutorMetaData.java
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/PoolSizeMetaData.java
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/RejectPolicyMetaData.java
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadFactoryMetaData.java
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadGroupMetaData.java
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadPoolExecutorMetaData.java
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadsMetaData.java
projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/TimeMetaData.java
projects/jboss-threads/trunk/jbossmc/src/main/resources/
projects/jboss-threads/trunk/jbossmc/src/main/resources/META-INF/
projects/jboss-threads/trunk/jbossmc/src/main/resources/META-INF/jboss-beans.xml
projects/jboss-threads/trunk/jbossmc/src/main/resources/schema/
projects/jboss-threads/trunk/jbossmc/src/main/resources/schema/jboss-threads_1_0.xsd
projects/jboss-threads/trunk/main/
projects/jboss-threads/trunk/main/pom.xml
projects/jboss-threads/trunk/main/src/
projects/jboss-threads/trunk/main/src/main/
projects/jboss-threads/trunk/main/src/main/java/
projects/jboss-threads/trunk/main/src/main/java/org/
projects/jboss-threads/trunk/main/src/main/java/org/jboss/
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ArrayQueue.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DirectExecutor.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DirectExecutorService.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/InterruptHandler.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossExecutors.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThread.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadFactory.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadPoolExecutor.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/OrderedExecutor.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutor.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutorService.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutorService.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/RejectionPolicy.java
projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/SimpleQueueExecutor.java
projects/jboss-threads/trunk/main/src/main/resources/
projects/jboss-threads/trunk/main/src/main/resources/META-INF/
projects/jboss-threads/trunk/main/src/main/resources/META-INF/jboss-classloading.xml
projects/jboss-threads/trunk/main/src/test/
projects/jboss-threads/trunk/main/src/test/java/
projects/jboss-threads/trunk/main/src/test/java/org/
projects/jboss-threads/trunk/main/src/test/java/org/jboss/
projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/
projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ArrayQueueTestCase.java
projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadFactoryTestCase.java
projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadPoolTestCase.java
projects/jboss-threads/trunk/pom.xml
projects/jboss-threads/trunk/test-support/
projects/jboss-threads/trunk/test-support/src/
projects/jboss-threads/trunk/test-support/src/main/
projects/jboss-threads/trunk/test-support/src/main/java/
projects/jboss-threads/trunk/test-support/src/main/java/org/
projects/jboss-threads/trunk/test-support/src/main/java/org/jboss/
projects/jboss-threads/trunk/test-support/src/main/java/org/jboss/testsupport/
projects/jboss-threads/trunk/test-support/src/main/java/org/jboss/testsupport/LoggingHelper.java
projects/jboss-threads/trunk/test-support/src/main/java/org/jboss/testsupport/LoggingSecurityManager.java
projects/jboss-threads/trunk/test-support/src/main/resources/
projects/jboss-threads/trunk/test-support/src/main/resources/testing.policy
Log:
Import jboss-threads project
Added: projects/jboss-threads/trunk/COPYING.txt
===================================================================
--- projects/jboss-threads/trunk/COPYING.txt (rev 0)
+++ projects/jboss-threads/trunk/COPYING.txt 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,458 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
Added: projects/jboss-threads/trunk/jbossmc/pom.xml
===================================================================
--- projects/jboss-threads/trunk/jbossmc/pom.xml (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/pom.xml 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,39 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.jboss.threads</groupId>
+ <artifactId>threads-metadata</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0.0.CR1</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.threads</groupId>
+ <artifactId>threads</artifactId>
+ <version>1.0.0.CR1</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.microcontainer</groupId>
+ <artifactId>jboss-kernel</artifactId>
+ <version>2.0.2.GA</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ <finalName>jboss-threads-metadata</finalName>
+ </build>
+</project>
Added: projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/DirectExecutorMetaData.java
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/DirectExecutorMetaData.java (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/DirectExecutorMetaData.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads.metadata;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ *
+ */
+ at XmlType(name = "direct-executor")
+public final class DirectExecutorMetaData {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ @XmlAttribute(required = true)
+ public void setName(final String name) {
+ this.name = name;
+ }
+}
Added: projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ExceptionHandlerRefMetaData.java
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ExceptionHandlerRefMetaData.java (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ExceptionHandlerRefMetaData.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads.metadata;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ *
+ */
+ at XmlType(name = "exception-handler")
+public final class ExceptionHandlerRefMetaData {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ @XmlAttribute(required = true)
+ public void setName(final String name) {
+ this.name = name;
+ }
+}
Added: projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/InterruptHandlerRefMetaData.java
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/InterruptHandlerRefMetaData.java (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/InterruptHandlerRefMetaData.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads.metadata;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ *
+ */
+ at XmlType(name = "interrupt-handler")
+public final class InterruptHandlerRefMetaData {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ @XmlAttribute(required = true)
+ public void setName(final String name) {
+ this.name = name;
+ }
+}
Added: projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/NotatingExecutorMetaData.java
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/NotatingExecutorMetaData.java (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/NotatingExecutorMetaData.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads.metadata;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ *
+ */
+ at XmlType(name = "notating-executor")
+public final class NotatingExecutorMetaData {
+ private String name;
+ private String parent;
+ private String note;
+
+ public String getName() {
+ return name;
+ }
+
+ @XmlAttribute(required = true)
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getParent() {
+ return parent;
+ }
+
+ @XmlAttribute(required = true)
+ public void setParent(final String parent) {
+ this.parent = parent;
+ }
+
+ public String getNote() {
+ return note;
+ }
+
+ @XmlAttribute(required = true)
+ public void setNote(final String note) {
+ this.note = note;
+ }
+}
Added: projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/PoolSizeMetaData.java
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/PoolSizeMetaData.java (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/PoolSizeMetaData.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads.metadata;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ *
+ */
+ at XmlType(name = "pool-size")
+public final class PoolSizeMetaData {
+ private float count;
+ private float perCpu;
+
+ public float getCount() {
+ return count;
+ }
+
+ @XmlAttribute
+ public void setCount(final float count) {
+ this.count = count;
+ }
+
+ public float getPerCpu() {
+ return perCpu;
+ }
+
+ @XmlAttribute(name = "per-cpu")
+ public void setPerCpu(final float perCpu) {
+ this.perCpu = perCpu;
+ }
+}
Added: projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/RejectPolicyMetaData.java
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/RejectPolicyMetaData.java (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/RejectPolicyMetaData.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads.metadata;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ *
+ */
+ at XmlType(name = "reject-policy")
+public final class RejectPolicyMetaData {
+ private String name;
+ private String executorName;
+
+ public String getName() {
+ return name;
+ }
+
+ @XmlAttribute(required = true)
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getExecutorName() {
+ return executorName;
+ }
+
+ @XmlAttribute(name = "executor-name")
+ public void setExecutorName(final String executorName) {
+ this.executorName = executorName;
+ }
+}
Added: projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadFactoryMetaData.java
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadFactoryMetaData.java (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadFactoryMetaData.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,114 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads.metadata;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ *
+ */
+ at XmlType(name = "thread-factory")
+public final class ThreadFactoryMetaData {
+ private String name;
+ private String group;
+ private Boolean daemon;
+ private Integer initialPriority;
+ private Long stackSize;
+ private String threadNamePattern = "pool-%f-thread-%t";
+ private ExceptionHandlerRefMetaData exceptionHandler;
+ private InterruptHandlerRefMetaData[] interruptHandlers = new InterruptHandlerRefMetaData[0];
+
+ public String getName() {
+ return name;
+ }
+
+ @XmlAttribute(required = true)
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ @XmlAttribute
+ public void setGroup(final String group) {
+ this.group = group;
+ }
+
+ public Boolean getDaemon() {
+ return daemon;
+ }
+
+ @XmlAttribute
+ public void setDaemon(final Boolean daemon) {
+ this.daemon = daemon;
+ }
+
+ public Integer getInitialPriority() {
+ return initialPriority;
+ }
+
+ @XmlAttribute(name = "initial-priority")
+ public void setInitialPriority(final Integer initialPriority) {
+ this.initialPriority = initialPriority;
+ }
+
+ public Long getStackSize() {
+ return stackSize;
+ }
+
+ @XmlAttribute(name = "stack-size")
+ public void setStackSize(final Long stackSize) {
+ this.stackSize = stackSize;
+ }
+
+ public String getThreadNamePattern() {
+ return threadNamePattern;
+ }
+
+ @XmlAttribute(name = "thread-name-pattern")
+ public void setThreadNamePattern(final String threadNamePattern) {
+ this.threadNamePattern = threadNamePattern;
+ }
+
+ public ExceptionHandlerRefMetaData getExceptionHandler() {
+ return exceptionHandler;
+ }
+
+ @XmlElement(name = "exception-handler")
+ public void setExceptionHandler(final ExceptionHandlerRefMetaData exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+
+ public InterruptHandlerRefMetaData[] getInterruptHandlers() {
+ return interruptHandlers;
+ }
+
+ @XmlElement(name = "interrupt-handler")
+ public void setInterruptHandlers(final InterruptHandlerRefMetaData[] interruptHandlers) {
+ this.interruptHandlers = interruptHandlers;
+ }
+}
Added: projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadGroupMetaData.java
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadGroupMetaData.java (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadGroupMetaData.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads.metadata;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+ at XmlType(name = "thread-group")
+public final class ThreadGroupMetaData {
+ private String name;
+ private String groupName;
+ private String parent;
+ private Boolean daemon;
+ private Integer maxPriority;
+
+ public String getName() {
+ return name;
+ }
+
+ @XmlAttribute(required = true)
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getGroupName() {
+ return groupName;
+ }
+
+ @XmlAttribute(name = "group-name", required = true)
+ public void setGroupName(final String groupName) {
+ this.groupName = groupName;
+ }
+
+ public String getParent() {
+ return parent;
+ }
+
+ @XmlAttribute
+ public void setParent(final String parent) {
+ this.parent = parent;
+ }
+
+ public Boolean isDaemon() {
+ return daemon;
+ }
+
+ @XmlAttribute
+ public void setDaemon(final Boolean daemon) {
+ this.daemon = daemon;
+ }
+
+ public Integer getMaxPriority() {
+ return maxPriority;
+ }
+
+ @XmlAttribute(name = "max-priority")
+ public void setMaxPriority(final Integer maxPriority) {
+ this.maxPriority = maxPriority;
+ }
+}
Added: projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadPoolExecutorMetaData.java
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadPoolExecutorMetaData.java (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadPoolExecutorMetaData.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,114 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads.metadata;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ *
+ */
+ at XmlType(name = "thread-pool-executor")
+public final class ThreadPoolExecutorMetaData {
+ private String name;
+ private String threadFactory;
+ private PoolSizeMetaData corePoolSize;
+ private PoolSizeMetaData maxPoolSize;
+ private TimeMetaData keepAliveTime;
+ private RejectPolicyMetaData rejectPolicyMetaData;
+ private Integer queueLength;
+ private boolean allowCoreTimeout;
+
+ public String getName() {
+ return name;
+ }
+
+ @XmlAttribute(required = true)
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getThreadFactory() {
+ return threadFactory;
+ }
+
+ @XmlAttribute(name = "thread-factory", required = true)
+ public void setThreadFactory(final String threadFactory) {
+ this.threadFactory = threadFactory;
+ }
+
+ public PoolSizeMetaData getCorePoolSize() {
+ return corePoolSize;
+ }
+
+ @XmlElement(name = "core-pool-size")
+ public void setCorePoolSize(final PoolSizeMetaData corePoolSize) {
+ this.corePoolSize = corePoolSize;
+ }
+
+ public PoolSizeMetaData getMaxPoolSize() {
+ return maxPoolSize;
+ }
+
+ @XmlElement(name = "max-pool-size")
+ public void setMaxPoolSize(final PoolSizeMetaData maxPoolSize) {
+ this.maxPoolSize = maxPoolSize;
+ }
+
+ public TimeMetaData getKeepAliveTime() {
+ return keepAliveTime;
+ }
+
+ @XmlElement(name = "keepalive-time")
+ public void setKeepAliveTime(final TimeMetaData keepAliveTime) {
+ this.keepAliveTime = keepAliveTime;
+ }
+
+ public RejectPolicyMetaData getRejectPolicyMetaData() {
+ return rejectPolicyMetaData;
+ }
+
+ @XmlElement(name = "reject-policy")
+ public void setRejectPolicyMetaData(final RejectPolicyMetaData rejectPolicyMetaData) {
+ this.rejectPolicyMetaData = rejectPolicyMetaData;
+ }
+
+ public Integer getQueueLength() {
+ return queueLength;
+ }
+
+ @XmlAttribute(name = "queue-length")
+ public void setQueueLength(final Integer queueLength) {
+ this.queueLength = queueLength;
+ }
+
+ public boolean isAllowCoreTimeout() {
+ return allowCoreTimeout;
+ }
+
+ @XmlAttribute(name = "allow-core-timeout")
+ public void setAllowCoreTimeout(final boolean allowCoreTimeout) {
+ this.allowCoreTimeout = allowCoreTimeout;
+ }
+}
Added: projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadsMetaData.java
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadsMetaData.java (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/ThreadsMetaData.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,383 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads.metadata;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.Queue;
+import java.util.LinkedList;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ArrayBlockingQueue;
+import org.jboss.xb.annotations.JBossXmlSchema;
+import org.jboss.beans.metadata.spi.BeanMetaData;
+import org.jboss.beans.metadata.spi.ValueMetaData;
+import org.jboss.beans.metadata.spi.BeanMetaDataFactory;
+import org.jboss.beans.metadata.spi.builder.BeanMetaDataBuilder;
+import org.jboss.threads.JBossThreadFactory;
+import org.jboss.threads.InterruptHandler;
+import org.jboss.threads.SimpleQueueExecutor;
+import org.jboss.threads.JBossExecutors;
+import org.jboss.threads.RejectionPolicy;
+import org.jboss.threads.ArrayQueue;
+import org.jboss.threads.JBossThreadPoolExecutor;
+import org.jboss.threads.DirectExecutor;
+import org.jboss.dependency.spi.ControllerMode;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlNsForm;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlTransient;
+
+/**
+ *
+ */
+ at JBossXmlSchema(namespace = "urn:jboss:threads:1.0", elementFormDefault = XmlNsForm.QUALIFIED)
+ at XmlRootElement(name = "threads")
+ at XmlType(name = "threads")
+public final class ThreadsMetaData implements BeanMetaDataFactory {
+ private static final class StringEntry implements Map.Entry<String, String> {
+ private final String key;
+ private final String value;
+
+ private StringEntry(final String key, final String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public String setValue(final String value) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private static StringEntry entry(final String key, final String value) {
+ return new StringEntry(key, value);
+ }
+
+ private static Map<String, String> stringMap(StringEntry... entries) {
+ final HashMap<String, String> hashMap = new HashMap<String, String>(entries.length);
+ for (Map.Entry<String, String> e : entries) {
+ hashMap.put(e.getKey(), e.getValue());
+ }
+ return Collections.unmodifiableMap(hashMap);
+ }
+
+ private static final Map<String, String> UNIT_NICK_NAMES = stringMap(
+ entry("S", "SECONDS"),
+ entry("SEC", "SECONDS"),
+ entry("M", "MINUTES"),
+ entry("MIN", "MINUTES"),
+ entry("MS", "MILLISECONDS"),
+ entry("NS", "NANOSECONDS"),
+ entry("H", "HOURS"),
+ entry("D", "DAYS"),
+ entry("MON", "MONTHS"),
+ entry("W", "WEEKS")
+ );
+
+ private List<ThreadGroupMetaData> threadGroups = new ArrayList<ThreadGroupMetaData>();
+ private List<ThreadFactoryMetaData> threadFactories = new ArrayList<ThreadFactoryMetaData>();
+ private List<ThreadPoolExecutorMetaData> threadPoolExecutors = new ArrayList<ThreadPoolExecutorMetaData>();
+ private List<DirectExecutorMetaData> directExecutors = new ArrayList<DirectExecutorMetaData>();
+ private List<NotatingExecutorMetaData> notatingExecutors = new ArrayList<NotatingExecutorMetaData>();
+
+ public List<ThreadGroupMetaData> getThreadGroups() {
+ return threadGroups;
+ }
+
+ @XmlElement(name = "thread-group")
+ public void setThreadGroups(final List<ThreadGroupMetaData> threadGroups) {
+ this.threadGroups = threadGroups;
+ }
+
+ public List<ThreadFactoryMetaData> getThreadFactories() {
+ return threadFactories;
+ }
+
+ @XmlElement(name = "thread-factory")
+ public void setThreadFactories(final List<ThreadFactoryMetaData> threadFactories) {
+ this.threadFactories = threadFactories;
+ }
+
+ public List<ThreadPoolExecutorMetaData> getThreadPoolExecutors() {
+ return threadPoolExecutors;
+ }
+
+ @XmlElement(name = "thread-pool-executor")
+ public void setThreadPoolExecutors(final List<ThreadPoolExecutorMetaData> threadPoolExecutors) {
+ this.threadPoolExecutors = threadPoolExecutors;
+ }
+
+ public List<DirectExecutorMetaData> getDirectExecutors() {
+ return directExecutors;
+ }
+
+ @XmlElement(name = "direct-executor")
+ public void setDirectExecutors(final List<DirectExecutorMetaData> directExecutors) {
+ this.directExecutors = directExecutors;
+ }
+
+ public List<NotatingExecutorMetaData> getNotatingExecutors() {
+ return notatingExecutors;
+ }
+
+ @XmlElement(name = "notating-executor")
+ public void setNotatingExecutors(final List<NotatingExecutorMetaData> notatingExecutors) {
+ this.notatingExecutors = notatingExecutors;
+ }
+
+ @XmlTransient
+ public List<BeanMetaData> getBeans() {
+ List<BeanMetaData> beanMetaDataList = new ArrayList<BeanMetaData>();
+ for (ThreadGroupMetaData metaData : threadGroups) {
+ final String name = metaData.getName();
+ final BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(name, ThreadGroup.class.getName());
+ builder.setMode(ControllerMode.ON_DEMAND);
+ final String parent = metaData.getParent();
+ if (parent != null && parent.length() > 0) {
+ builder.addConstructorParameter(ThreadGroup.class.getName(), builder.createInject(parent));
+ }
+ builder.addConstructorParameter(String.class.getName(), builder.createValue(name));
+ if (metaData.isDaemon() != null) {
+ builder.addPropertyMetaData("daemon", builder.createValue(metaData.isDaemon()));
+ }
+ final Integer maxPriorityMeta = metaData.getMaxPriority();
+ if (maxPriorityMeta != null) {
+ builder.addPropertyMetaData("maxPriority", builder.createValue(maxPriorityMeta));
+ }
+ builder.ignoreStop();
+ beanMetaDataList.add(builder.getBeanMetaData());
+ }
+ for (ThreadFactoryMetaData metaData : threadFactories) {
+ final String name = metaData.getName();
+ final BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(name, JBossThreadFactory.class.getName());
+ builder.setMode(ControllerMode.ON_DEMAND);
+ final String group = metaData.getGroup();
+ builder.addConstructorParameter(ThreadGroup.class.getName(), group == null ? builder.createNull() : builder.createInject(group));
+ final Boolean daemon = metaData.getDaemon();
+ builder.addConstructorParameter(Boolean.class.getName(), daemon == null ? builder.createNull() : builder.createValue(daemon));
+ final Integer priorityMeta = metaData.getInitialPriority();
+ final Integer actualPriorityMeta;
+ if (priorityMeta != null) {
+ actualPriorityMeta = priorityMeta;
+ } else {
+ actualPriorityMeta = null;
+ }
+ builder.addConstructorParameter(Integer.class.getName(), actualPriorityMeta == null ? builder.createNull() : builder.createValue(actualPriorityMeta));
+ builder.addConstructorParameter(String.class.getName(), builder.createValue(metaData.getThreadNamePattern()));
+ final List<ValueMetaData> interruptHandlers = builder.createArray(InterruptHandler[].class.getName(), InterruptHandler.class.getName());
+ for (InterruptHandlerRefMetaData ihmd : metaData.getInterruptHandlers()) {
+ interruptHandlers.add(builder.createInject(ihmd.getName()));
+ }
+ builder.addConstructorParameter(InterruptHandler[].class.getName(), (ValueMetaData) interruptHandlers);
+ final ExceptionHandlerRefMetaData ehmd = metaData.getExceptionHandler();
+ builder.addConstructorParameter(Thread.UncaughtExceptionHandler.class.getName(), ehmd == null ? builder.createNull() : builder.createInject(ehmd.getName()));
+ final Long stackSize = metaData.getStackSize();
+ builder.addConstructorParameter(Long.class.getName(), stackSize == null ? builder.createNull() : builder.createValue(stackSize));
+ beanMetaDataList.add(builder.getBeanMetaData());
+ }
+ for (ThreadPoolExecutorMetaData metaData : threadPoolExecutors) {
+ final String name = metaData.getName();
+ final PoolSizeMetaData corePoolSizeMetaData = metaData.getCorePoolSize();
+ final int corePoolSize;
+ if (corePoolSizeMetaData == null) {
+ corePoolSize = 0;
+ } else {
+ corePoolSize = Math.max(calcPoolSize(corePoolSizeMetaData), 0);
+ }
+ final PoolSizeMetaData maxPoolSizeMetaData = metaData.getMaxPoolSize();
+ final int maxPoolSize;
+ if (maxPoolSizeMetaData == null) {
+ maxPoolSize = corePoolSize;
+ } else {
+ maxPoolSize = Math.max(calcPoolSize(maxPoolSizeMetaData), corePoolSize < 1 ? 1 : corePoolSize);
+ }
+ final TimeMetaData timeMetaData = metaData.getKeepAliveTime();
+ final long time;
+ final TimeUnit unit;
+ if (timeMetaData == null) {
+ time = Long.MAX_VALUE;
+ unit = TimeUnit.NANOSECONDS;
+ } else {
+ time = Math.max(0L, timeMetaData.getTime());
+ final String unitName = timeMetaData.getUnit();
+
+ if (unitName == null) {
+ unit = TimeUnit.MILLISECONDS;
+ } else {
+ final String upperUnitName = unitName.toUpperCase();
+ if (UNIT_NICK_NAMES.containsKey(upperUnitName)) {
+ unit = TimeUnit.valueOf(UNIT_NICK_NAMES.get(upperUnitName));
+ } else {
+ unit = TimeUnit.valueOf(upperUnitName);
+ }
+ }
+ }
+ final String threadFactory = metaData.getThreadFactory();
+ final Integer queueLength = metaData.getQueueLength();
+ final RejectPolicyMetaData rejectPolicyMetaData = metaData.getRejectPolicyMetaData();
+ final String policyName = rejectPolicyMetaData == null ? "block" : rejectPolicyMetaData.getName();
+ final BeanMetaDataBuilder executorBuilder;
+ // here is where we decide which thread pool implementation to use
+ // right now, our criteria is simple - if blocking is desired, use the queue executor instead
+ if ("block".equals(policyName)) {
+ // use SimpleQueueExecutor
+ executorBuilder = BeanMetaDataBuilder.createBuilder(SimpleQueueExecutor.class.getName());
+ final RejectionPolicy rejectionPolicy;
+ final ValueMetaData handoffExecutorValue;
+ if ("abort".equals(policyName)) {
+ rejectionPolicy = RejectionPolicy.ABORT;
+ handoffExecutorValue = executorBuilder.createNull();
+ } else if ("block".equals(policyName)) {
+ rejectionPolicy = RejectionPolicy.BLOCK;
+ handoffExecutorValue = executorBuilder.createNull();
+ } else if ("caller-runs".equals(policyName)) {
+ rejectionPolicy = RejectionPolicy.HANDOFF;
+ handoffExecutorValue = executorBuilder.createValue(JBossExecutors.directExecutor());
+ } else if ("discard".equals(policyName)) {
+ rejectionPolicy = RejectionPolicy.DISCARD;
+ handoffExecutorValue = executorBuilder.createNull();
+ } else if ("discard-oldest".equals(policyName)) {
+ rejectionPolicy = RejectionPolicy.DISCARD_OLDEST;
+ handoffExecutorValue = executorBuilder.createNull();
+ } else if ("handoff".equals(policyName)) {
+ rejectionPolicy = RejectionPolicy.HANDOFF;
+ handoffExecutorValue = executorBuilder.createInject(rejectPolicyMetaData.getExecutorName());
+ } else {
+ throw new IllegalStateException();
+ }
+ final Queue<Runnable> queue;
+ if (queueLength == null) {
+ queue = new LinkedList<Runnable>();
+ } else {
+ queue = new ArrayQueue<Runnable>(queueLength.intValue());
+ }
+ executorBuilder.addConstructorParameter("int", Integer.valueOf(corePoolSize));
+ executorBuilder.addConstructorParameter("int", Integer.valueOf(maxPoolSize));
+ executorBuilder.addConstructorParameter("long", Long.valueOf(time));
+ executorBuilder.addConstructorParameter(TimeUnit.class.getName(), unit);
+ executorBuilder.addConstructorParameter(Queue.class.getName(), executorBuilder.createValue(queue));
+ executorBuilder.addConstructorParameter(ThreadFactory.class.getName(), executorBuilder.createInject(threadFactory));
+ executorBuilder.addConstructorParameter(RejectionPolicy.class.getName(), rejectionPolicy);
+ executorBuilder.addConstructorParameter(Executor.class.getName(), handoffExecutorValue);
+ if (metaData.isAllowCoreTimeout()) {
+ executorBuilder.addPropertyMetaData("allowCoreTimeout", Boolean.TRUE);
+ }
+ } else {
+ // use ThreadPoolExecutor
+ executorBuilder = BeanMetaDataBuilder.createBuilder(JBossThreadPoolExecutor.class.getName());
+ final ValueMetaData policyValue;
+ if ("abort".equals(policyName)) {
+ policyValue = executorBuilder.createValue(JBossExecutors.abortPolicy());
+ } else if ("block".equals(policyName)) {
+ throw new IllegalStateException();
+ } else if ("caller-runs".equals(policyName)) {
+ policyValue = executorBuilder.createValue(JBossExecutors.callerRunsPolicy());
+ } else if ("discard".equals(policyName)) {
+ policyValue = executorBuilder.createValue(JBossExecutors.discardPolicy());
+ } else if ("discard-oldest".equals(policyName)) {
+ policyValue = executorBuilder.createValue(JBossExecutors.discardOldestPolicy());
+ } else if ("handoff".equals(policyName)) {
+ final BeanMetaDataBuilder policyBuilder = BeanMetaDataBuilder.createBuilder(RejectedExecutionHandler.class.getName());
+ policyBuilder.setFactoryClass(JBossExecutors.class.getName());
+ policyBuilder.setFactoryMethod("handoffPolicy");
+ policyBuilder.addConstructorParameter(Executor.class.getName(), policyBuilder.createInject(rejectPolicyMetaData.getExecutorName()));
+ policyValue = policyBuilder.getBeanMetaData();
+ } else {
+ throw new IllegalStateException();
+ }
+ final BlockingQueue<Runnable> queue;
+ if (queueLength == null) {
+ // todo: try LinkedTransferQueue
+ queue = new LinkedBlockingQueue<Runnable>();
+ } else {
+ queue = new ArrayBlockingQueue<Runnable>(queueLength.intValue());
+ }
+ executorBuilder.addConstructorParameter("int", Integer.valueOf(corePoolSize));
+ executorBuilder.addConstructorParameter("int", Integer.valueOf(maxPoolSize));
+ executorBuilder.addConstructorParameter("long", Long.valueOf(time));
+ executorBuilder.addConstructorParameter(TimeUnit.class.getName(), unit);
+ executorBuilder.addConstructorParameter(BlockingQueue.class.getName(), executorBuilder.createValue(queue));
+ executorBuilder.addConstructorParameter(ThreadFactory.class.getName(), executorBuilder.createInject(threadFactory));
+ executorBuilder.addConstructorParameter(RejectedExecutionHandler.class.getName(), policyValue);
+ }
+ executorBuilder.setMode(ControllerMode.ON_DEMAND);
+// final BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(name, ExecutorService.class.getName());
+// builder.setFactoryClass(JBossExecutors.class.getName());
+// builder.setFactoryMethod("protectedExecutorService");
+// builder.addConstructorParameter(Executor.class.getName(), executorBuilder.getBeanMetaData());
+// builder.setMode(ControllerMode.ON_DEMAND);
+// beanMetaDataList.add(builder.getBeanMetaData());
+ executorBuilder.setName(name);
+ beanMetaDataList.add(executorBuilder.getBeanMetaData());
+ }
+ for (DirectExecutorMetaData metaData : directExecutors) {
+ final String name = metaData.getName();
+ final BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(name, ExecutorService.class.getName());
+ builder.setFactoryClass(JBossExecutors.class.getName());
+ builder.setFactoryMethod("directExecutorService");
+ builder.setMode(ControllerMode.ON_DEMAND);
+ beanMetaDataList.add(builder.getBeanMetaData());
+ }
+ for (NotatingExecutorMetaData metaData : notatingExecutors) {
+ final String name = metaData.getName();
+ final BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(name, DirectExecutor.class.getName());
+ builder.setMode(ControllerMode.ON_DEMAND);
+ builder.setFactoryClass(JBossExecutors.class.getName());
+ builder.setFactoryMethod("notatingExecutor");
+ builder.addConstructorParameter(Executor.class.getName(), builder.createInject(metaData.getParent()));
+ builder.addConstructorParameter(String.class.getName(), metaData.getNote());
+ beanMetaDataList.add(builder.getBeanMetaData());
+ }
+ return beanMetaDataList;
+ }
+
+ private static int calcPoolSize(PoolSizeMetaData poolSizeMetaData) {
+ float count = poolSizeMetaData.getCount();
+ float perCpu = poolSizeMetaData.getPerCpu();
+ if (Float.isNaN(count) || Float.isInfinite(count) || count < 0.0f) {
+ count = 0.0f;
+ }
+ if (Float.isNaN(perCpu) || Float.isInfinite(perCpu) || perCpu < 0.0f) {
+ perCpu = 0.0f;
+ }
+ return Math.round(count + ((float) Runtime.getRuntime().availableProcessors()) * perCpu);
+ }
+}
Added: projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/TimeMetaData.java
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/TimeMetaData.java (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/java/org/jboss/threads/metadata/TimeMetaData.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads.metadata;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ *
+ */
+ at XmlType(name = "time")
+public final class TimeMetaData {
+ private String unit;
+ private long time;
+
+ public String getUnit() {
+ return unit;
+ }
+
+ @XmlAttribute
+ public void setUnit(final String unit) {
+ this.unit = unit;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ @XmlAttribute(required = true)
+ public void setTime(final long time) {
+ this.time = time;
+ }
+}
Added: projects/jboss-threads/trunk/jbossmc/src/main/resources/META-INF/jboss-beans.xml
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/resources/META-INF/jboss-beans.xml (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/resources/META-INF/jboss-beans.xml 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+ <bean name="JBossThreadsMetaDataFactoryDeployer" class="org.jboss.deployers.vfs.deployer.kernel.BeanMetaDataFactoryDeployer">
+ <constructor>
+ <parameter>org.jboss.threads.metadata.ThreadsMetaData</parameter>
+ </constructor>
+ </bean>
+
+ <bean name="JBossThreadsMetaDataSchemaResolverDeployer" class="org.jboss.deployers.vfs.spi.deployer.SchemaResolverDeployer">
+ <constructor>
+ <parameter>org.jboss.threads.metadata.ThreadsMetaData</parameter>
+ </constructor>
+ <property name="name">jboss-threads.xml</property>
+ <property name="registerWithJBossXB">true</property>
+ </bean>
+
+ <classloading xmlns="urn:jboss:classloading:1.0" version="1.0.0.CR1" import-all="false">
+ <requirements>
+ <module name="jboss-threads" from="1.0.0.CR1" from-inclusive="true"/>
+ <package name="org.jboss.deployers.vfs.deployer.kernel"/>
+ <package name="org.jboss.deployers.vfs.spi.deployer"/>
+ </requirements>
+ </classloading>
+</deployment>
Added: projects/jboss-threads/trunk/jbossmc/src/main/resources/schema/jboss-threads_1_0.xsd
===================================================================
--- projects/jboss-threads/trunk/jbossmc/src/main/resources/schema/jboss-threads_1_0.xsd (rev 0)
+++ projects/jboss-threads/trunk/jbossmc/src/main/resources/schema/jboss-threads_1_0.xsd 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
+ targetNamespace="urn:jboss:threads:1.0"
+ xmlns="urn:jboss:threads:1.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="1.0">
+
+ <xsd:element name="threads" type="threads"/>
+
+ <xsd:complexType name="threads">
+ <xsd:annotation>
+ <xsd:documentation>
+ The root threads deployment element. Specify thread groups, thread factories, and executors within.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+ <xsd:choice>
+ <xsd:element name="thread-group" type="thread-group"/>
+ <xsd:element name="thread-factory" type="thread-factory"/>
+ <xsd:element name="thread-pool-executor" type="thread-pool-executor"/>
+ <xsd:element name="direct-executor" type="direct-executor"/>
+ <xsd:element name="notating-executor" type="notating-executor"/>
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="thread-group">
+ <xsd:annotation>
+ <xsd:documentation>
+ A thread group that can be referenced by a bean name. The "name" attribute is the
+ bean name of the created thread group, used for injection. The "group-name" attribute is
+ the JDK name of the thread group. The optional "daemon" attribute specifies whether
+ threads should be forced to be daemon threads, or forced to be non-daemon threads (not
+ specifying this attribute will cause the thread group to inherit the daemon status from
+ its parent). The optional "max-priority" attribute can be used to limit the priority of
+ threads within the group. The optional "parent" attribute specifies the parent thread
+ group (by bean name).
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="group-name" type="xsd:string" use="required"/>
+ <xsd:attribute name="daemon" type="xsd:boolean" use="optional"/>
+ <xsd:attribute name="max-priority" type="priority" use="optional"/>
+ <xsd:attribute name="parent" type="xsd:string" use="optional"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="thread-factory">
+ <xsd:annotation>
+ <xsd:documentation>
+ A thread factory (implementing java.util.concurrent.ThreadFactory). The "name" attribute is
+ the bean name of the created thread factory. The "group" attribute specifies the thread group to
+ be used for threads created by this factory. The optional "daemon" attribute specifies whether
+ threads created by this factory should be forced to be daemon threads, or forced to be non-daemon
+ threads (not specifying this attribute will cause the thread group to inherit the daemon status from
+ its group). The optional "initial-priority" attribute may be used to specify the thread priority of
+ created threads.
+
+ One nested "exception-handler" tag may be used to specify an uncaught exception handler for the
+ thread factory. One or more "interrupt-handler" tags may be used to specify beans which need to be
+ notified when a thread from this factory has been interrupted.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="exception-handler" type="exception-handler" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="interrupt-handler" type="interrupt-handler" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="group" type="xsd:string" use="required"/>
+ <xsd:attribute name="daemon" type="xsd:boolean" use="optional"/>
+ <xsd:attribute name="thread-name-pattern" type="xsd:string" use="optional"/>
+ <xsd:attribute name="initial-priority" type="priority" use="optional"/>
+ </xsd:complexType>
+
+ <xsd:simpleType name="priority">
+ <xsd:annotation>
+ <xsd:documentation>
+ A priority which can range from 1 to 10 (inclusive). See <xhtml:a href="http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#setPriority(int)">Thread.setPriority(int)</xhtml:a> for more information.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:integer">
+ <xsd:minInclusive value="1"/>
+ <xsd:maxInclusive value="10"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:complexType name="thread-pool-executor">
+ <xsd:annotation>
+ <xsd:documentation>
+ A thread pool executor. The "name" attribute is the bean name of the created executor. The
+ "thread-factory" attribute specifies the bean name of the thread factory to use to create worker
+ threads. The nested "core-pool-size" element may be used to specify the core thread pool size.
+ The nested "max-pool-size" element may be used to specify the maximum thread pool size. The nested
+ "keepalive-time" is used to specify the amount of time that threads beyond the core pool size should
+ be kept running when idle. One of the "unbounded-queue", "bounded-queue", or "direct-queue" nested
+ elements may be specified to control the type of queue to use for tasks. The nested "reject-policy"
+ element may be used to specify how rejected tasks are handled.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="core-pool-size" type="pool-size" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="max-pool-size" type="pool-size" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="keepalive-time" type="time" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="reject-policy" type="reject-policy" minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string"/>
+ <xsd:attribute name="thread-factory" use="required" type="xsd:string"/>
+ <xsd:attribute name="allow-core-timeout" use="optional" type="xsd:boolean"/>
+ <xsd:attribute name="queue-length" use="optional" type="xsd:integer"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="direct-executor">
+ <xsd:annotation>
+ <xsd:documentation>
+ An executor that executes tasks in the caller's thread. The "name" attribute is the bean name of
+ the executor.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="notating-executor">
+ <xsd:annotation>
+ <xsd:documentation>
+ An executor which wraps another executor, and adds a notation to the name of a thread while that thread
+ is executing a task. The "name" attribute is the bean name of the created executor. The "parent"
+ attribute is the bean name of the executor to delegate tasks to. The "note" element specifies the text
+ that is to be added to the thread name while it executes the task.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="parent" type="xsd:string" use="required"/>
+ <xsd:attribute name="note" type="xsd:string" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="exception-handler">
+ <xsd:annotation>
+ <xsd:documentation>
+ A reference to an exception handler for a thread or executor. The referenced bean should implement
+ java.lang.Thread.UncaughtExceptionHandler.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="interrupt-handler">
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="pool-size">
+ <xsd:annotation>
+ <xsd:documentation>
+ A thread pool size designation. The "count" attribute specifies a flat number of threads. The
+ "per-cpu" attribute specifies a number of threads per CPU. The numbers are added and rounded off
+ to an integer number of threads.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="count" type="xsd:float" use="optional"/>
+ <xsd:attribute name="per-cpu" type="xsd:float" use="optional"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="time">
+ <xsd:annotation>
+ <xsd:documentation>
+ An amount of time. Comprised of a time value and a unit value.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="time" type="xsd:integer" use="required"/>
+ <xsd:attribute name="unit" type="time-unit-name" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="reject-policy">
+ <xsd:annotation>
+ <xsd:documentation>
+ Specify a task rejection policy for a thread pool executor. This is the action that is taken when
+ all threads are busy and the task queue is full for an executor. The "name" attribute specifies which
+ reject policy to use. The "executor-name" attribute is used to specify a handoff executor
+ for policies that involve passing the task to another executor, and is required when the reject policy
+ is set to "handoff".
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="reject-policy-name" use="required"/>
+ <xsd:attribute name="executor-name" type="xsd:string" use="optional"/>
+ </xsd:complexType>
+
+ <xsd:simpleType name="reject-policy-name">
+ <xsd:annotation>
+ <xsd:documentation>
+ The name of the policy. Possible values are "abort", "block", "caller-runs", "discard", "discard-oldest",
+ and "handoff".
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="abort">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[When a task cannot be accepted, a RejectedExecutionException is thrown.]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="block">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[Block until a task can be accepted. If the thread is interrupted while waiting, a RejectedExecutionException is thrown.]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="caller-runs">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[When a task connot be accepted, the calling thread runs the task.]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="discard">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[When a task cannot be accepted, the task is discarded.]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="discard-oldest">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[When a task cannot be accepted, the task which has been in the queue for the longest is discarded to make room.]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="handoff">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[When a task cannot be accepted, the task is handed off to another Executor whose name is given in the executor-name attribute.]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="time-unit-name">
+ <xsd:annotation>
+ <xsd:documentation>
+ The name of a unit of time.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string">
+
+ <xsd:enumeration value="s"/>
+ <xsd:enumeration value="sec"/>
+ <xsd:enumeration value="seconds"/>
+
+ <xsd:enumeration value="m"/>
+ <xsd:enumeration value="min"/>
+ <xsd:enumeration value="minutes"/>
+
+ <xsd:enumeration value="ms"/>
+ <xsd:enumeration value="milliseconds"/>
+
+ <xsd:enumeration value="ns"/>
+ <xsd:enumeration value="nanoseconds"/>
+
+ <xsd:enumeration value="h"/>
+ <xsd:enumeration value="hours"/>
+
+ <xsd:enumeration value="d"/>
+ <xsd:enumeration value="days"/>
+
+ <xsd:enumeration value="w"/>
+ <xsd:enumeration value="weeks"/>
+
+ <xsd:enumeration value="mon"/>
+ <xsd:enumeration value="months"/>
+
+ </xsd:restriction>
+ </xsd:simpleType>
+
+</xsd:schema>
\ No newline at end of file
Added: projects/jboss-threads/trunk/main/pom.xml
===================================================================
--- projects/jboss-threads/trunk/main/pom.xml (rev 0)
+++ projects/jboss-threads/trunk/main/pom.xml 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,33 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.jboss.threads</groupId>
+ <artifactId>threads</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0.0.CR1</version>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ <finalName>jboss-threads</finalName>
+ </build>
+</project>
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ArrayQueue.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ArrayQueue.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ArrayQueue.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,137 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.AbstractQueue;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.Arrays;
+import java.util.ConcurrentModificationException;
+
+/**
+ * A simple array-backed queue with a fixed size.
+ */
+public final class ArrayQueue<E> extends AbstractQueue<E> implements Queue<E> {
+ private final E[] elements;
+ // elements are added at head
+ private int head;
+ // elements are removed at tail
+ private int tail;
+ private int modCnt;
+
+ @SuppressWarnings({ "unchecked" })
+ public ArrayQueue(final int capacity) {
+ elements = (E[]) new Object[capacity];
+ }
+
+ public Iterator<E> iterator() {
+ return new Iterator<E>() {
+ private int pos = 0;
+ private int size = size();
+ private final int modIdx = modCnt;
+
+ public boolean hasNext() {
+ if (modCnt != modIdx) {
+ throw new ConcurrentModificationException();
+ }
+ return pos < size;
+ }
+
+ public E next() {
+ if (modCnt != modIdx) {
+ throw new ConcurrentModificationException();
+ }
+ final int pos = this.pos;
+ if (pos >= size) {
+ throw new NoSuchElementException();
+ }
+ final E[] elements = ArrayQueue.this.elements;
+ final E value = elements[(tail + pos) % elements.length];
+ this.pos = pos + 1;
+ return value;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ public boolean isEmpty() {
+ return elements[tail] == null;
+ }
+
+ public int size() {
+ final int head = this.head;
+ final int tail = this.tail;
+ final E[] elements = this.elements;
+ if (elements[tail] == null) {
+ return 0;
+ } else if (head > tail) {
+ return head - tail;
+ } else {
+ return head + elements.length - tail;
+ }
+ }
+
+ public boolean offer(final E e) {
+ if (e == null) {
+ throw new NullPointerException("e is null");
+ }
+ final int head = this.head;
+ final E[] elements = this.elements;
+ final int len = elements.length;
+ if (elements[head] != null) {
+ return false;
+ } else {
+ elements[head] = e;
+ this.head = (head + 1) % len;
+ modCnt++;
+ return true;
+ }
+ }
+
+ public E poll() {
+ final int tail = this.tail;
+ final E[] elements = this.elements;
+ final E value = elements[tail];
+ if (value != null) {
+ modCnt++;
+ elements[tail] = null;
+ this.tail = (tail + 1) % elements.length;
+ }
+ return value;
+ }
+
+ public E peek() {
+ final int tail = this.tail;
+ return tail == -1 ? null : elements[tail];
+ }
+
+ public void clear() {
+ Arrays.fill(elements, null);
+ modCnt++;
+ tail = head = 0;
+ }
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DirectExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DirectExecutor.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DirectExecutor.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.concurrent.Executor;
+
+/**
+ * A direct executor. Such an executor is required to run the given task in the current thread rather than
+ * delegate to a thread pool.
+ */
+public interface DirectExecutor extends Executor {
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DirectExecutorService.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DirectExecutorService.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DirectExecutorService.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * A direct executor service. Such an executor service is required to run the given task in the current thread rather than
+ * delegate to a thread pool.
+ */
+public interface DirectExecutorService extends DirectExecutor, ExecutorService {
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/InterruptHandler.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/InterruptHandler.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/InterruptHandler.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+/**
+ * A thread interrupt handler. Called when a thread's {@code interrupt()} method is invoked. The handler should
+ * not throw an exception; otherwise user code might end up in an unexpected state.
+ */
+public interface InterruptHandler {
+
+ /**
+ * Handle an interrupt condition on the given thread. This method should not throw an exception.
+ *
+ * @param thread the thread which was interrupted
+ */
+ void handleInterrupt(Thread thread);
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossExecutors.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossExecutors.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossExecutors.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,358 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ThreadFactory;
+import java.security.PrivilegedAction;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+
+/**
+ *
+ */
+public final class JBossExecutors {
+
+ private JBossExecutors() {}
+
+ private static final DirectExecutor DIRECT_EXECUTOR = new DirectExecutor() {
+ public void execute(final Runnable command) {
+ command.run();
+ }
+ };
+
+ private static final DirectExecutor REJECTING_EXECUTOR = new DirectExecutor() {
+ public void execute(final Runnable command) {
+ throw new RejectedExecutionException();
+ }
+ };
+
+ private static final DirectExecutor DISCARDING_EXECUTOR = new DirectExecutor() {
+ public void execute(final Runnable command) {
+ // nothing
+ }
+ };
+
+ private static final DirectExecutorService DIRECT_EXECUTOR_SERVICE = new ProtectedDirectExecutorService(DIRECT_EXECUTOR);
+ private static final DirectExecutorService REJECTING_EXECUTOR_SERVICE = new ProtectedDirectExecutorService(REJECTING_EXECUTOR);
+ private static final DirectExecutorService DISCARDING_EXECUTOR_SERVICE = new ProtectedDirectExecutorService(DISCARDING_EXECUTOR);
+
+ /**
+ * Get the direct executor. This executor will immediately run any task it is given, and propagate back any
+ * run-time exceptions thrown.
+ *
+ * @return the direct executor instance
+ */
+ public static DirectExecutor directExecutor() {
+ return DIRECT_EXECUTOR;
+ }
+
+ /**
+ * Get the direct executor service. This executor will immediately run any task it is given, and propagate back any
+ * run-time exceptions thrown. It cannot be shut down.
+ *
+ * @return the direct executor service instance
+ */
+ public static DirectExecutorService directExecutorService() {
+ return DIRECT_EXECUTOR_SERVICE;
+ }
+
+ /**
+ * Get the rejecting executor. This executor will reject any task submitted to it.
+ *
+ * @return the rejecting executor instance
+ */
+ public static DirectExecutor rejectingExecutor() {
+ return REJECTING_EXECUTOR;
+ }
+
+ /**
+ * Get the rejecting executor service. This executor will reject any task submitted to it. It cannot be shut down.
+ *
+ * @return the rejecting executor service instance
+ */
+ public static DirectExecutorService rejectingExecutorService() {
+ return REJECTING_EXECUTOR_SERVICE;
+ }
+
+ /**
+ * Get the discarding executor. This executor will silently discard any task submitted to it.
+ *
+ * @return the discarding executor instance
+ */
+ public static DirectExecutor discardingExecutor() {
+ return DISCARDING_EXECUTOR;
+ }
+
+ /**
+ * Get the discarding executor service. This executor will silently discard any task submitted to it. It cannot
+ * be shut down.
+ *
+ * @return the discarding executor service instance
+ */
+ public static DirectExecutorService discardingExecutorService() {
+ return DISCARDING_EXECUTOR_SERVICE;
+ }
+
+ /**
+ * Get a task that runs the given task through the given direct executor.
+ *
+ * @param executor the executor to run the task through
+ * @param task the task to run
+ * @return an encapsulating task
+ */
+ public static Runnable executorTask(final DirectExecutor executor, final Runnable task) {
+ return new Runnable() {
+ public void run() {
+ executor.execute(task);
+ }
+ };
+ }
+
+ /**
+ * An executor which delegates to another executor, wrapping each task in a task wrapper.
+ *
+ * @param delegate the delegate executor
+ * @param taskWrapper the task wrapper
+ * @return a wrapping executor
+ */
+ public static Executor wrappingExecutor(final Executor delegate, final DirectExecutor taskWrapper) {
+ return new Executor() {
+ public void execute(final Runnable command) {
+ delegate.execute(executorTask(taskWrapper, command));
+ }
+ };
+ }
+
+ /**
+ * Create a direct executor which runs with the privileges given by the supplied {@code AccessControlContext} instance.
+ *
+ * @param delegate the executor to delegate to at the privileged level
+ * @param context the {@code AccessControlContext} to use
+ * @return the new direct executor
+ */
+ public static DirectExecutor privilegedExecutor(final DirectExecutor delegate, final AccessControlContext context) {
+ return new DirectExecutor() {
+ public void execute(final Runnable command) {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ delegate.execute(command);
+ return null;
+ }
+ }, context);
+ } else {
+ delegate.execute(command);
+ }
+ }
+ };
+ }
+
+ /**
+ * Create a direct executor which runs tasks with the given context class loader.
+ *
+ * @param delegate the executor to delegate to
+ * @param taskClassLoader the context class loader to use
+ * @return the new direct executor
+ */
+ public static DirectExecutor contextClassLoaderExecutor(final DirectExecutor delegate, final ClassLoader taskClassLoader) {
+ return new DirectExecutor() {
+ public void execute(final Runnable command) {
+ final Thread thr = Thread.currentThread();
+ ClassLoader old = thr.getContextClassLoader();
+ thr.setContextClassLoader(taskClassLoader);
+ try {
+ delegate.execute(command);
+ } finally {
+ thr.setContextClassLoader(old);
+ }
+ }
+ };
+ }
+
+ /**
+ * Create a direct executor which changes the thread name for the duration of a task.
+ *
+ * @param delegate the executor to delegate to
+ * @param newName the thread name to use
+ * @return the new direct executor
+ */
+ public static DirectExecutor threadNameExecutor(final DirectExecutor delegate, final String newName) {
+ return new DirectExecutor() {
+ public void execute(final Runnable command) {
+ final Thread thr = Thread.currentThread();
+ final String oldName = thr.getName();
+ thr.setName(newName);
+ try {
+ delegate.execute(command);
+ } finally {
+ thr.setName(oldName);
+ }
+ }
+ };
+ }
+
+ /**
+ * Create a direct executor which adds a note to the thread name for the duration of a task.
+ *
+ * @param delegate the executor to delegate to
+ * @param notation the note to use
+ * @return the new direct executor
+ */
+ public static DirectExecutor threadNameNotateExecutor(final DirectExecutor delegate, final String notation) {
+ return new DirectExecutor() {
+ public void execute(final Runnable command) {
+ final Thread thr = Thread.currentThread();
+ final String oldName;
+ oldName = thr.getName();
+ thr.setName(oldName + " (" + notation + ')');
+ try {
+ delegate.execute(command);
+ } finally {
+ thr.setName(oldName);
+ }
+ }
+ };
+ }
+
+ /**
+ * Create a direct executor which consumes and logs errors that are thrown.
+ *
+ * @param delegate the executor to delegate to
+ * @param log the logger to which exceptions are written at the {@code error} level
+ * @return the new direct executor
+ */
+ public static DirectExecutor exceptionLoggingExecutor(final DirectExecutor delegate, final Object log) {
+ return new DirectExecutor() {
+ public void execute(final Runnable command) {
+ try {
+ delegate.execute(command);
+ } catch (Throwable t) {
+ // todo log it
+ // log.error(t, "Exception thrown from thread task");
+ }
+ }
+ };
+ }
+
+ /**
+ * Create an executor that executes each task in a new thread.
+ *
+ * @param factory the thread factory to use
+ * @return the executor
+ */
+ public static Executor threadFactoryExecutor(final ThreadFactory factory) {
+ return new Executor() {
+ public void execute(final Runnable command) {
+ factory.newThread(command).start();
+ }
+ };
+ }
+
+ private static final RejectedExecutionHandler ABORT_POLICY = new ThreadPoolExecutor.AbortPolicy();
+ private static final RejectedExecutionHandler CALLER_RUNS_POLICY = new ThreadPoolExecutor.CallerRunsPolicy();
+ private static final RejectedExecutionHandler DISCARD_OLDEST_POLICY = new ThreadPoolExecutor.DiscardOldestPolicy();
+ private static final RejectedExecutionHandler DISCARD_POLICY = new ThreadPoolExecutor.DiscardPolicy();
+
+ /**
+ * Get the abort policy for a {@link java.util.concurrent.ThreadPoolExecutor}.
+ *
+ * @return the abort policy
+ * @see java.util.concurrent.ThreadPoolExecutor.AbortPolicy
+ */
+ public static RejectedExecutionHandler abortPolicy() {
+ return ABORT_POLICY;
+ }
+
+ /**
+ * Get the caller-runs policy for a {@link java.util.concurrent.ThreadPoolExecutor}.
+ *
+ * @return the caller-runs policy
+ * @see java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy
+ */
+ public static RejectedExecutionHandler callerRunsPolicy() {
+ return CALLER_RUNS_POLICY;
+ }
+
+ /**
+ * Get the discard-oldest policy for a {@link java.util.concurrent.ThreadPoolExecutor}.
+ *
+ * @return the discard-oldest policy
+ * @see java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy
+ */
+ public static RejectedExecutionHandler discardOldestPolicy() {
+ return DISCARD_OLDEST_POLICY;
+ }
+
+ /**
+ * Get the discard policy for a {@link java.util.concurrent.ThreadPoolExecutor}.
+ *
+ * @return the discard policy
+ * @see java.util.concurrent.ThreadPoolExecutor.DiscardPolicy
+ */
+ public static RejectedExecutionHandler discardPolicy() {
+ return DISCARD_POLICY;
+ }
+
+ /**
+ * Get a handoff policy for a {@link java.util.concurrent.ThreadPoolExecutor}. The returned instance will
+ * delegate to another executor in the event that the task is rejected.
+ *
+ * @param target the target executor
+ * @return the new handoff policy implementation
+ */
+ public static RejectedExecutionHandler handoffPolicy(final Executor target) {
+ return new RejectedExecutionHandler() {
+ public void rejectedExecution(final Runnable r, final ThreadPoolExecutor executor) {
+ target.execute(r);
+ }
+ };
+ }
+
+ /**
+ * Wrap an executor with an {@code ExecutorService} instance, which supports all the features of {@code ExecutorService}
+ * except for shutting down the executor.
+ *
+ * @param target the target executor
+ * @return the executor service
+ */
+ public static ExecutorService protectedExecutorService(final Executor target) {
+ return new ProtectedExecutorService(target);
+ }
+
+ /**
+ * Wrap a direct executor with an {@code DirectExecutorService} instance, which supports all the features of {@code ExecutorService}
+ * except for shutting down the executor.
+ *
+ * @param target the target executor
+ * @return the executor service
+ */
+ public static DirectExecutorService protectedDirectExecutorService(final DirectExecutor target) {
+ return new ProtectedDirectExecutorService(target);
+ }
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThread.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThread.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThread.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+/**
+ *
+ */
+public final class JBossThread extends Thread {
+ private final InterruptHandler[] interruptHandlers;
+
+ public JBossThread(final InterruptHandler[] handlers, final ThreadGroup group, final Runnable target, final String name, final long stackSize) {
+ super(group, target, name, stackSize);
+ interruptHandlers = handlers;
+ }
+
+ public JBossThread(final InterruptHandler[] handlers, final ThreadGroup group, final Runnable target, final String name) {
+ super(group, target, name);
+ interruptHandlers = handlers;
+ }
+
+ public void interrupt() {
+ try {
+ super.interrupt();
+ } finally {
+ if (interruptHandlers != null) {
+ for (InterruptHandler interruptHandler : interruptHandlers) try {
+ interruptHandler.handleInterrupt(this);
+ } catch (Throwable t) {
+ // must ignore
+ }
+ }
+ }
+ }
+
+ public void run() {
+ // todo log start
+ try {
+ super.run();
+ } finally {
+ // todo log end
+ }
+ }
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadFactory.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadFactory.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadFactory.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,215 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ *
+ */
+public final class JBossThreadFactory implements ThreadFactory {
+ private final ThreadGroup threadGroup;
+ private final Boolean daemon;
+ private final Integer initialPriority;
+ private final List<Appender> nameAppenderList;
+ private final InterruptHandler[] interruptHandlers;
+ private final Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
+ private final Long stackSize;
+
+ private final AtomicLong factoryThreadIndexSequence = new AtomicLong(1L);
+
+ private final long factoryIndex;
+
+ private static final AtomicLong globalThreadIndexSequence = new AtomicLong(1L);
+ private static final AtomicLong factoryIndexSequence = new AtomicLong(1L);
+
+ private static final Appender globalThreadIndexAppender = new Appender() {
+ public void appendTo(final StringBuilder target, final ThreadSequenceInfo info) {
+ target.append(info.getGlobalThreadNum());
+ }
+ };
+ private static final Appender factoryIndexAppender = new Appender() {
+ public void appendTo(final StringBuilder target, final ThreadSequenceInfo info) {
+ target.append(info.getFactoryNum());
+ }
+ };
+ private static final Appender perFactoryThreadIndexAppender = new Appender() {
+ public void appendTo(final StringBuilder target, final ThreadSequenceInfo info) {
+ target.append(info.getPerFactoryThreadNum());
+ }
+ };
+ private static final Appender percentAppender = new Appender() {
+ public void appendTo(final StringBuilder target, final ThreadSequenceInfo info) {
+ target.append('%');
+ }
+ };
+ private final Appender groupPathAppender;
+
+ private static void appendParent(ThreadGroup group, StringBuilder builder) {
+ final ThreadGroup parent = group.getParent();
+ if (parent != null) {
+ appendParent(parent, builder);
+ builder.append(':');
+ }
+ builder.append(group.getName());
+ }
+
+ public JBossThreadFactory(ThreadGroup threadGroup, final Boolean daemon, final Integer initialPriority, String namePattern, final InterruptHandler[] interruptHandlers, final Thread.UncaughtExceptionHandler uncaughtExceptionHandler, final Long stackSize) {
+ if (threadGroup == null) {
+ final SecurityManager sm = System.getSecurityManager();
+ threadGroup = sm != null ? sm.getThreadGroup() : Thread.currentThread().getThreadGroup();
+ }
+ this.threadGroup = threadGroup;
+ this.daemon = daemon;
+ this.initialPriority = initialPriority;
+ this.uncaughtExceptionHandler = uncaughtExceptionHandler;
+ this.interruptHandlers = interruptHandlers;
+ this.stackSize = stackSize;
+ final StringBuilder builder = new StringBuilder();
+ appendParent(threadGroup, builder);
+ final String groupPath = builder.toString();
+ groupPathAppender = new StringAppender(groupPath);
+
+ factoryIndex = factoryIndexSequence.getAndIncrement();
+ if (namePattern == null) {
+ namePattern = "pool-%f-thread-%t";
+ }
+ List<Appender> appenders = new ArrayList<Appender>();
+ final int len = namePattern.length();
+ for (int i = 0;; ) {
+ final int n = namePattern.indexOf('%', i);
+ if (n == -1) {
+ if (i < len) {
+ appenders.add(new StringAppender(namePattern.substring(i)));
+ }
+ break;
+ }
+ if (n > i) {
+ appenders.add(new StringAppender(namePattern.substring(i, n)));
+ }
+ if (n >= len - 1) {
+ break;
+ }
+ final char c = namePattern.charAt(n + 1);
+ switch (c) {
+ case 't': {
+ appenders.add(perFactoryThreadIndexAppender);
+ break;
+ }
+ case 'g': {
+ appenders.add(globalThreadIndexAppender);
+ break;
+ }
+ case 'f': {
+ appenders.add(factoryIndexAppender);
+ break;
+ }
+ case 'p': {
+ appenders.add(groupPathAppender);
+ break;
+ }
+ case '%': {
+ appenders.add(percentAppender);
+ break;
+ }
+ }
+ i = n + 2;
+ }
+ nameAppenderList = appenders;
+ }
+
+ public Thread newThread(final Runnable target) {
+ return AccessController.doPrivileged(new ThreadCreateAction(target));
+ }
+
+ private final class ThreadCreateAction implements PrivilegedAction<Thread> {
+ private final Runnable target;
+
+ private ThreadCreateAction(final Runnable target) {
+ this.target = target;
+ }
+
+ public Thread run() {
+ final JBossThread thread;
+ final ThreadSequenceInfo info = new ThreadSequenceInfo(globalThreadIndexSequence.getAndIncrement(), factoryThreadIndexSequence.getAndIncrement(), factoryIndex);
+ final StringBuilder nameBuilder = new StringBuilder();
+ for (Appender appender : nameAppenderList) {
+ appender.appendTo(nameBuilder, info);
+ }
+ if (stackSize != null) {
+ thread = new JBossThread(interruptHandlers, threadGroup, target, nameBuilder.toString(), stackSize.longValue());
+ } else {
+ thread = new JBossThread(interruptHandlers, threadGroup, target, nameBuilder.toString());
+ }
+ if (initialPriority != null) thread.setPriority(initialPriority.intValue());
+ if (daemon != null) thread.setDaemon(daemon.booleanValue());
+ if (uncaughtExceptionHandler != null) thread.setUncaughtExceptionHandler(uncaughtExceptionHandler);
+ return thread;
+ }
+ }
+
+ private static final class StringAppender implements Appender {
+ private final String string;
+
+ private StringAppender(final String string) {
+ this.string = string;
+ }
+
+ public void appendTo(final StringBuilder target, final ThreadSequenceInfo info) {
+ target.append(string);
+ }
+ }
+
+ private static final class ThreadSequenceInfo {
+ private final long globalThreadNum;
+ private final long perFactoryThreadNum;
+ private final long factoryNum;
+
+ private ThreadSequenceInfo(final long globalThreadNum, final long perFactoryThreadNum, final long factoryNum) {
+ this.globalThreadNum = globalThreadNum;
+ this.perFactoryThreadNum = perFactoryThreadNum;
+ this.factoryNum = factoryNum;
+ }
+
+ public long getGlobalThreadNum() {
+ return globalThreadNum;
+ }
+
+ public long getPerFactoryThreadNum() {
+ return perFactoryThreadNum;
+ }
+
+ public long getFactoryNum() {
+ return factoryNum;
+ }
+ }
+
+ private interface Appender {
+ void appendTo(StringBuilder target, ThreadSequenceInfo info);
+ }
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadPoolExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadPoolExecutor.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadPoolExecutor.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,74 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.RejectedExecutionHandler;
+
+/**
+ *
+ */
+public final class JBossThreadPoolExecutor extends ThreadPoolExecutor {
+
+ public JBossThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
+ }
+
+ public JBossThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
+ }
+
+ public JBossThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
+ }
+
+ public JBossThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
+ }
+
+ public void stop() {
+ shutdown();
+ try {
+ awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ // todo log if fails?
+ } catch (InterruptedException e) {
+ // todo log it?
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ public void destroy() {
+ // todo is this the right behavior?
+ shutdownNow();
+ try {
+ awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ // todo log if fails?
+ } catch (InterruptedException e) {
+ // todo log it?
+ Thread.currentThread().interrupt();
+ }
+ }
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/OrderedExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/OrderedExecutor.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/OrderedExecutor.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,183 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.Condition;
+
+/**
+ * An executor that always runs all tasks in queue order, using a delegate executor to run the tasks.
+ * <p/>
+ * More specifically, if a FIFO queue type is used, any call B to the {@link #execute(Runnable)} method that
+ * happens-after another call A to the same method, will result in B's task running after A's.
+ */
+public final class OrderedExecutor implements Executor {
+
+ private final Executor parent;
+ private final Runnable runner = new Runner();
+ private final Lock lock = new ReentrantLock();
+ private final Condition removeCondition = lock.newCondition();
+ // @protectedby lock
+ private final Queue<Runnable> queue;
+ // @protectedby lock
+ private boolean running;
+ // @protectedby lock
+ private RejectionPolicy policy;
+ // @protectedby lock
+ private Executor handoffExecutor;
+
+ /**
+ * Construct a new instance using an unbounded FIFO queue. Since the queue is unbounded, tasks are never
+ * rejected.
+ *
+ * @param parent the parent to delegate tasks to
+ */
+ public OrderedExecutor(final Executor parent) {
+ this(parent, RejectionPolicy.BLOCK, null);
+ }
+
+ /**
+ * Construct a new instance using the given queue and a blocking reject policy.
+ *
+ * @param parent the parent to delegate tasks to
+ * @param queue the queue to use to hold tasks
+ */
+ public OrderedExecutor(final Executor parent, final Queue<Runnable> queue) {
+ this(parent, queue, RejectionPolicy.BLOCK, null);
+ }
+
+ /**
+ * Construct a new instance using an unbounded FIFO queue.
+ *
+ * @param parent the parent executor
+ * @param policy the task rejection policy
+ * @param handoffExecutor the executor to hand tasks to if the queue is full
+ */
+ public OrderedExecutor(final Executor parent, final RejectionPolicy policy, final Executor handoffExecutor) {
+ this(parent, new LinkedList<Runnable>(), policy, handoffExecutor);
+ }
+
+ /**
+ * Construct a new instance.
+ *
+ * @param parent the parent executor
+ * @param queue the task queue to use
+ * @param policy the task rejection policy
+ * @param handoffExecutor the executor to hand tasks to if the queue is full
+ */
+ public OrderedExecutor(final Executor parent, final Queue<Runnable> queue, final RejectionPolicy policy, final Executor handoffExecutor) {
+ if (parent == null) {
+ throw new NullPointerException("parent is null");
+ }
+ if (queue == null) {
+ throw new NullPointerException("queue is null");
+ }
+ if (policy == null) {
+ throw new NullPointerException("policy is null");
+ }
+ if (policy == RejectionPolicy.HANDOFF && handoffExecutor == null) {
+ throw new NullPointerException("handoffExecutor is null");
+ }
+ this.queue = queue;
+ this.parent = parent;
+ this.policy = policy;
+ this.handoffExecutor = handoffExecutor;
+ }
+
+ /**
+ * Run a task.
+ *
+ * @param command the task to run.
+ */
+ public void execute(Runnable command) {
+ try {
+ lock.lockInterruptibly();
+ try {
+ while (! queue.offer(command)) {
+ switch (policy) {
+ case ABORT:
+ throw new RejectedExecutionException();
+ case BLOCK:
+ removeCondition.await();
+ break;
+ case DISCARD:
+ return;
+ case DISCARD_OLDEST:
+ if (queue.poll() != null) {
+ queue.add(command);
+ }
+ break;
+ case HANDOFF:
+ handoffExecutor.execute(command);
+ return;
+ }
+ }
+ if (! running) {
+ running = true;
+ boolean ok = false;
+ try {
+ parent.execute(runner);
+ ok = true;
+ } finally {
+ if (! ok) {
+ running = false;
+ }
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+ } catch (InterruptedException e) {
+ throw new RejectedExecutionException();
+ }
+ }
+
+ private class Runner implements Runnable {
+ public void run() {
+ for (;;) {
+ final Runnable task;
+ lock.lock();
+ try {
+ task = queue.poll();
+ removeCondition.signal();
+ if (task == null) {
+ running = false;
+ return;
+ }
+ } finally {
+ lock.unlock();
+ }
+ try {
+ task.run();
+ } catch (Throwable t) {
+ // todo log?
+ }
+ }
+ }
+ }
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutor.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutor.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,34 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+/**
+ * A direct executor that simply delegates to another direct executor. Use instances of this class to hide extra methods on
+ * another executor.
+ */
+public class ProtectedDirectExecutor extends ProtectedExecutor implements DirectExecutor {
+
+ public ProtectedDirectExecutor(final DirectExecutor delegate) {
+ super(delegate);
+ }
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutorService.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutorService.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutorService.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+/**
+ * A {@code DirectExecutor} version of {@code ProtectedExecutorService}.
+ */
+public class ProtectedDirectExecutorService extends ProtectedExecutorService implements DirectExecutorService {
+ public ProtectedDirectExecutorService(final DirectExecutor delegate) {
+ super(delegate);
+ }
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,46 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.concurrent.Executor;
+
+/**
+ * An executor that simply delegates to another executor. Use instances of this class to hide extra methods on
+ * another executor.
+ */
+public class ProtectedExecutor implements Executor {
+ private final Executor delegate;
+
+ public ProtectedExecutor(final Executor delegate) {
+ this.delegate = delegate;
+ }
+
+ /**
+ * Execute a task by passing it to the delegate executor.
+ *
+ * @param command the task
+ */
+ public void execute(final Runnable command) {
+ delegate.execute(command);
+ }
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutorService.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutorService.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutorService.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.Executor;
+import java.util.List;
+
+/**
+ * An implementation of {@code ExecutorService} that delegates to the real executor, while disallowing termination.
+ */
+public class ProtectedExecutorService extends AbstractExecutorService implements ExecutorService {
+ private final Executor delegate;
+
+ public ProtectedExecutorService(final Executor delegate) {
+ this.delegate = delegate;
+ }
+
+ public void execute(final Runnable command) {
+ delegate.execute(command);
+ }
+
+ public boolean isShutdown() {
+ // container managed executors are never shut down from the application's perspective
+ return false;
+ }
+
+ public boolean isTerminated() {
+ // container managed executors are never shut down from the application's perspective
+ return false;
+ }
+
+ public boolean awaitTermination(final long timeout, final TimeUnit unit) throws InterruptedException {
+ unit.sleep(timeout);
+ return false;
+ }
+
+ public void shutdown() {
+ throw new SecurityException("shutdown() not allowed on container-managed executor");
+ }
+
+ public List<Runnable> shutdownNow() {
+ throw new SecurityException("shutdownNow() not allowed on container-managed executor");
+ }
+
+ public static ExecutorService directExecutorService() {
+ return new ProtectedExecutorService(JBossExecutors.directExecutor());
+ }
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/RejectionPolicy.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/RejectionPolicy.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/RejectionPolicy.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+/**
+ * Specify the way a task rejection should be handled.
+ */
+public enum RejectionPolicy {
+
+ /**
+ * Abort execution with an exception.
+ */
+ ABORT,
+ /**
+ * Wait until there is room in the queue, or the calling thread is interrupted.
+ */
+ BLOCK,
+ /**
+ * Discard the excess task silently.
+ */
+ DISCARD,
+ /**
+ * Discard the oldest task in the queue silently, and enqueue the new task. If the queue has no capacity
+ * then the new task will be discarded.
+ */
+ DISCARD_OLDEST,
+ /**
+ * Hand off the task to another executor.
+ */
+ HANDOFF,
+}
Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/SimpleQueueExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/SimpleQueueExecutor.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/SimpleQueueExecutor.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,556 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.ExecutorService;
+import java.util.Queue;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * An executor which uses a regular queue to hold tasks. The executor may be tuned at runtime in many ways.
+ */
+public final class SimpleQueueExecutor extends AbstractExecutorService implements ExecutorService {
+ private final Lock lock = new ReentrantLock();
+ // signal when a task is written to the queue
+ private final Condition enqueueCondition = lock.newCondition();
+ // signal when the queue is read
+ private final Condition removeCondition = lock.newCondition();
+ // signalled when threads terminate
+ private final Condition threadExitCondition = lock.newCondition();
+ private final ThreadFactory threadFactory;
+
+ // all protected by poolLock...
+ private int coreThreadLimit;
+ private int maxThreadLimit;
+ private boolean allowCoreThreadTimeout;
+ private long keepAliveTime;
+ private TimeUnit keepAliveTimeUnit;
+ private RejectionPolicy rejectionPolicy;
+ private Executor handoffExecutor;
+
+ private int threadCount;
+ private Set<Thread> workers = new HashSet<Thread>();
+
+ private boolean stop;
+ private boolean interrupt;
+
+ private Queue<Runnable> queue;
+
+ public SimpleQueueExecutor(final int coreThreadLimit, final int maxThreadLimit, final long keepAliveTime, final TimeUnit keepAliveTimeUnit, final Queue<Runnable> queue, final ThreadFactory threadFactory, final RejectionPolicy rejectionPolicy, final Executor handoffExecutor) {
+ if (threadFactory == null) {
+ throw new NullPointerException("threadFactory is null");
+ }
+ if (queue == null) {
+ throw new NullPointerException("queue is null");
+ }
+ if (keepAliveTimeUnit == null) {
+ throw new NullPointerException("keepAliveTimeUnit is null");
+ }
+ if (rejectionPolicy == null) {
+ throw new NullPointerException("rejectionPolicy is null");
+ }
+ if (rejectionPolicy == RejectionPolicy.HANDOFF && handoffExecutor == null) {
+ throw new NullPointerException("handoffExecutor is null");
+ }
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ this.threadFactory = threadFactory;
+ // configurable...
+ this.keepAliveTime = keepAliveTime;
+ this.keepAliveTimeUnit = keepAliveTimeUnit;
+ this.coreThreadLimit = coreThreadLimit;
+ this.maxThreadLimit = maxThreadLimit;
+ this.queue = queue;
+ this.rejectionPolicy = rejectionPolicy;
+ this.handoffExecutor = handoffExecutor;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void execute(final Runnable task) throws RejectedExecutionException {
+ final Lock lock = this.lock;
+ try {
+ lock.lockInterruptibly();
+ try {
+ for (;;) {
+ if (stop) {
+ throw new RejectedExecutionException("Executor is stopped");
+ }
+ // Try core thread first, then queue, then extra thread
+ final int count = threadCount;
+ if (count < coreThreadLimit) {
+ startNewThread(task);
+ threadCount = count + 1;
+ return;
+ }
+ // next queue...
+ final Queue<Runnable> queue = this.queue;
+ if (queue.offer(task)) {
+ enqueueCondition.signal();
+ return;
+ }
+ // extra threads?
+ if (count < maxThreadLimit) {
+ startNewThread(task);
+ threadCount = count + 1;
+ return;
+ }
+ // how to reject the task...
+ switch (rejectionPolicy) {
+ case ABORT:
+ throw new RejectedExecutionException("Executor is busy");
+ case BLOCK:
+ removeCondition.await();
+ break;
+ case DISCARD:
+ return;
+ case DISCARD_OLDEST:
+ if (queue.poll() != null) {
+ queue.add(task);
+ enqueueCondition.signal();
+ }
+ return;
+ case HANDOFF:
+ handoffExecutor.execute(task);
+ return;
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RejectedExecutionException("Thread interrupted");
+ }
+ }
+
+ public void shutdown() {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ if (! stop) {
+ stop = true;
+ // wake up the whole town
+ removeCondition.signalAll();
+ enqueueCondition.signalAll();
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public List<Runnable> shutdownNow() {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ stop = true;
+ interrupt = true;
+ removeCondition.signalAll();
+ enqueueCondition.signalAll();
+ for (Thread worker : workers) {
+ worker.interrupt();
+ }
+ final Queue<Runnable> queue = this.queue;
+ final ArrayList<Runnable> list = new ArrayList<Runnable>(queue);
+ queue.clear();
+ return list;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public boolean isShutdown() {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ return stop;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public boolean isTerminated() {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ return stop && threadCount == 0;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public boolean awaitTermination(final long timeout, final TimeUnit unit) throws InterruptedException {
+ final Lock lock = this.lock;
+ lock.lockInterruptibly();
+ try {
+ final long start = System.currentTimeMillis();
+ long elapsed = 0L;
+ while (! stop && threadCount > 0) {
+ final long remaining = timeout - elapsed;
+ if (remaining <= 0) {
+ return false;
+ }
+ threadExitCondition.await(remaining, unit);
+ elapsed = unit.convert(System.currentTimeMillis() - start, TimeUnit.MILLISECONDS);
+ }
+ return true;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public boolean isAllowCoreThreadTimeout() {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ return allowCoreThreadTimeout;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void setAllowCoreThreadTimeout(boolean allowCoreThreadTimeout) {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ this.allowCoreThreadTimeout = allowCoreThreadTimeout;
+ if (allowCoreThreadTimeout) {
+ // wake everyone up so core threads can time out
+ enqueueCondition.signalAll();
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public int getCoreThreadLimit() {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ return coreThreadLimit;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void setCoreThreadLimit(final int coreThreadLimit) {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ final int oldLimit = this.coreThreadLimit;
+ if (maxThreadLimit < coreThreadLimit) {
+ // don't let the max thread limit be less than the core thread limit.
+ // the called method will signal as needed
+ setMaxThreadLimit(coreThreadLimit);
+ } else if (oldLimit < coreThreadLimit) {
+ // we're growing the number of core threads
+ // therefore signal anyone waiting to add tasks; there might be more threads to add
+ removeCondition.signalAll();
+ } else if (oldLimit > coreThreadLimit) {
+ // we're shrinking the number of core threads
+ // therefore signal anyone waiting to remove tasks so the pool can shrink properly
+ enqueueCondition.signalAll();
+ } else {
+ // we aren't changing anything...
+ return;
+ }
+ this.coreThreadLimit = coreThreadLimit;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public int getMaxThreadLimit() {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ return maxThreadLimit;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void setMaxThreadLimit(final int maxThreadLimit) {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ final int oldLimit = this.maxThreadLimit;
+ if (maxThreadLimit < coreThreadLimit) {
+ // don't let the max thread limit be less than the core thread limit.
+ // the called method will signal as needed
+ setCoreThreadLimit(maxThreadLimit);
+ } else if (oldLimit < maxThreadLimit) {
+ // we're growing the number of extra threads
+ // therefore signal anyone waiting to add tasks; there might be more threads to add
+ removeCondition.signalAll();
+ } else if (oldLimit > maxThreadLimit) {
+ // we're shrinking the number of extra threads
+ // therefore signal anyone waiting to remove tasks so the pool can shrink properly
+ enqueueCondition.signalAll();
+ } else {
+ // we aren't changing anything...
+ return;
+ }
+ this.maxThreadLimit = maxThreadLimit;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public long getKeepAliveTime() {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ return keepAliveTime;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public TimeUnit getKeepAliveTimeUnit() {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ return keepAliveTimeUnit;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void setKeepAliveTime(final long keepAliveTime, final TimeUnit keepAliveTimeUnit) {
+ if (keepAliveTimeUnit == null) {
+ throw new NullPointerException("keepAliveTimeUnit is null");
+ }
+ if (keepAliveTime < 0L) {
+ throw new IllegalArgumentException("keepAliveTime is less than zero");
+ }
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ this.keepAliveTime = keepAliveTime;
+ this.keepAliveTimeUnit = keepAliveTimeUnit;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public RejectionPolicy getRejectionPolicy() {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ return rejectionPolicy;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void setRejectionPolicy(final RejectionPolicy newPolicy, final Executor handoffExecutor) {
+ if (newPolicy == null) {
+ throw new NullPointerException("rejectionPolicy is null");
+ }
+ if (newPolicy == RejectionPolicy.HANDOFF && handoffExecutor == null) {
+ throw new NullPointerException("handoffExecutor is null");
+ }
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ if (rejectionPolicy == RejectionPolicy.BLOCK && newPolicy != RejectionPolicy.BLOCK) {
+ // there could be blocking .execute() calls out there; give them a nudge
+ removeCondition.signalAll();
+ }
+ rejectionPolicy = newPolicy;
+ this.handoffExecutor = handoffExecutor;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ // container lifecycle methods
+ public void stop() {
+ shutdown();
+ try {
+ awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ // todo log if fails?
+ } catch (InterruptedException e) {
+ // todo log it?
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ public void destroy() {
+ // todo is this the right behavior?
+ shutdownNow();
+ try {
+ awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ // todo log if fails?
+ } catch (InterruptedException e) {
+ // todo log it?
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ // call with lock held!
+ private void startNewThread(final Runnable task) {
+ final Thread thread = threadFactory.newThread(new Worker(task));
+ workers.add(thread);
+ thread.start();
+ }
+
+ // call with lock held!
+ private Runnable pollTask() {
+ final Runnable task = queue.poll();
+ if (task != null) {
+ removeCondition.signal();
+ return task;
+ } else {
+ if (-- threadCount == 0) {
+ threadExitCondition.signalAll();
+ }
+ return null;
+ }
+ }
+
+ // call with lock held!
+ private Runnable takeTask() {
+ final Condition removeCondition = this.removeCondition;
+ Runnable task = queue.poll();
+ if (task != null) {
+ removeCondition.signal();
+ return task;
+ } else {
+ final Condition enqueueCondition = this.enqueueCondition;
+ final long start = System.currentTimeMillis();
+ boolean intr = Thread.interrupted();
+ try {
+ long elapsed = 0L;
+ for (;;) {
+ // these parameters may change on each iteration
+ final int threadCount = this.threadCount;
+ final int coreThreadLimit = this.coreThreadLimit;
+ final boolean allowCoreThreadTimeout = this.allowCoreThreadTimeout;
+ if (stop || threadCount > maxThreadLimit) {
+ // too many threads. Handle a task if there is one, otherwise exit
+ return pollTask();
+ } else if (!allowCoreThreadTimeout && threadCount < coreThreadLimit) {
+ // ignore timeout until we are not a core thread or until core threads are allowed to time out
+ try {
+ enqueueCondition.await();
+ } catch (InterruptedException e) {
+ intr = true;
+ }
+ } else {
+ final TimeUnit timeUnit = keepAliveTimeUnit;
+ final long time = keepAliveTime;
+ final long remaining = time - timeUnit.convert(elapsed, TimeUnit.MILLISECONDS);
+ if (remaining <= 0L && (allowCoreThreadTimeout || threadCount > coreThreadLimit)) {
+ // the timeout has expired
+ return pollTask();
+ }
+ try {
+ enqueueCondition.await(remaining, timeUnit);
+ } catch (InterruptedException e) {
+ intr = true;
+ }
+ }
+ task = queue.poll();
+ if (task != null) {
+ removeCondition.signal();
+ return task;
+ }
+ elapsed = System.currentTimeMillis() - start;
+ }
+ } finally {
+ if (intr) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+ }
+
+ private class Worker implements Runnable {
+
+ private Runnable first;
+
+ public Worker(final Runnable command) {
+ first = command;
+ }
+
+ public void run() {
+ final Lock lock = SimpleQueueExecutor.this.lock;
+ Runnable task = first;
+ // Release reference to task
+ first = null;
+ lock.lock();
+ try {
+ for (;;) {
+ if (task != null) {
+ try {
+ if (interrupt) {
+ Thread.currentThread().interrupt();
+ }
+ lock.unlock();
+ try {
+ task.run();
+ } finally {
+ // this is OK because it's in the finally block after lock.unlock()
+ //noinspection LockAcquiredButNotSafelyReleased
+ lock.lock();
+ }
+ } catch (Throwable t) {
+ // todo - log the exception perhaps
+ }
+ // don't hang on to task while we possibly block down below
+ task = null;
+ }
+ if (stop) {
+ // drain queue
+ if ((task = pollTask()) == null) {
+ return;
+ }
+ } else {
+ // get next task
+ if ((task = takeTask()) == null) {
+ return;
+ }
+ }
+ }
+ } finally {
+ workers.remove(Thread.currentThread());
+ lock.unlock();
+ }
+ }
+ }
+}
Added: projects/jboss-threads/trunk/main/src/main/resources/META-INF/jboss-classloading.xml
===================================================================
--- projects/jboss-threads/trunk/main/src/main/resources/META-INF/jboss-classloading.xml (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/resources/META-INF/jboss-classloading.xml 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<classloading xmlns="urn:jboss:classloading:1.0" import-all="false">
+ <capabilities>
+ <module name="jboss-threads" version="1.0.0.CR1"/>
+ <package name="org.jboss.threads" version="1.0.0.CR1"/>
+ </capabilities>
+ <requirements/>
+</classloading>
Added: projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ArrayQueueTestCase.java
===================================================================
--- projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ArrayQueueTestCase.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ArrayQueueTestCase.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,86 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import junit.framework.TestCase;
+
+/**
+ *
+ */
+public final class ArrayQueueTestCase extends TestCase {
+
+ public void testBasic() {
+ final int max = 40;
+ final ArrayQueue<Object> queue = new ArrayQueue<Object>(max);
+ for (int i = 0; i < max; i ++) {
+ assertEquals("Size mismatch, iteration " + i, i, queue.size());
+ assertTrue("Iteration " + i, queue.offer(new Object()));
+ }
+ assertFalse("Queue took extra element", queue.offer(new Object()));
+ for (int i = 0; i < max; i ++) {
+ assertNotNull("Queue missing elements", queue.poll());
+ }
+ assertNull("Queue has extra elements", queue.poll());
+ }
+
+ public void testContents() {
+ final int max = 40;
+ final ArrayQueue<Object> queue = new ArrayQueue<Object>(max);
+ for (int cnt = 1; cnt < max; cnt ++) {
+ for (int i = 0; i < cnt; i ++) {
+ assertEquals("Size mismatch, iteration " + i, i, queue.size());
+ assertTrue("Queue won't take element, iteration " + cnt + "/" + i, queue.offer(new Integer(i)));
+ }
+ for (int i = 0; i < cnt; i ++) {
+ assertTrue("Missing int value, iteration " + cnt + "/" + i, queue.contains(new Integer(i)));
+ }
+ for (int i = 0; i < cnt; i ++) {
+ assertEquals("Size mismatch, iteration " + i, cnt - i, queue.size());
+ assertEquals("Wrong object value, iteration " + cnt + "/" + i, new Integer(i), queue.poll());
+ }
+ assertNull("Extra value, iteration " + cnt, queue.poll());
+ for (int i = 0; i < cnt; i ++) {
+ assertFalse("Nonremoved value, iteration " + cnt + "/" + i, queue.contains(new Integer(i)));
+ }
+ }
+ }
+
+ public void testClear() {
+ final int max = 40;
+ final ArrayQueue<Object> queue = new ArrayQueue<Object>(max);
+ for (int cnt = 1; cnt < max; cnt ++) {
+ for (int i = 0; i < cnt; i ++) {
+ assertEquals("Size mismatch, iteration " + i, i, queue.size());
+ assertTrue("Queue won't take element, iteration " + cnt + "/" + i, queue.offer(new Integer(i)));
+ }
+ for (int i = 0; i < cnt; i ++) {
+ assertTrue("Missing int value, iteration " + cnt + "/" + i, queue.contains(new Integer(i)));
+ }
+ queue.clear();
+ assertNull("Extra value, iteration " + cnt, queue.poll());
+ for (int i = 0; i < cnt; i ++) {
+ assertFalse("Nonremoved value, iteration " + cnt + "/" + i, queue.contains(new Integer(i)));
+ }
+ }
+ }
+}
Added: projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadFactoryTestCase.java
===================================================================
--- projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadFactoryTestCase.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadFactoryTestCase.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,126 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import junit.framework.TestCase;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ *
+ */
+public final class ThreadFactoryTestCase extends TestCase {
+ private static final NullRunnable NULL_RUNNABLE = new NullRunnable();
+
+ private static class NullRunnable implements Runnable {
+ public void run() {
+ }
+ }
+
+ private static void doTestNamePattern(JBossThreadFactory threadFactory, int expectedPerFactoryId, int expectedGlobalId, int expectedFactoryId) {
+ final String name = threadFactory.newThread(NULL_RUNNABLE).getName();
+ assertTrue("Wrong thread name (" + name + ") ", name.matches("-([a-z]+:)*one:two:three-%-" + expectedPerFactoryId + "-" + expectedGlobalId + "-" + expectedFactoryId + "-"));
+ }
+
+ /**
+ * This MUST be the first test, otherwise the sequence numbers will be wrong.
+ */
+ public void testNamePattern() {
+ // TODO - skip test for now since it depends on order.
+ if (true) return;
+ final JBossThreadFactory threadFactory1 = new JBossThreadFactory(new ThreadGroup(new ThreadGroup(new ThreadGroup("one"), "two"), "three"), null,
+ null, "-%p-%%-%t-%g-%f-", null, null, null);
+ doTestNamePattern(threadFactory1, 1, 1, 1);
+ doTestNamePattern(threadFactory1, 2, 2, 1);
+ doTestNamePattern(threadFactory1, 3, 3, 1);
+ final JBossThreadFactory threadFactory2 = new JBossThreadFactory(new ThreadGroup(new ThreadGroup(new ThreadGroup("one"), "two"), "three"), null,
+ null, "-%p-%%-%t-%g-%f-", null, null, null);
+ doTestNamePattern(threadFactory2, 1, 4, 2);
+ doTestNamePattern(threadFactory2, 2, 5, 2);
+ doTestNamePattern(threadFactory2, 3, 6, 2);
+ doTestNamePattern(threadFactory2, 4, 7, 2);
+ // back to the first factory...
+ doTestNamePattern(threadFactory1, 4, 8, 1);
+ }
+
+ public void testDaemon() {
+ final JBossThreadFactory threadFactory1 = new JBossThreadFactory(null, Boolean.TRUE, null, "%t", null, null, null);
+ assertTrue("Thread is not a daemon thread", threadFactory1.newThread(NULL_RUNNABLE).isDaemon());
+ final JBossThreadFactory threadFactory2 = new JBossThreadFactory(null, Boolean.FALSE, null, "%t", null, null, null);
+ assertFalse("Thread should not be a daemon thread", threadFactory2.newThread(NULL_RUNNABLE).isDaemon());
+ }
+
+ public void testInterruptHandler() throws InterruptedException {
+ final AtomicBoolean wasInterrupted = new AtomicBoolean();
+ final AtomicBoolean called = new AtomicBoolean();
+ final JBossThreadFactory threadFactory = new JBossThreadFactory(null, null, null, null, new InterruptHandler[] {
+ new InterruptHandler() {
+ public void handleInterrupt(final Thread thread) {
+ called.set(true);
+ }
+ }
+ }, null, null);
+ final Thread t = threadFactory.newThread(new Runnable() {
+ public void run() {
+ synchronized (this) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ wasInterrupted.set(true);
+ }
+ }
+ }
+ });
+ t.start();
+ t.interrupt();
+ t.join();
+ assertTrue("Was not interrupted", wasInterrupted.get());
+ assertTrue("Handler was not called", called.get());
+ }
+
+ public void testUncaughtHandler() throws InterruptedException {
+ final AtomicBoolean called = new AtomicBoolean();
+ final JBossThreadFactory factory = new JBossThreadFactory(null, null, null, null, null, new Thread.UncaughtExceptionHandler() {
+ public void uncaughtException(final Thread t, final Throwable e) {
+ called.set(true);
+ }
+ }, null);
+ final Thread t = factory.newThread(new Runnable() {
+ public void run() {
+ throw new RuntimeException("...");
+ }
+ });
+ t.start();
+ t.join();
+ assertTrue("Handler was not called", called.get());
+ }
+
+ public void testInitialPriority() {
+ assertEquals("Wrong initial thread priority", 1, new JBossThreadFactory(null, null, Integer.valueOf(1), null, null, null, null).newThread(NULL_RUNNABLE).getPriority());
+ assertEquals("Wrong initial thread priority", 2, new JBossThreadFactory(null, null, Integer.valueOf(2), null, null, null, null).newThread(NULL_RUNNABLE).getPriority());
+ final ThreadGroup grp = new ThreadGroup("blah");
+ grp.setMaxPriority(5);
+ assertEquals("Wrong initial thread priority", 5, new JBossThreadFactory(grp, null, Integer.valueOf(10), null, null, null, null).newThread(NULL_RUNNABLE).getPriority());
+ assertEquals("Wrong initial thread priority", 1, new JBossThreadFactory(grp, null, Integer.valueOf(1), null, null, null, null).newThread(NULL_RUNNABLE).getPriority());
+ }
+}
Added: projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadPoolTestCase.java
===================================================================
--- projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadPoolTestCase.java (rev 0)
+++ projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadPoolTestCase.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,157 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import junit.framework.TestCase;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.LinkedList;
+
+/**
+ *
+ */
+public final class ThreadPoolTestCase extends TestCase {
+
+ private final JBossThreadFactory threadFactory = new JBossThreadFactory(null, null, null, "test thread %p %t", null, null, null);
+
+ private static final class SimpleTask implements Runnable {
+
+ private final CountDownLatch taskUnfreezer;
+ private final CountDownLatch taskFinishLine;
+
+ private SimpleTask(final CountDownLatch taskUnfreezer, final CountDownLatch taskFinishLine) {
+ this.taskUnfreezer = taskUnfreezer;
+ this.taskFinishLine = taskFinishLine;
+ }
+
+ public void run() {
+ try {
+ assertTrue(taskUnfreezer.await(800L, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ fail("interrupted");
+ }
+ taskFinishLine.countDown();
+ }
+ }
+
+ public void testBasic() throws InterruptedException {
+ // Start some tasks, let them run, then shut down the executor
+ final int cnt = 100;
+ final CountDownLatch taskUnfreezer = new CountDownLatch(1);
+ final CountDownLatch taskFinishLine = new CountDownLatch(cnt);
+ final ExecutorService simpleQueueExecutor = new SimpleQueueExecutor(5, 5, 500L, TimeUnit.MILLISECONDS, new LinkedList<Runnable>(), threadFactory, RejectionPolicy.BLOCK, null);
+ for (int i = 0; i < cnt; i ++) {
+ simpleQueueExecutor.execute(new SimpleTask(taskUnfreezer, taskFinishLine));
+ }
+ taskUnfreezer.countDown();
+ final boolean finished = taskFinishLine.await(800L, TimeUnit.MILLISECONDS);
+ assertTrue(finished);
+ simpleQueueExecutor.shutdown();
+ try {
+ simpleQueueExecutor.execute(new Runnable() {
+ public void run() {
+ }
+ });
+ fail("Task not rejected after shutdown");
+ } catch (Throwable t) {
+ assertEquals(RejectedExecutionException.class, t.getClass());
+ }
+ assertTrue(simpleQueueExecutor.awaitTermination(800L, TimeUnit.MILLISECONDS));
+ }
+
+ public void testShutdownNow() throws InterruptedException {
+ final AtomicBoolean interrupted = new AtomicBoolean();
+ final AtomicBoolean ran = new AtomicBoolean();
+
+ final CountDownLatch startLatch = new CountDownLatch(1);
+ final ExecutorService simpleQueueExecutor = new SimpleQueueExecutor(5, 5, 500L, TimeUnit.MILLISECONDS, new LinkedList<Runnable>(), threadFactory, RejectionPolicy.BLOCK, null);
+ simpleQueueExecutor.execute(new Runnable() {
+ public void run() {
+ try {
+ ran.set(true);
+ startLatch.countDown();
+ Thread.sleep(5000L);
+ } catch (InterruptedException e) {
+ interrupted.set(true);
+ }
+ }
+ });
+ assertTrue("Task not started", startLatch.await(300L, TimeUnit.MILLISECONDS));
+ assertTrue("Task returned", simpleQueueExecutor.shutdownNow().isEmpty());
+ try {
+ simpleQueueExecutor.execute(new Runnable() {
+ public void run() {
+ }
+ });
+ fail("Task not rejected after shutdown");
+ } catch (RejectedExecutionException t) {
+ }
+ assertTrue("Executor not shut down in 800ms", simpleQueueExecutor.awaitTermination(800L, TimeUnit.MILLISECONDS));
+ assertTrue("Task wasn't run", ran.get());
+ assertTrue("Worker wasn't interrupted", interrupted.get());
+ }
+
+ public void testBlocking() throws InterruptedException {
+ final int queueSize = 20;
+ final int coreThreads = 5;
+ final int extraThreads = 5;
+ final int cnt = queueSize + coreThreads + extraThreads;
+ final CountDownLatch taskUnfreezer = new CountDownLatch(1);
+ final CountDownLatch taskFinishLine = new CountDownLatch(cnt);
+ final ExecutorService simpleQueueExecutor = new SimpleQueueExecutor(coreThreads, coreThreads + extraThreads, 500L, TimeUnit.MILLISECONDS, new ArrayQueue<Runnable>(queueSize), threadFactory, RejectionPolicy.BLOCK, null);
+ for (int i = 0; i < cnt; i ++) {
+ simpleQueueExecutor.execute(new SimpleTask(taskUnfreezer, taskFinishLine));
+ }
+ Thread.currentThread().interrupt();
+ try {
+ simpleQueueExecutor.execute(new Runnable() {
+ public void run() {
+ }
+ });
+ fail("Task was accepted");
+ } catch (RejectedExecutionException t) {
+ }
+ Thread.interrupted();
+ final CountDownLatch latch = new CountDownLatch(1);
+ final Thread otherThread = threadFactory.newThread(new Runnable() {
+ public void run() {
+ simpleQueueExecutor.execute(new Runnable() {
+ public void run() {
+ latch.countDown();
+ }
+ });
+ }
+ });
+ otherThread.start();
+ assertFalse("Task executed without wait", latch.await(100L, TimeUnit.MILLISECONDS));
+ // safe to say the other thread is blocking...?
+ taskUnfreezer.countDown();
+ assertTrue("Task never ran", latch.await(800L, TimeUnit.MILLISECONDS));
+ otherThread.join(500L);
+ simpleQueueExecutor.shutdown();
+ assertTrue("Executor not shut down in 800ms", simpleQueueExecutor.awaitTermination(800L, TimeUnit.MILLISECONDS));
+ }
+}
Added: projects/jboss-threads/trunk/pom.xml
===================================================================
--- projects/jboss-threads/trunk/pom.xml (rev 0)
+++ projects/jboss-threads/trunk/pom.xml 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,15 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.jboss.threads</groupId>
+ <artifactId>threads-all</artifactId>
+ <version>1.0.0.CR1</version>
+ <packaging>pom</packaging>
+ <modules>
+ <module>main</module>
+ <module>jbossmc</module>
+ </modules>
+</project>
Added: projects/jboss-threads/trunk/test-support/src/main/java/org/jboss/testsupport/LoggingHelper.java
===================================================================
--- projects/jboss-threads/trunk/test-support/src/main/java/org/jboss/testsupport/LoggingHelper.java (rev 0)
+++ projects/jboss-threads/trunk/test-support/src/main/java/org/jboss/testsupport/LoggingHelper.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,117 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.testsupport;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.io.IOException;
+
+import java.util.logging.Logger;
+import java.util.logging.Level;
+import java.util.logging.Handler;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.FileHandler;
+
+/**
+ *
+ */
+public final class LoggingHelper {
+ private static final long startTime = System.currentTimeMillis();
+
+ private static final class Once {
+ static {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ final Logger rootLogger = Logger.getLogger("");
+ rootLogger.setLevel(Level.ALL);
+ final Handler[] handlers = rootLogger.getHandlers();
+ for (Handler handler : handlers) {
+ rootLogger.removeHandler(handler);
+ }
+ final Formatter formatter = new Formatter() {
+ public String format(final LogRecord record) {
+ StringBuilder builder = new StringBuilder();
+ long offs = record.getMillis() - startTime;
+ final String sign = offs < 0 ? "-" : "+";
+ offs = Math.abs(offs);
+ int ms = (int) (offs % 1000L);
+ long s = offs / 1000L;
+ builder.append(String.format("%s%04d.%03d ", sign, Long.valueOf(s), Long.valueOf(ms)));
+ builder.append(String.format("tid:%d ", Integer.valueOf(record.getThreadID())));
+ builder.append(record.getLevel().toString());
+ builder.append(" [").append(record.getLoggerName()).append("] ");
+ builder.append(String.format(record.getMessage(), record.getParameters()));
+ Throwable t = record.getThrown();
+ while (t != null) {
+ builder.append("\n Caused by: ");
+ builder.append(t.toString());
+ for (StackTraceElement e : t.getStackTrace()) {
+ builder.append("\n at ");
+ builder.append(e.getClassName()).append('.').append(e.getMethodName());
+ builder.append("(").append(e.getFileName()).append(':').append(e.getLineNumber()).append(')');
+ }
+ t = t.getCause();
+ }
+ builder.append('\n');
+ return builder.toString();
+ }
+ };
+ final Handler handler = new ConsoleHandler() {
+ @Override
+ public void publish(final LogRecord record) {
+ super.publish(record);
+ flush();
+ }
+ };
+ handler.setFormatter(formatter);
+ handler.setLevel(Level.ALL);
+ rootLogger.addHandler(handler);
+ if (false) try {
+ final FileHandler fileHandler = new FileHandler("test-output.log", true) {
+ @Override
+ public void publish(final LogRecord record) {
+ super.publish(record);
+ flush();
+ }
+ };
+ fileHandler.setFormatter(formatter);
+ fileHandler.setLevel(Level.ALL);
+ rootLogger.addHandler(fileHandler);
+ } catch (IOException e) {
+ // oh well
+ }
+ return null;
+ }
+ });
+ }
+ }
+
+ private LoggingHelper() {
+ }
+
+ public static void init() {
+ new Once();
+ }
+}
Added: projects/jboss-threads/trunk/test-support/src/main/java/org/jboss/testsupport/LoggingSecurityManager.java
===================================================================
--- projects/jboss-threads/trunk/test-support/src/main/java/org/jboss/testsupport/LoggingSecurityManager.java (rev 0)
+++ projects/jboss-threads/trunk/test-support/src/main/java/org/jboss/testsupport/LoggingSecurityManager.java 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,295 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.testsupport;
+
+import java.security.Permission;
+import java.io.FileDescriptor;
+import java.net.InetAddress;
+
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+/**
+ *
+ */
+public final class LoggingSecurityManager extends SecurityManager {
+
+ private static final Logger log = Logger.getLogger("ACCESS_EXCEPTION");
+
+ public LoggingSecurityManager() {
+ }
+
+ private static <T extends Throwable> T logged(T se) {
+ log.log(Level.SEVERE, "Access violation!", se);
+ return se;
+ }
+
+ public void checkPermission(final Permission perm) {
+ try {
+ super.checkPermission(perm);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkPermission(final Permission perm, final Object context) {
+ try {
+ super.checkPermission(perm, context);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkCreateClassLoader() {
+ try {
+ super.checkCreateClassLoader();
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkAccess(final Thread t) {
+ try {
+ super.checkAccess(t);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkAccess(final ThreadGroup g) {
+ try {
+ super.checkAccess(g);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkExit(final int status) {
+ try {
+ super.checkExit(status);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkExec(final String cmd) {
+ try {
+ super.checkExec(cmd);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkLink(final String lib) {
+ try {
+ super.checkLink(lib);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkRead(final FileDescriptor fd) {
+ try {
+ super.checkRead(fd);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkRead(final String file) {
+ try {
+ super.checkRead(file);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkRead(final String file, final Object context) {
+ try {
+ super.checkRead(file, context);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkWrite(final FileDescriptor fd) {
+ try {
+ super.checkWrite(fd);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkWrite(final String file) {
+ try {
+ super.checkWrite(file);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkDelete(final String file) {
+ try {
+ super.checkDelete(file);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkConnect(final String host, final int port) {
+ try {
+ super.checkConnect(host, port);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkConnect(final String host, final int port, final Object context) {
+ try {
+ super.checkConnect(host, port, context);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkListen(final int port) {
+ try {
+ super.checkListen(port);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkAccept(final String host, final int port) {
+ try {
+ super.checkAccept(host, port);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkMulticast(final InetAddress maddr) {
+ try {
+ super.checkMulticast(maddr);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ @Deprecated
+ public void checkMulticast(final InetAddress maddr, final byte ttl) {
+ try {
+ super.checkMulticast(maddr, ttl);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkPropertiesAccess() {
+ try {
+ super.checkPropertiesAccess();
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkPropertyAccess(final String key) {
+ try {
+ super.checkPropertyAccess(key);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public boolean checkTopLevelWindow(final Object window) {
+ try {
+ return super.checkTopLevelWindow(window);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkPrintJobAccess() {
+ try {
+ super.checkPrintJobAccess();
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkSystemClipboardAccess() {
+ try {
+ super.checkSystemClipboardAccess();
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkAwtEventQueueAccess() {
+ try {
+ super.checkAwtEventQueueAccess();
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkPackageAccess(final String pkg) {
+ try {
+ super.checkPackageAccess(pkg);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkPackageDefinition(final String pkg) {
+ try {
+ super.checkPackageDefinition(pkg);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkSetFactory() {
+ try {
+ super.checkSetFactory();
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkMemberAccess(final Class<?> clazz, final int which) {
+ try {
+ super.checkMemberAccess(clazz, which);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+
+ public void checkSecurityAccess(final String target) {
+ try {
+ super.checkSecurityAccess(target);
+ } catch (SecurityException se) {
+ throw logged(se);
+ }
+ }
+}
Added: projects/jboss-threads/trunk/test-support/src/main/resources/testing.policy
===================================================================
--- projects/jboss-threads/trunk/test-support/src/main/resources/testing.policy (rev 0)
+++ projects/jboss-threads/trunk/test-support/src/main/resources/testing.policy 2009-02-17 23:09:48 UTC (rev 84336)
@@ -0,0 +1,37 @@
+
+// Permissions to grant to modules
+
+grant codeBase "file:${build.home}/main/target/main/classes/-"
+{
+ permission java.lang.RuntimePermission "modifyThreadGroup";
+};
+
+// Permissions to run the main test suite
+
+grant codeBase "file:${build.home}/main/target/test/classes/-"
+{
+ permission java.lang.RuntimePermission "modifyThread";
+ permission java.lang.RuntimePermission "modifyThreadGroup";
+};
+
+// Support classes
+
+grant codeBase "file:${build.home}/test-support/target/main/classes/-"
+{
+ permission java.security.AllPermission;
+};
+
+grant codeBase "file:${idea.home}/lib/idea_rt.jar"
+{
+ permission java.security.AllPermission;
+};
+
+grant codeBase "file:${lib.junit.local}"
+{
+ permission java.security.AllPermission;
+};
+
+grant codeBase "file:${ant.library.dir}/-"
+{
+ permission java.security.AllPermission;
+};
More information about the jboss-cvs-commits
mailing list