/* * Copyright (c) 2011, Jan Stender, Bjoern Kolbeck, Mikael Hoegqvist, * Felix Hupfeld, Felix Langner, Zuse Institute Berlin * * Licensed under the BSD License, see LICENSE file for details. * */ package de.mxro.thrd.babudb05; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import de.mxro.thrd.babudb05.api.database.DatabaseRequestListener; import de.mxro.thrd.babudb05.api.dev.ResponseManagerInternal; import de.mxro.thrd.babudb05.api.exception.BabuDBException; /** * Thread to process response handles for BabuDB request futures. This is necessary to decouple internal BabuDB * threads from user listeners. It does not prevent user listeners from deadlock by them selves. * * @author flangner * @since 05/29/2011 */ public class ResponseManagerImpl extends ResponseManagerInternal { private final BlockingQueue<ResponseRecord<?>> queue; private boolean quit = true; /** * @param max_Q - max length of the queue. */ public ResponseManagerImpl(int max_Q) { super(); if (max_Q > 0) { queue = new LinkedBlockingQueue<ResponseRecord<?>>(max_Q); } else { queue = new LinkedBlockingQueue<ResponseRecord<?>>(); } } /* (non-Javadoc) * @see org.xtreemfs.babudb.api.dev.ResponseManagerInternal#enqueueResponse( * org.xtreemfs.babudb.api.database.DatabaseRequestListener, * org.xtreemfs.babudb.api.exception.BabuDBException, java.lang.Object, * java.lang.Object) */ @Override public <T> void enqueueResponse(DatabaseRequestListener<T> listener, BabuDBException error, T result, Object context) throws InterruptedException { assert (result == null || error == null && result != error); queue.put(new ResponseRecord<T>(listener, error, result, context)); } /* (non-Javadoc) * @see java.lang.Thread#start() */ @Override public synchronized void start() { quit = false; super.start(); } /* (non-Javadoc) * @see org.xtreemfs.foundation.LifeCycleThread#shutdown() */ @Override public synchronized void shutdown() throws Exception { quit = true; interrupt(); } /* (non-Javadoc) * @see java.lang.Thread#run() */ @Override @SuppressWarnings("unchecked") public void run() { ResponseRecord respRec = null; notifyStarted(); while (!quit) { try { respRec = queue.take(); if (respRec.error == null) { respRec.listener.finished(respRec.result, respRec.context); } else { respRec.listener.failed(respRec.error, respRec.context); } } catch (InterruptedException e) { if (!quit) { notifyCrashed(e); } } } notifyStopped(); } /** * Data record for processing the listener. * * @author flangner * @since 05/29/2011 * @param <T> */ private final static class ResponseRecord<T> { private final DatabaseRequestListener<T> listener; private final BabuDBException error; private final Object context; private final T result; private ResponseRecord(DatabaseRequestListener<T> listener, BabuDBException error, T result, Object context) { this.listener = listener; this.error = error; this.result = result; this.context = context; } } }