23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package com.sun.corba.se.impl.orbutil.threadpool; |
26 package com.sun.corba.se.impl.orbutil.threadpool; |
27 |
27 |
|
28 import java.io.IOException; |
|
29 |
|
30 import java.security.PrivilegedAction; |
|
31 import java.security.AccessController; |
|
32 |
|
33 import java.util.concurrent.atomic.AtomicInteger; |
|
34 |
|
35 import com.sun.corba.se.spi.orb.ORB; |
|
36 |
28 import com.sun.corba.se.spi.orbutil.threadpool.NoSuchThreadPoolException; |
37 import com.sun.corba.se.spi.orbutil.threadpool.NoSuchThreadPoolException; |
29 import com.sun.corba.se.spi.orbutil.threadpool.ThreadPool; |
38 import com.sun.corba.se.spi.orbutil.threadpool.ThreadPool; |
30 import com.sun.corba.se.spi.orbutil.threadpool.ThreadPoolManager; |
39 import com.sun.corba.se.spi.orbutil.threadpool.ThreadPoolManager; |
31 import com.sun.corba.se.spi.orbutil.threadpool.ThreadPoolChooser; |
40 import com.sun.corba.se.spi.orbutil.threadpool.ThreadPoolChooser; |
32 |
41 |
33 import com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl; |
42 import com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl; |
34 import com.sun.corba.se.impl.orbutil.ORBConstants; |
43 import com.sun.corba.se.impl.orbutil.ORBConstants; |
35 |
44 |
|
45 import com.sun.corba.se.impl.logging.ORBUtilSystemException; |
|
46 import com.sun.corba.se.impl.orbutil.ORBConstants; |
|
47 import com.sun.corba.se.spi.logging.CORBALogDomains; |
|
48 |
|
49 |
36 public class ThreadPoolManagerImpl implements ThreadPoolManager |
50 public class ThreadPoolManagerImpl implements ThreadPoolManager |
37 { |
51 { |
38 private ThreadPool threadPool ; |
52 private ThreadPool threadPool; |
39 |
53 private ThreadGroup threadGroup; |
40 public ThreadPoolManagerImpl( ThreadGroup tg ) |
54 |
41 { |
55 private static final ORBUtilSystemException wrapper = |
42 // Use unbounded threadpool in J2SE ORB |
56 ORBUtilSystemException.get(CORBALogDomains.RPC_TRANSPORT); |
43 // ThreadPoolManager from s1as appserver code base can be set in the |
57 |
44 // ORB. ThreadPools in the appserver are bounded. In that situation |
58 public ThreadPoolManagerImpl() { |
45 // the ThreadPool in this ThreadPoolManager will have its threads |
59 threadGroup = getThreadGroup(); |
46 // die after the idle timeout. |
60 threadPool = new ThreadPoolImpl(threadGroup, |
47 // XXX Should there be cleanup when ORB.shutdown is called if the |
61 ORBConstants.THREADPOOL_DEFAULT_NAME); |
48 // ORB owns the ThreadPool? |
62 } |
49 threadPool = new ThreadPoolImpl( tg, |
63 |
50 ORBConstants.THREADPOOL_DEFAULT_NAME ) ; |
64 private static AtomicInteger tgCount = new AtomicInteger(); |
|
65 |
|
66 |
|
67 private ThreadGroup getThreadGroup() { |
|
68 ThreadGroup tg; |
|
69 |
|
70 // See bugs 4916766 and 4936203 |
|
71 // We intend to create new threads in a reliable thread group. |
|
72 // This avoids problems if the application/applet |
|
73 // creates a thread group, makes JavaIDL calls which create a new |
|
74 // connection and ReaderThread, and then destroys the thread |
|
75 // group. If our ReaderThreads were to be part of such destroyed thread |
|
76 // group then it might get killed and cause other invoking threads |
|
77 // sharing the same connection to get a non-restartable |
|
78 // CommunicationFailure. We'd like to avoid that. |
|
79 // |
|
80 // Our solution is to create all of our threads in the highest thread |
|
81 // group that we have access to, given our own security clearance. |
|
82 // |
|
83 try { |
|
84 // try to get a thread group that's as high in the threadgroup |
|
85 // parent-child hierarchy, as we can get to. |
|
86 // this will prevent an ORB thread created during applet-init from |
|
87 // being killed when an applet dies. |
|
88 tg = AccessController.doPrivileged( |
|
89 new PrivilegedAction<ThreadGroup>() { |
|
90 public ThreadGroup run() { |
|
91 ThreadGroup tg = Thread.currentThread().getThreadGroup(); |
|
92 ThreadGroup ptg = tg; |
|
93 try { |
|
94 while (ptg != null) { |
|
95 tg = ptg; |
|
96 ptg = tg.getParent(); |
|
97 } |
|
98 } catch (SecurityException se) { |
|
99 // Discontinue going higher on a security exception. |
|
100 } |
|
101 return new ThreadGroup(tg, "ORB ThreadGroup " + tgCount.getAndIncrement()); |
|
102 } |
|
103 } |
|
104 ); |
|
105 } catch (SecurityException e) { |
|
106 // something wrong, we go back to the original code |
|
107 tg = Thread.currentThread().getThreadGroup(); |
|
108 } |
|
109 |
|
110 return tg; |
|
111 } |
|
112 |
|
113 public void close() { |
|
114 try { |
|
115 threadPool.close(); |
|
116 } catch (IOException exc) { |
|
117 wrapper.threadPoolCloseError(); |
|
118 } |
|
119 |
|
120 try { |
|
121 boolean isDestroyed = threadGroup.isDestroyed(); |
|
122 int numThreads = threadGroup.activeCount(); |
|
123 int numGroups = threadGroup.activeGroupCount(); |
|
124 |
|
125 if (isDestroyed) { |
|
126 wrapper.threadGroupIsDestroyed(threadGroup); |
|
127 } else { |
|
128 if (numThreads > 0) |
|
129 wrapper.threadGroupHasActiveThreadsInClose(threadGroup, numThreads); |
|
130 |
|
131 if (numGroups > 0) |
|
132 wrapper.threadGroupHasSubGroupsInClose(threadGroup, numGroups); |
|
133 |
|
134 threadGroup.destroy(); |
|
135 } |
|
136 } catch (IllegalThreadStateException exc) { |
|
137 wrapper.threadGroupDestroyFailed(exc, threadGroup); |
|
138 } |
|
139 |
|
140 threadGroup = null; |
51 } |
141 } |
52 |
142 |
53 /** |
143 /** |
54 * This method will return an instance of the threadpool given a threadpoolId, |
144 * This method will return an instance of the threadpool given a threadpoolId, |
55 * that can be used by any component in the app. server. |
145 * that can be used by any component in the app. server. |