14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.nio.ch;
27
28 // Special-purpose data structure for sets of native threads
29
30 class NativeThreadSet {
31 private static final int OTHER_THREAD_INDEX = -99;
32
33 private final int initialCapacity;
34 private long[] threads; // array of thread handles, created lazily
35 private int used; // number of thread handles in threads array
36 private int otherThreads; // count of threads without a native thread handle
37 private boolean waitingToEmpty;
38
39 NativeThreadSet(int n) {
40 initialCapacity = n;
41 }
42
43 /**
44 * Adds the current thread handle to this set, returning an index so that
45 * it can efficiently be removed later.
46 */
47 int add() {
48 long th = NativeThread.current();
49 synchronized (this) {
50 if (!NativeThread.isNativeThread(th)) {
51 otherThreads++;
52 return OTHER_THREAD_INDEX;
53 }
54
55 // add native thread handle to array, creating or growing array if needed
56 int start = 0;
57 if (threads == null) {
58 threads = new long[initialCapacity];
59 } else if (used >= threads.length) {
60 int on = threads.length;
61 int nn = on * 2;
62 long[] nthreads = new long[nn];
63 System.arraycopy(threads, 0, nthreads, 0, on);
64 threads = nthreads;
65 start = on;
66 }
67 for (int i = start; i < threads.length; i++) {
68 if (threads[i] == 0) {
69 threads[i] = th;
70 used++;
71 return i;
72 }
73 }
74 throw new InternalError();
75 }
76 }
77
78 /**
79 * Removes the thread at the given index. A no-op if index is -1.
80 */
81 void remove(int i) {
82 synchronized (this) {
83 if (i >= 0) {
84 assert threads[i] == NativeThread.current();
85 threads[i] = 0;
86 used--;
87 } else if (i == OTHER_THREAD_INDEX) {
88 otherThreads--;
89 } else {
90 assert i == -1;
91 return;
92 }
93 if (used == 0 && otherThreads == 0 && waitingToEmpty) {
94 notifyAll();
95 }
96 }
97 }
98
99 /**
100 * Signals all native threads in the thread set and wait for the thread set to empty.
101 */
102 synchronized void signalAndWait() {
103 boolean interrupted = false;
104 while (used > 0 || otherThreads > 0) {
105 int u = used, i = 0;
106 while (u > 0 && i < threads.length) {
107 long th = threads[i];
108 if (th != 0) {
109 NativeThread.signal(th);
110 u--;
111 }
112 i++;
113 }
114 waitingToEmpty = true;
115 try {
116 wait(50);
117 } catch (InterruptedException e) {
118 interrupted = true;
119 } finally {
120 waitingToEmpty = false;
121 }
122 }
123 if (interrupted)
124 Thread.currentThread().interrupt();
125 }
126 }
|
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.nio.ch;
27
28 // Special-purpose data structure for sets of native threads
29
30 class NativeThreadSet {
31 private static final int OTHER_THREAD_INDEX = -99;
32
33 private final int initialCapacity;
34 private NativeThread[] threads; // array of native threads, created lazily
35 private int used; // number of elements in threads array
36 private int otherThreads; // count of threads without a native thread object
37 private boolean waitingToEmpty;
38
39 NativeThreadSet(int n) {
40 initialCapacity = n;
41 }
42
43 /**
44 * Adds the current thread handle to this set, returning an index so that
45 * it can efficiently be removed later.
46 */
47 int add() {
48 NativeThread nt = NativeThread.currentNativeThread();
49 synchronized (this) {
50 if (nt == null) {
51 otherThreads++;
52 return OTHER_THREAD_INDEX;
53 }
54
55 // add native thread handle to array, creating or growing array if needed
56 int start = 0;
57 if (threads == null) {
58 threads = new NativeThread[initialCapacity];
59 } else if (used >= threads.length) {
60 int on = threads.length;
61 int nn = on * 2;
62 NativeThread[] nthreads = new NativeThread[nn];
63 System.arraycopy(threads, 0, nthreads, 0, on);
64 threads = nthreads;
65 start = on;
66 }
67 for (int i = start; i < threads.length; i++) {
68 if (threads[i] == null) {
69 threads[i] = nt;
70 used++;
71 return i;
72 }
73 }
74 throw new InternalError();
75 }
76 }
77
78 /**
79 * Removes the thread at the given index. A no-op if index is -1.
80 */
81 void remove(int i) {
82 synchronized (this) {
83 if (i >= 0) {
84 assert threads[i] == NativeThread.currentNativeThread();
85 threads[i] = null;
86 used--;
87 } else if (i == OTHER_THREAD_INDEX) {
88 otherThreads--;
89 } else {
90 assert i == -1;
91 return;
92 }
93 if (used == 0 && otherThreads == 0 && waitingToEmpty) {
94 notifyAll();
95 }
96 }
97 }
98
99 /**
100 * Signals all native threads in the thread set and wait for the thread set to empty.
101 */
102 synchronized void signalAndWait() {
103 boolean interrupted = false;
104 while (used > 0 || otherThreads > 0) {
105 int u = used, i = 0;
106 while (u > 0 && i < threads.length) {
107 NativeThread nt = threads[i];
108 if (nt != null) {
109 nt.signal();
110 u--;
111 }
112 i++;
113 }
114 waitingToEmpty = true;
115 try {
116 wait(50);
117 } catch (InterruptedException e) {
118 interrupted = true;
119 } finally {
120 waitingToEmpty = false;
121 }
122 }
123 if (interrupted)
124 Thread.currentThread().interrupt();
125 }
126 }
|