64 * buf.putInt(x).putInt(y);
65 * buf.putLong(addr1);
66 * buf.putLong(addr2);
67 * } finally {
68 * rq.unlock();
69 * }
70 * }
71 */
72 public abstract class RenderQueue {
73
74 /** The size of the underlying buffer, in bytes. */
75 private static final int BUFFER_SIZE = 32000;
76
77 /** The underlying buffer for this queue. */
78 protected RenderBuffer buf;
79
80 /**
81 * A Set containing hard references to Objects that must stay alive until
82 * the queue has been completely flushed.
83 */
84 protected Set refSet;
85
86 protected RenderQueue() {
87 refSet = new HashSet();
88 buf = RenderBuffer.allocate(BUFFER_SIZE);
89 }
90
91 /**
92 * Locks the queue for read/write access.
93 */
94 public final void lock() {
95 /*
96 * Implementation note: In theory we should have two separate locks:
97 * one lock to synchronize access to the RenderQueue, and then a
98 * separate lock (the AWT lock) that only needs to be acquired when
99 * we are about to flush the queue (using native windowing system
100 * operations). In practice it has been difficult to enforce the
101 * correct lock ordering; sometimes AWT will have already acquired
102 * the AWT lock before grabbing the RQ lock (see 6253009), while the
103 * expected order should be RQ lock and then AWT lock. Due to this
104 * issue, using two separate locks is prone to deadlocks. Therefore,
105 * to solve this issue we have decided to eliminate the separate RQ
106 * lock and instead just acquire the AWT lock here. (Someday it might
107 * be nice to go back to the old two-lock system, but that would
|
64 * buf.putInt(x).putInt(y);
65 * buf.putLong(addr1);
66 * buf.putLong(addr2);
67 * } finally {
68 * rq.unlock();
69 * }
70 * }
71 */
72 public abstract class RenderQueue {
73
74 /** The size of the underlying buffer, in bytes. */
75 private static final int BUFFER_SIZE = 32000;
76
77 /** The underlying buffer for this queue. */
78 protected RenderBuffer buf;
79
80 /**
81 * A Set containing hard references to Objects that must stay alive until
82 * the queue has been completely flushed.
83 */
84 protected Set<Object> refSet;
85
86 protected RenderQueue() {
87 refSet = new HashSet<>();
88 buf = RenderBuffer.allocate(BUFFER_SIZE);
89 }
90
91 /**
92 * Locks the queue for read/write access.
93 */
94 public final void lock() {
95 /*
96 * Implementation note: In theory we should have two separate locks:
97 * one lock to synchronize access to the RenderQueue, and then a
98 * separate lock (the AWT lock) that only needs to be acquired when
99 * we are about to flush the queue (using native windowing system
100 * operations). In practice it has been difficult to enforce the
101 * correct lock ordering; sometimes AWT will have already acquired
102 * the AWT lock before grabbing the RQ lock (see 6253009), while the
103 * expected order should be RQ lock and then AWT lock. Due to this
104 * issue, using two separate locks is prone to deadlocks. Therefore,
105 * to solve this issue we have decided to eliminate the separate RQ
106 * lock and instead just acquire the AWT lock here. (Someday it might
107 * be nice to go back to the old two-lock system, but that would
|