1/*
2 * Copyright (c) 2008-2010, Matthias Mann
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
7 * conditions are met:
8 *
9 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Matthias Mann nor
12 * the names of its contributors may be used to endorse or promote products derived from this software without specific prior
13 * written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
16 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
17 * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 */
22
23package com.badlogic.gdx.utils;
24
25import java.util.concurrent.atomic.AtomicInteger;
26import java.util.concurrent.atomic.AtomicReferenceArray;
27
28/** A queue that allows one thread to call {@link #put(Object)} and another thread to call {@link #poll()}. Multiple threads must
29 * not call these methods.
30 * @author Matthias Mann */
31public class AtomicQueue<T> {
32	private final AtomicInteger writeIndex = new AtomicInteger();
33	private final AtomicInteger readIndex = new AtomicInteger();
34	private final AtomicReferenceArray<T> queue;
35
36	public AtomicQueue (int capacity) {
37		queue = new AtomicReferenceArray(capacity);
38	}
39
40	private int next (int idx) {
41		return (idx + 1) % queue.length();
42	}
43
44	public boolean put (T value) {
45		int write = writeIndex.get();
46		int read = readIndex.get();
47		int next = next(write);
48		if (next == read) return false;
49		queue.set(write, value);
50		writeIndex.set(next);
51		return true;
52	}
53
54	public T poll () {
55		int read = readIndex.get();
56		int write = writeIndex.get();
57		if (read == write) return null;
58		T value = queue.get(read);
59		readIndex.set(next(read));
60		return value;
61	}
62}
63