/** * block thread until event available * * @return available event or null if no event available and return-threshold is reach * @throws InterruptedException */ public EventType waitNewEvent(int waitTimeout) throws InterruptedException { this.returnCount = 0; while (true) { synchronized (this.queue) { if (Options.LL_DEBUG) { BtLog.d("EventQueue.waitNewEvent() before remove queue size:" + this.queue.size()); } // event available => return first event if (!this.queue.isEmpty()) { return this.queue.removeFirst(); } // return threshold is enabled when it's > 0 else if (this.returnThreshold > 0) { // event not available => check return threshold // this is for the abnormal case and avoid infinite loop situation (no end event) this.returnCount++; if (this.returnCount >= this.returnThreshold) { return null; } } // wait until event available or timeout try { if (this.isCanceled) { this.isCanceled = false; return null; } this.queue.wait(waitTimeout); if (this.isCanceled) { this.isCanceled = false; return null; } } catch (InterruptedException ie) { BtLog.i( "EventQueue.waitNewEvent() thread[" + Thread.currentThread().getName() + "] interrupted"); throw ie; } catch (Exception ex) { BtLog.e("EventQueue.waitNewEvent() error: " + ex.getMessage()); throw new IllegalStateException("EventQueue.waitNewEvent() error.", ex); } } } }
/** * add event into this queue and notify waiting thread to process * * @param newEvent */ public void notifyNewEvent(EventType newEvent) { synchronized (this.queue) { this.queue.addLast(newEvent); if (Options.LL_DEBUG) { BtLog.d("EventQueue.notifyNewEvent() after insert queue size:" + this.queue.size()); } this.queue.notify(); } }
/** return null from waitNewEvent() */ public void cancelWaitNewEvent() { synchronized (this.queue) { this.isCanceled = true; if (Options.LL_DEBUG) { BtLog.d("EventQueue.cancelWaitNewEvent():" + this.queue.size()); } this.queue.notify(); } }