/* ************************************************************************
#
# DivConq
#
# http://divconq.com/
#
# Copyright:
# Copyright 2014 eTimeline, LLC. All rights reserved.
#
# License:
# See the license.txt file in the project's top-level directory for details.
#
# Authors:
# * Andy White
#
************************************************************************ */
package divconq.lang;
import java.util.concurrent.ConcurrentLinkedQueue;
import divconq.lang.op.FuncCallback;
public class CallbackQueue<T> {
protected ConcurrentLinkedQueue<T> resources = new ConcurrentLinkedQueue<T>();
protected ConcurrentLinkedQueue<FuncCallback<T>> callbacks = new ConcurrentLinkedQueue<FuncCallback<T>>();
protected volatile boolean disposed = false;
protected QueueWatcher qwatcher = null;
public void setWatcher(QueueWatcher watcher) {
this.qwatcher = watcher;
}
public void pop(FuncCallback<T> callback) {
if (this.disposed) {
callback.error(1, "Disposed"); // TODO better code
callback.complete();
return;
}
T resource = this.resources.poll();
if (resource != null) {
callback.setResult(resource);
callback.complete();
return;
}
this.callbacks.add(callback);
}
public void add(T resource) {
if (this.disposed) {
if (this.qwatcher != null)
this.qwatcher.disposed(resource);
return;
}
FuncCallback<T> callback = this.callbacks.poll();
if (callback != null) {
callback.setResult(resource);
callback.complete();
return;
}
this.resources.add(resource);
}
// tell the callbacks to go away, nothing more to do
// and grab all the available resources
public void dispose() {
this.disposed = true;
FuncCallback<T> callback = this.callbacks.poll();
while (callback != null) {
callback.error(1, "Nothing more to do"); // TODO better code
callback.complete();
callback = this.callbacks.poll();
}
if (this.qwatcher != null) {
T res = this.resources.poll();
while (res != null) {
this.qwatcher.disposed(res);
res = this.resources.poll();
}
}
}
abstract public class QueueWatcher {
abstract public void disposed(T res);
}
}