int IOCPConnection::Write( const void* pBuf, size_t len ) { if( !IsConnected() ) return -1; if( len == 0 ) return 0; THREAD_SYNC( m_sendCS ); if( m_bAsyncCloseSignal ) return -1; uint32 prevSize = m_pSendQueue->Size(); uint32 sendLen = len; if( m_pSendQueue->FreeSize() < len ) { // TOOD+ 큐가 넘치면 무시한다(WaitQueue 처리 해야함) sendLen = m_pSendQueue->FreeSize(); m_pSendQueue->Write( pBuf, sendLen ); uint32 waitPrevSize = m_pWaitQueue->Size(); if( waitPrevSize + (len - sendLen) > MAXDWORD ) { AsyncClose(); return -1; } m_pWaitQueue->Write( (char*)pBuf+sendLen, len-sendLen ); } else { if( m_pSendQueue->Write( pBuf, len ) != len ) { OnDisconnect( -1 ); return -1; } } if( !m_bSendPending ) { ProcWriteFile(); } return len; }
/** Handle the requests for this channel. @param aFunction The operation the LDD should perform. @param a1 The first argument for the operation. @param a2 The second argument for the operation. @return KErrNone on success or one of the system wide error codes. */ TInt DDefragChannel::Request(TInt aFunction, TAny* a1, TAny* a2) { TInt r = KErrNone; NKern::ThreadEnterCS(); Kern::SemaphoreWait(*iDefragSemaphore); if (!iDefragDfcFree && aFunction != RDefragChannel::EControlGeneralDefragDfcComplete) {// Only allow a single defrag operation at a time. r = KErrInUse; goto exit; } switch (aFunction) { case RDefragChannel::EControlGeneralDefragDfc: // Queue a defrag operation so that on completion it queues a // DFC on this driver. iRequestThread = &Kern::CurrentThread(); iRequestThread->Open(); // Open a reference on this channel to stop the destructor running before // the defrag request has completed. Open(); r = iCompleteReq->SetStatus((TRequestStatus*)a1); if (r == KErrNone) r = iDefragReq.DefragRam(&iDefragCompleteDfc, KDefragRamThreadPriority); if (r != KErrNone) {// defrag operation didn't start so close all openned handles AsyncClose(); iRequestThread->AsyncClose(); iRequestThread = NULL; } else iDefragDfcFree = EFalse; break; case RDefragChannel::EControlGeneralDefragDfcComplete: if (iRequestThread != NULL) {// The defrag dfc hasn't completed so this shouldn't have been invoked. r = KErrGeneral; } else { iDefragDfcFree = ETrue; } break; case RDefragChannel::EControlGeneralDefragSem: {// Queue a defrag operation so that it will signal a fast mutex once // it has completed. NFastSemaphore sem; NKern::FSSetOwner(&sem, 0); r = iDefragReq.DefragRam(&sem, KDefragRamThreadPriority); if (r != KErrNone) {// Error occurred attempting to queue the defrag operation. break; } // Defrag operation has now been queued so wait for it to finish. // Could do some extra kernel side work here before waiting on the // semaphore. NKern::FSWait(&sem); r = iDefragReq.Result(); } break; case RDefragChannel::EControlGeneralDefrag: // Synchronously perform a defrag. { r = iDefragReq.DefragRam(KDefragRamThreadPriority); } break; case RDefragChannel::EControlAllocLowestZone: // Allocate from the lowest preference zone r = DoAllocLowestZone(); break; case RDefragChannel::EControlClaimLowestZone: // Claims the lowest preference zone r = DoClaimLowestZone(); break; case RDefragChannel::EControlCloseChunk: // Have finished with the chunk so close it then free the RAM mapped by it r = DoChunkClose(); TRACE( if (r != KErrNone) {Kern::Printf("ChunkClose returns %d", r);}); break; default: r=KErrNotSupported; break; }