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);
|
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 // Assignment of queue to special ENQUEUED queue must be
70 // after the reference is added to the queue's list.
71 // Otherwise, there is a race condition where the
72 // reference appears to be enqueued (isEnqueue returns
73 // true, another enqueue returns false), but polling the
74 // queue could find it still empty. The q.head and
75 // r.queue fields are volatile, ensuring that order.
76 r.queue = ENQUEUED;
77 if (r instanceof FinalReference) {
78 sun.misc.VM.addFinalRefCount(1);
79 }
80 lock.notifyAll();
81 return true;
82 }
83 }
84
85 @SuppressWarnings("unchecked")
86 private Reference<? extends T> reallyPoll() { /* Must hold lock */
87 Reference<? extends T> r = head;
88 if (r != null) {
89 head = (r.next == r) ?
90 null :
91 r.next; // Unchecked due to the next field having a raw type in Reference
92 r.queue = NULL;
93 r.next = r;
94 queueLength--;
95 if (r instanceof FinalReference) {
96 sun.misc.VM.addFinalRefCount(-1);
|