synchronized void transactionServiced(TransactionQueueEvent event) { TransactionQueueEvent svcEvent = new TransactionQueueEvent(event); mTotalServiceDuration += (svcEvent.getTimestampMillis() - event.getTimestampMillis()); if (mListeners.size() > 0) { Iterator it = mListeners.iterator(); while (it.hasNext()) { ((TransactionQueueListener) it.next()).transactionServiced(svcEvent); } } // Adjust counters at end in case a listener threw an exception and let // the call to transactionException adjust the counters instead. mServicingCount--; mTotalServiced++; }
synchronized TransactionQueueEvent transactionDequeued(TransactionQueueEvent event) { if (++mServicingCount > mPeakServicingCount) { mPeakServicingCount = mServicingCount; } TransactionQueueEvent deqEvent = new TransactionQueueEvent(event); mTotalQueueDuration += (deqEvent.getTimestampMillis() - event.getTimestampMillis()); if (mListeners.size() > 0) { Iterator it = mListeners.iterator(); while (it.hasNext()) { ((TransactionQueueListener) it.next()).transactionDequeued(deqEvent); } } return deqEvent; }
public void run() { boolean forceExit = false; TransactionQueueEvent event; while (true) { try { // allow event to be GC'd in case we wait() on next event event = null; // Phase 1: wait for a transaction try { if ((event = nextTransactionEvent()) == null) { // Go into idle mode. continue; } } catch (InterruptedException e) { forceExit = true; continue; } long enqueueTimestamp = event.getTimestampMillis(); // Phase 2: spawn off a replacement thread try { startThread(false); } catch (NoThreadException e) { if (e.isThreadPoolClosed()) { forceExit = true; // Don't "continue" because the transaction must // still be serviced first. } } catch (InterruptedException e) { forceExit = true; // Don't "continue" because the transaction must // still be serviced first. } catch (Throwable e) { uncaughtException(e); } finally { // Only indicate that transaction has been dequeued // after a replacement thread has been created. // Queue time is more accurate this way because time // spent waiting for a thread is time spent not being // serviced. try { event = transactionDequeued(event); } catch (Throwable e) { uncaughtException(e); } } long serviceTimestamp = event.getTimestampMillis(); // Phase 3: service the transaction long timeout = getTransactionTimeout(); if (timeout >= 0 && (serviceTimestamp - enqueueTimestamp) >= timeout) { try { event.getTransaction().cancel(); } finally { transactionExpired(event); } } else { try { event.getTransaction().service(); transactionServiced(event); } catch (Throwable e) { uncaughtException(e); try { event.getTransaction().cancel(); } catch (Throwable e2) { uncaughtException(e2); } transactionException(event, e); } } } catch (Throwable e) { try { uncaughtException(e); } catch (Throwable e2) { // If another error is thrown while trying to log the // first error, ignore it. This ensures that the // exitThread method is called, even if // OutOfMemoryErrors are being thrown around. } } finally { if (exitThread(forceExit)) { break; } } } }