Esempio n. 1
0
	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;
	}
Esempio n. 2
0
/**
	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;
		}