// ---------------------------------------------------------------------------- // CWmDrmDlaDefaultHttpManager::Stop // This method should be used instead of Cancel. // ---------------------------------------------------------------------------- void CWmDrmDlaDefaultHttpManager::Stop() { LOGFN( "CWmDrmDlaDefaultHttpManager::Stop" ); // Make sure Stop was not called from a callback ASSERT( !iInCallback ); if ( IsActive() ) { // We are still establishing the connection, cancel the active object Cancel(); } else { // The active object is not active - we are past the setup phase if ( iTransactionOpen ) { iHttpTransaction.Cancel(); // Only generate the callback if there was a transaction going on, // otherwise the client will get a callback without previously // calling StartL HandleDownloadComplete( KErrCancel ); } } // Close the HTTP session in use iHttpSession.Close(); CleanupConnection(); DeleteUsernamePassword(); iState = EConstructed; }
// ---------------------------------------------------------------------------- // CWmDrmDlaDefaultHttpManager::CleanupTransaction // ---------------------------------------------------------------------------- void CWmDrmDlaDefaultHttpManager::CleanupTransaction() { LOGFN( "CWmDrmDlaDefaultHttpManager::CleanupTransaction" ); if ( iBody ) { iBody->ReleaseData(); iBody = NULL; } // Release HTTP transaction & session resources delete iSrcAddress; iSrcAddress = NULL; TInt nofheaders = iHdrValues.Count(); for ( TInt i = 0; i < nofheaders; i++ ) { delete iHdrValues[i]; } // set to empty iHdrValues.Reset(); iHdrFields.Reset(); iHttpTransaction.Close(); if ( !iKeepAlive ) { CleanupConnection(); iState = ESubmit == iState ? EConstructed : iState; } else if ( ESubmit == iState ) { // end of a transaction iState = EOpen; } else { // do nothing. This is to get rid of a PC-Lint warning } iTransactionOpen = EFalse; }
// ---------------------------------------------------------------------------- // CWmDrmDlaDefaultHttpManager::DoStartL // ---------------------------------------------------------------------------- void CWmDrmDlaDefaultHttpManager::DoStartL( const TDesC8& aUrl, const RArray<CWmDrmDlaDefaultHttpManager::THeader>& aHeaders ) { LOGFN( "CWmDrmDlaDefaultHttpManager::DoStartL" ); CleanupTransaction(); // Store callers URL iSrcAddress = aUrl.AllocL(); // Store headers TInt nofheaders = aHeaders.Count(); for ( TInt i = 0; i < nofheaders; i++ ) { iHdrFields.AppendL( aHeaders[i].iField ); iHdrValues.AppendL( aHeaders[i].iVal.AllocL() ); } if ( (iState == EOpen) && iKeepAlive ) { TConnectionInfo connectionInfo; TRAPD(err, GetConnectionInfoL(connectionInfo) ); if ( err || ( connectionInfo.iIapId != iIapNumber && iIapNumber != 0 && connectionInfo.iIapId != 0 ) ) { CleanupConnection(); iState = EStart; } } else { iState = EConstructed == iState ? EStart : EOpen; } iError = KErrNone; iCredentialsOk = ETrue; CompleteSelf(); }
DWORD CNdasEventPublisher::OnTaskStart() { _ASSERTE(NULL != m_hSemQueue && "Don't forget to call initialize()."); // Queue Semaphore, Terminating Thread, Pipe Instances(MAX...) HANDLE hWaitHandles[2 + MAX_NDAS_EVENT_PIPE_INSTANCES]; hWaitHandles[0] = m_hTaskTerminateEvent; hWaitHandles[1] = m_hSemQueue; // // initial pipe instance // m_PipeData.clear(); BOOL fSuccess = AcceptNewConnection(); if (!fSuccess) { DPErrorEx(_T("Creating a first pipe instance failed: ")); return -1; } BOOL bTerminate(FALSE); while (FALSE == bTerminate) { DWORD dwWaitHandles = 2 + m_PipeData.size(); for (DWORD i = 0; i < m_PipeData.size(); ++i) { hWaitHandles[i + 2] = m_PipeData[i]->overlapped.hEvent; } DWORD dwWaitResult = ::WaitForMultipleObjects( dwWaitHandles, hWaitHandles, FALSE, m_dwPeriod); if (dwWaitResult == WAIT_OBJECT_0) { // // Terminate Thread // bTerminate = TRUE; } else if (dwWaitResult == WAIT_OBJECT_0 + 1) { // // Event Message is queued // while (TRUE) { m_queueLock.Lock(); bool bEmpty = m_EventMessageQueue.empty(); if (bEmpty) { m_queueLock.Unlock(); break; } NDAS_EVENT_MESSAGE message = m_EventMessageQueue.front(); m_EventMessageQueue.pop(); m_queueLock.Unlock(); Publish(&message); } } else if (dwWaitResult >= WAIT_OBJECT_0 + 2 && dwWaitResult < WAIT_OBJECT_0 + 2 + m_PipeData.size()) { DWORD dwPipe = dwWaitResult - WAIT_OBJECT_0 - 2; DPInfo(_FT("Event Client %d\n"), dwPipe); CLIENT_DATA* pCurClientData = m_PipeData[dwPipe]; DPInfo(_FT("Connected: %d\n"), pCurClientData->bConnected); fSuccess = ::ResetEvent(pCurClientData->overlapped.hEvent); _ASSERT(fSuccess); if (!pCurClientData->bConnected) { // // create another instance // fSuccess = AcceptNewConnection(); if (!fSuccess) { DPWarningEx(_FT("Creating another pipe instance failed: ")); DPWarning(_FT("No more event subscribers can be accepted.\n")); } // AcceptNewConnection will invalidate pCurClientData; pCurClientData = m_PipeData.at(dwPipe); // // Accepting connection // pCurClientData->bConnected = TRUE; fSuccess = ::ResetEvent(pCurClientData->overlapped.hEvent); _ASSERT(fSuccess); // // Send a version event for connected client // fSuccess = SendVersionInfo( pCurClientData->hPipe, &pCurClientData->overlapped); // // Any failure will disconnect the client // if (!fSuccess && ERROR_IO_PENDING != ::GetLastError()) { ClientDataVector::iterator itr = m_PipeData.begin(); CleanupConnection(pCurClientData); while (itr != m_PipeData.end()) { if ((CLIENT_DATA*)*itr == pCurClientData) { m_PipeData.erase(itr); break; } ++itr; } DPInfo(_FT("Accepted removed event subscriber.\n")); } else { DPInfo(_FT("Accepted new event subscriber.\n")); } } else { } // ignore other status } else if (WAIT_TIMEOUT == dwWaitResult) { NDAS_EVENT_MESSAGE msg = {0}; msg.EventType = NDAS_EVENT_TYPE_PERIODIC; Publish(&msg); } else { // // Error // } } // // TODO: Add cleanup // DWORD nPipeData = m_PipeData.size(); ClientDataVector::iterator itr = m_PipeData.begin(); while (itr != m_PipeData.end()) { CleanupConnection(*itr); ++itr; } m_PipeData.clear(); _tprintf(TEXT("Terminating Publisher Thread...\n")); return 0; }
void CNdasEventPublisher::Publish(const PNDAS_EVENT_MESSAGE pMessage) { DPInfo(_FT("Publishing Event: %s\n"), NdasEventTypeString(pMessage->EventType)); // // sent the message to the connected pipes // for (ClientDataVector::iterator itr = m_PipeData.begin(); itr != m_PipeData.end();) // // do not forward the iterator here when erasing some // elements // itr2 = v.erase(itr); // itr2 has a forwarded iterator from itr // { CLIENT_DATA* pClientData = *itr; if (pClientData->bConnected) { DWORD cbWritten; BOOL fSuccess = ::WriteFile( pClientData->hPipe, pMessage, sizeof(NDAS_EVENT_MESSAGE), &cbWritten, &pClientData->overlapped); if (!fSuccess && ERROR_IO_PENDING != ::GetLastError()) { DPErrorEx(_FT("Writing to a pipe failed: ")); DPInfo(_FT("Detaching an event subscriber.\n")); CleanupConnection(pClientData); // // erasing an element will automatically // forward the vector // (actually, itr remains the same, but the itr is // a next elemen) itr = m_PipeData.erase(itr); // // create another instance // fSuccess = AcceptNewConnection(); if (!fSuccess) { DPWarningEx(_FT("Creating another pipe instance failed: ")); DPWarning(_FT("No more event subscribers can be accepted.\n")); } } else { // // forward the iterator if we did erase // DPInfo(_FT("Event written to a pipe %p.\n"), (*itr)->hPipe); ++itr; } } else { // // forward the iterator if not connected // ++itr; } } }