1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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
46 }
47 }
48
49 static ReferenceQueue<Object> NULL = new Null<>();
50 static ReferenceQueue<Object> ENQUEUED = new Null<>();
51
52 static private class Lock { };
53 private Lock lock = new Lock();
54 private volatile Reference<? extends T> head = null;
55 private long queueLength = 0;
56
57 boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
58 synchronized (lock) {
59 // Check that since getting the lock this reference hasn't already been
60 // enqueued (and even then removed)
61 ReferenceQueue<?> queue = r.queue;
62 if ((queue == NULL) || (queue == ENQUEUED)) {
63 return false;
64 }
65 assert queue == this;
66 r.queue = ENQUEUED;
67 r.next = (head == null) ? r : head;
68 head = r;
69 queueLength++;
70 if (r instanceof FinalReference) {
71 sun.misc.VM.addFinalRefCount(1);
72 }
73 lock.notifyAll();
74 return true;
75 }
76 }
77
78 @SuppressWarnings("unchecked")
79 private Reference<? extends T> reallyPoll() { /* Must hold lock */
80 Reference<? extends T> r = head;
81 if (r != null) {
82 head = (r.next == r) ?
83 null :
84 r.next; // Unchecked due to the next field having a raw type in Reference
85 r.queue = NULL;
86 r.next = r;
87 queueLength--;
88 if (r instanceof FinalReference) {
89 sun.misc.VM.addFinalRefCount(-1);
90 }
91 return r;
92 }
93 return null;
94 }
95
96 /**
97 * Polls this queue to see if a reference object is available. If one is
98 * available without further delay then it is removed from the queue and
99 * returned. Otherwise this method immediately returns <tt>null</tt>.
100 *
101 * @return A reference object, if one was immediately available,
102 * otherwise <code>null</code>
103 */
104 public Reference<? extends T> poll() {
105 if (head == null)
|
1 /*
2 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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
46 }
47 }
48
49 static ReferenceQueue<Object> NULL = new Null<>();
50 static ReferenceQueue<Object> ENQUEUED = new Null<>();
51
52 static private class Lock { };
53 private Lock lock = new Lock();
54 private volatile Reference<? extends T> head = null;
55 private long queueLength = 0;
56
57 boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
58 synchronized (lock) {
59 // Check that since getting the lock this reference hasn't already been
60 // enqueued (and even then removed)
61 ReferenceQueue<?> queue = r.queue;
62 if ((queue == NULL) || (queue == ENQUEUED)) {
63 return false;
64 }
65 assert queue == this;
66 r.next = (head == null) ? r : head;
67 head = r;
68 queueLength++;
69 // Update r.queue *after* adding to list, to avoid race
70 // with concurrent enqueued checks and fast-path poll().
71 // Volatiles ensure ordering.
72 r.queue = ENQUEUED;
73 if (r instanceof FinalReference) {
74 sun.misc.VM.addFinalRefCount(1);
75 }
76 lock.notifyAll();
77 return true;
78 }
79 }
80
81 @SuppressWarnings("unchecked")
82 private Reference<? extends T> reallyPoll() { /* Must hold lock */
83 Reference<? extends T> r = head;
84 if (r != null) {
85 r.queue = NULL;
86 // Update r.queue *before* removing from list, to avoid
87 // race with concurrent enqueued checks and fast-path
88 // poll(). Volatiles ensure ordering.
89 head = (r.next == r) ?
90 null :
91 r.next; // Unchecked due to the next field having a raw type in Reference
92 r.next = r;
93 queueLength--;
94 if (r instanceof FinalReference) {
95 sun.misc.VM.addFinalRefCount(-1);
96 }
97 return r;
98 }
99 return null;
100 }
101
102 /**
103 * Polls this queue to see if a reference object is available. If one is
104 * available without further delay then it is removed from the queue and
105 * returned. Otherwise this method immediately returns <tt>null</tt>.
106 *
107 * @return A reference object, if one was immediately available,
108 * otherwise <code>null</code>
109 */
110 public Reference<? extends T> poll() {
111 if (head == null)
|