void stack::call::expired(void) { linked_pointer<segment> sp; switch(state) { case TRANSFER: case HOLDING: // hold-recall timer expired... case RINGING: // re-generate ring event to origination... // also controls call-forward no-answer timing... if(answering == 1 && forwarding) { forwarding = "na"; cancelLocked(); if(stack::forward(this)) { arm(1000); reply_source(SIP_CALL_IS_BEING_FORWARDED); return; } disconnectLocked(); break; } if(answering) --answering; arm(1000); reply_source(SIP_RINGING); return; case REDIRECT: // FIXME: add refer select of next segment if list.... case RINGBACK: case BUSY: // invite expired case JOINED: // active call session expired without re-invite case ANSWERED: case REORDER: case TRYING: case FAILED: disconnectLocked(); break; case FINAL: // session expired that expects to be recycled. case INITIAL: // never used session recycled. // The call record is garbage collected shell::debug(4, "expiring call %08x:%u\n", source->sequence, source->cid); stack::destroy(this); return; default: break; } }
bool WorkQueue::threadLoop() { WorkUnit* workUnit; { // acquire lock AutoMutex _l(mLock); for (;;) { if (mCanceled) { return false; } if (!mWorkUnits.isEmpty()) { workUnit = mWorkUnits.itemAt(0); mWorkUnits.removeAt(0); mIdleThreads -= 1; mWorkDequeuedCondition.broadcast(); break; } if (mFinished) { return false; } mWorkChangedCondition.wait(mLock); } } // release lock bool shouldContinue = workUnit->run(); delete workUnit; { // acquire lock AutoMutex _l(mLock); mIdleThreads += 1; if (!shouldContinue) { cancelLocked(); return false; } } // release lock return true; }
status_t WorkQueue::cancel() { AutoMutex _l(mLock); return cancelLocked(); }