コード例 #1
0
ファイル: filesender.cpp プロジェクト: hackshields/antivirus
	//!\brief Функция отправки файла на сервер FileTransfer
	void FileSenderImp::SendFile( std::wstring &fileId,
			FileInfo *filesArray, int filesArraySize,
			int lifeTime )
	{	
		if ( m_connName.localComponentName.empty() || m_connName.remoteComponentName.empty() )
			KLFT_THROW_ERROR( ERR_BAD_FUNCTION_PARAMETERS );

		if ( !KLTR_GetTransport()->IsConnectionActive( m_connName.localComponentName.c_str(),
			m_connName.remoteComponentName.c_str() ) )
			KLFT_THROW_ERROR( ERR_CONNECTION_BROKEN );

		if ( filesArray==NULL || filesArraySize==0 )
			KLFT_THROW_ERROR( ERR_BAD_FUNCTION_PARAMETERS );

		if ( filesArray!=NULL && filesArraySize!=0 )
		{
			for( int i = 0; i < filesArraySize; i++ )
			{
				if( !KLSTD_IfExists( filesArray[i].sourceFilePath.c_str() ) )
				{
					KLFT_THROW_ERROR1( ERR_FILE_NOT_FOUND, filesArray[i].sourceFilePath.c_str() );
				}
			}
		}

		if ( m_pSentFile!=NULL )
			KLFT_THROW_ERROR( ERR_FILE_IS_ALREADY_UPLOADING );

		KLERR_TRY
		{
			KLSTD::AutoCriticalSection autoUnlock( m_pCricSec );

			fileId = KLSTD_CreateGUIDString();
			
			m_fileId = fileId;

			m_filesArray.clear();
			for( int i = 0; i < filesArraySize; i++ )
			{
				m_filesArray.push_back( filesArray[i] );
			}			

			m_pWaitSem = NULL;
			KLSTD_CreateSemaphore( &m_pWaitSem, 0 );

			KLTP_GetThreadsPool()->AddWorker( &m_wId,
					L"File sender worker", new FileSenderWorker( this ), 
					KLTP::ThreadsPool::RunOnce );
		}
		KLERR_CATCH( pError )
		{
			KLERR_SAY_FAILURE( 2, pError );

			m_pSentFile = NULL;

			KLERR_RETHROW();
		}
		KLERR_ENDTRY
	}
コード例 #2
0
ファイル: filesender.cpp プロジェクト: hackshields/antivirus
	//!\brief Получение текущего статуса отправляемого файла
	void FileSenderImp::GetFileStatus( const std::wstring &fileId, 
			SendFileStatus &fileStatus )
	{
		KLSTD::AutoCriticalSection autoUnlock( m_pCricSec );

		if ( m_fileId!=fileId ) KLFT_THROW_ERROR( ERR_WRONG_FILE_ID );
		
		fileStatus = m_fileStatus;			

		if ( fileStatus.sentPercent < PERCENT_FOR_ARCHIVATE && m_pSentFile!=NULL )
		{
			int iArchPercent = m_pSentFile->GetArchivatePercent();
			fileStatus.sentPercent = (int)(((double)iArchPercent / 100.0) * (double)PERCENT_FOR_ARCHIVATE);
		}
	}
コード例 #3
0
ファイル: filesender.cpp プロジェクト: hackshields/antivirus
	//!\brief Функция прерывает отправку файла 
	void FileSenderImp::CancelSendFile( const std::wstring &fileId )
	{
		KLTP::ThreadsPool::WorkerId wId;
		{
			KLSTD::AutoCriticalSection autoUnlock( m_pCricSec );

			if ( m_pSentFile!=NULL && m_pSentFile->GetFileId()!=fileId )
				KLFT_THROW_ERROR( ERR_WRONG_FILE_ID );

			wId = m_wId;
			m_wId = (-1);

			m_stopSendFlag = true;

			m_pSentFile = NULL;

			KLERR_BEGIN
			{
				KLTRAP::TransportProxy trProxy;
				trProxy.Initialize( m_connName.localComponentName.c_str(), m_connName.remoteComponentName.c_str() );

				KLTRAP::TransportConnectionLocker trLocker( &trProxy );

				struct soap* pSoap = trLocker.Get();

				struct klft_CancelServerFileUploadResponse res;

				soap_call_klft_CancelServerFileUpload( pSoap, NULL, NULL,
					(wchar_t *)fileId.c_str(),					
					res );

				trLocker.CheckResult();

				if ( res.error.code )
				{
					KLERR::Error *pError=NULL;
					KLPAR::ExceptionFromSoap( res.error, &pError );
					throw pError;
				}

			}KLERR_ENDT(3);
		}

		KLTP_GetThreadsPool()->DeleteWorker( wId );
		
	}
コード例 #4
0
ファイル: filesender.cpp プロジェクト: hackshields/antivirus
	//!\brief Функция ожидания окончания операции отправки файла на сервер
	bool FileSenderImp::WaitFileSent( const std::wstring &fileId,
		int waitTimeout )
	{
		KLSTD::CAutoPtr<KLSTD::Semaphore>		pWaitSem;
		{
			KLSTD::AutoCriticalSection autoUnlock( m_pCricSec );
			
			if ( m_fileId!=fileId ) KLFT_THROW_ERROR( ERR_WRONG_FILE_ID );

			pWaitSem = m_pWaitSem;

			if ( pWaitSem==NULL )
				KLFT_THROW_ERROR( ERR_WRONG_FILE_ID );

			if ( m_fileStatus.errorCode!=0 ) KLFT_THROW_ERROR_CODE( m_fileStatus.errorCode );
		}

		bool waitRes = pWaitSem->Wait( waitTimeout );
		if ( m_fileStatus.errorCode!=0 ) KLFT_THROW_ERROR_CODE( m_fileStatus.errorCode );

		return waitRes;
	}
コード例 #5
0
bool
QuotaObject::MaybeAllocateMoreSpace(int64_t aOffset, int32_t aCount)
{
  int64_t end = aOffset + aCount;

  QuotaManager* quotaManager = QuotaManager::Get();
  NS_ASSERTION(quotaManager, "Shouldn't be null!");

  MutexAutoLock lock(quotaManager->mQuotaMutex);

  if (mSize >= end || !mOriginInfo) {
    return true;
  }

  GroupInfo* groupInfo = mOriginInfo->mGroupInfo;

  if (groupInfo->IsForPersistentStorage()) {
    uint64_t newUsage = mOriginInfo->mUsage - mSize + end;

    if (newUsage > mOriginInfo->mLimit) {
      // This will block the thread, but it will also drop the mutex while
      // waiting. The mutex will be reacquired again when the waiting is
      // finished.
      if (!quotaManager->LockedQuotaIsLifted()) {
        return false;
      }

      // Threads raced, the origin info removal has been done by some other
      // thread.
      if (!mOriginInfo) {
        // The other thread could allocate more space.
        if (end > mSize) {
          mSize = end;
        }

        return true;
      }

      nsCString group = mOriginInfo->mGroupInfo->mGroup;
      nsCString origin = mOriginInfo->mOrigin;

      mOriginInfo->LockedClearOriginInfos();
      NS_ASSERTION(!mOriginInfo,
                   "Should have cleared in LockedClearOriginInfos!");

      quotaManager->LockedRemoveQuotaForOrigin(PERSISTENCE_TYPE_PERSISTENT,
                                               group, origin);

      // Some other thread could increase the size without blocking (increasing
      // the origin usage without hitting the limit), but no more than this one.
      NS_ASSERTION(mSize < end, "This shouldn't happen!");

      mSize = end;

      return true;
    }

    mOriginInfo->mUsage = newUsage;

    groupInfo->mUsage = groupInfo->mUsage - mSize + end;

    mSize = end;

    return true;
  }

  NS_ASSERTION(groupInfo->mPersistenceType == PERSISTENCE_TYPE_TEMPORARY,
               "Huh?");

  uint64_t delta = end - mSize;

  uint64_t newUsage = mOriginInfo->mUsage + delta;

  // Temporary storage has no limit for origin usage (there's a group and the
  // global limit though).

  uint64_t newGroupUsage = groupInfo->mUsage + delta;

  // Temporary storage has a hard limit for group usage (20 % of the global
  // limit).
  if (newGroupUsage > quotaManager->GetGroupLimit()) {
    return false;
  }

  uint64_t newTemporaryStorageUsage = quotaManager->mTemporaryStorageUsage +
                                      delta;

  if (newTemporaryStorageUsage > quotaManager->mTemporaryStorageLimit) {
    // This will block the thread without holding the lock while waitting.

    nsAutoTArray<OriginInfo*, 10> originInfos;
    uint64_t sizeToBeFreed =
      quotaManager->LockedCollectOriginsForEviction(delta, originInfos);

    if (!sizeToBeFreed) {
      return false;
    }

    NS_ASSERTION(sizeToBeFreed >= delta, "Huh?");

    {
      MutexAutoUnlock autoUnlock(quotaManager->mQuotaMutex);

      for (uint32_t i = 0; i < originInfos.Length(); i++) {
        quotaManager->DeleteTemporaryFilesForOrigin(originInfos[i]->mOrigin);
      }
    }

    // Relocked.

    NS_ASSERTION(mOriginInfo, "How come?!");

    nsTArray<nsCString> origins;
    for (uint32_t i = 0; i < originInfos.Length(); i++) {
      OriginInfo* originInfo = originInfos[i];

      NS_ASSERTION(originInfo != mOriginInfo, "Deleted itself!");

      nsCString group = originInfo->mGroupInfo->mGroup;
      nsCString origin = originInfo->mOrigin;
      quotaManager->LockedRemoveQuotaForOrigin(PERSISTENCE_TYPE_TEMPORARY,
                                               group, origin);

#ifdef DEBUG
      originInfos[i] = nullptr;
#endif

      origins.AppendElement(origin);
    }

    // We unlocked and relocked several times so we need to recompute all the
    // essential variables and recheck the group limit.

    delta = end - mSize;

    newUsage = mOriginInfo->mUsage + delta;

    newGroupUsage = groupInfo->mUsage + delta;

    if (newGroupUsage > quotaManager->GetGroupLimit()) {
      // Unfortunately some other thread increased the group usage in the
      // meantime and we are not below the group limit anymore.

      // However, the origin eviction must be finalized in this case too.
      MutexAutoUnlock autoUnlock(quotaManager->mQuotaMutex);

      quotaManager->FinalizeOriginEviction(origins);

      return false;
    }

    newTemporaryStorageUsage = quotaManager->mTemporaryStorageUsage + delta;

    NS_ASSERTION(newTemporaryStorageUsage <=
                 quotaManager->mTemporaryStorageLimit, "How come?!");

    // Ok, we successfully freed enough space and the operation can continue
    // without throwing the quota error.

    mOriginInfo->mUsage = newUsage;
    groupInfo->mUsage = newGroupUsage;
    quotaManager->mTemporaryStorageUsage = newTemporaryStorageUsage;;

    // Some other thread could increase the size in the meantime, but no more
    // than this one.
    NS_ASSERTION(mSize < end, "This shouldn't happen!");
    mSize = end;

    // Finally, release IO thread only objects and allow next synchronized
    // ops for the evicted origins.
    MutexAutoUnlock autoUnlock(quotaManager->mQuotaMutex);

    quotaManager->FinalizeOriginEviction(origins);

    return true;
  }

  mOriginInfo->mUsage = newUsage;
  groupInfo->mUsage = newGroupUsage;
  quotaManager->mTemporaryStorageUsage = newTemporaryStorageUsage;

  mSize = end;

  return true;
}
コード例 #6
0
ファイル: QuotaObject.cpp プロジェクト: LordJZ/gecko-dev
bool
QuotaObject::MaybeUpdateSize(int64_t aSize, bool aTruncate)
{
  QuotaManager* quotaManager = QuotaManager::Get();
  MOZ_ASSERT(quotaManager);

  MutexAutoLock lock(quotaManager->mQuotaMutex);

  if (mSize == aSize) {
    return true;
  }

  if (!mOriginInfo) {
    mSize = aSize;
    return true;
  }

  GroupInfo* groupInfo = mOriginInfo->mGroupInfo;
  MOZ_ASSERT(groupInfo);

  if (mSize > aSize) {
    if (aTruncate) {
      const int64_t delta = mSize - aSize;

      AssertNoUnderflow(quotaManager->mTemporaryStorageUsage, delta);
      quotaManager->mTemporaryStorageUsage -= delta;

      AssertNoUnderflow(groupInfo->mUsage, delta);
      groupInfo->mUsage -= delta;

      AssertNoUnderflow(mOriginInfo->mUsage, delta);
      mOriginInfo->mUsage -= delta;

      mSize = aSize;
    }
    return true;
  }

  MOZ_ASSERT(mSize < aSize);

  nsRefPtr<GroupInfo> complementaryGroupInfo =
    groupInfo->mGroupInfoPair->LockedGetGroupInfo(
      ComplementaryPersistenceType(groupInfo->mPersistenceType));

  uint64_t delta = aSize - mSize;

  AssertNoOverflow(mOriginInfo->mUsage, delta);
  uint64_t newUsage = mOriginInfo->mUsage + delta;

  // Temporary storage has no limit for origin usage (there's a group and the
  // global limit though).

  AssertNoOverflow(groupInfo->mUsage, delta);
  uint64_t newGroupUsage = groupInfo->mUsage + delta;

  uint64_t groupUsage = groupInfo->mUsage;
  if (complementaryGroupInfo) {
    AssertNoOverflow(groupUsage, complementaryGroupInfo->mUsage);
    groupUsage += complementaryGroupInfo->mUsage;
  }

  // Temporary storage has a hard limit for group usage (20 % of the global
  // limit).
  AssertNoOverflow(groupUsage, delta);
  if (groupUsage + delta > quotaManager->GetGroupLimit()) {
    return false;
  }

  AssertNoOverflow(quotaManager->mTemporaryStorageUsage, delta);
  uint64_t newTemporaryStorageUsage = quotaManager->mTemporaryStorageUsage +
                                      delta;

  if (newTemporaryStorageUsage > quotaManager->mTemporaryStorageLimit) {
    // This will block the thread without holding the lock while waitting.

    nsAutoTArray<OriginInfo*, 10> originInfos;
    uint64_t sizeToBeFreed =
      quotaManager->LockedCollectOriginsForEviction(delta, originInfos);

    if (!sizeToBeFreed) {
      return false;
    }

    NS_ASSERTION(sizeToBeFreed >= delta, "Huh?");

    {
      MutexAutoUnlock autoUnlock(quotaManager->mQuotaMutex);

      for (uint32_t i = 0; i < originInfos.Length(); i++) {
        OriginInfo* originInfo = originInfos[i];

        quotaManager->DeleteFilesForOrigin(
                                       originInfo->mGroupInfo->mPersistenceType,
                                       originInfo->mOrigin);
      }
    }

    // Relocked.

    NS_ASSERTION(mOriginInfo, "How come?!");

    nsTArray<OriginParams> origins;
    for (uint32_t i = 0; i < originInfos.Length(); i++) {
      OriginInfo* originInfo = originInfos[i];

      NS_ASSERTION(originInfo != mOriginInfo, "Deleted itself!");

      PersistenceType persistenceType =
        originInfo->mGroupInfo->mPersistenceType;
      nsCString group = originInfo->mGroupInfo->mGroup;
      nsCString origin = originInfo->mOrigin;
      bool isApp = originInfo->mIsApp;
      quotaManager->LockedRemoveQuotaForOrigin(persistenceType, group, origin);

#ifdef DEBUG
      originInfos[i] = nullptr;
#endif

      origins.AppendElement(OriginParams(persistenceType, origin, isApp));
    }

    // We unlocked and relocked several times so we need to recompute all the
    // essential variables and recheck the group limit.

    AssertNoUnderflow(aSize, mSize);
    delta = aSize - mSize;

    AssertNoOverflow(mOriginInfo->mUsage, delta);
    newUsage = mOriginInfo->mUsage + delta;

    AssertNoOverflow(groupInfo->mUsage, delta);
    newGroupUsage = groupInfo->mUsage + delta;

    groupUsage = groupInfo->mUsage;
    if (complementaryGroupInfo) {
      AssertNoOverflow(groupUsage, complementaryGroupInfo->mUsage);
      groupUsage += complementaryGroupInfo->mUsage;
    }

    AssertNoOverflow(groupUsage, delta);
    if (groupUsage + delta > quotaManager->GetGroupLimit()) {
      // Unfortunately some other thread increased the group usage in the
      // meantime and we are not below the group limit anymore.

      // However, the origin eviction must be finalized in this case too.
      MutexAutoUnlock autoUnlock(quotaManager->mQuotaMutex);

      quotaManager->FinalizeOriginEviction(origins);

      return false;
    }

    AssertNoOverflow(quotaManager->mTemporaryStorageUsage, delta);
    newTemporaryStorageUsage = quotaManager->mTemporaryStorageUsage + delta;

    NS_ASSERTION(newTemporaryStorageUsage <=
                 quotaManager->mTemporaryStorageLimit, "How come?!");

    // Ok, we successfully freed enough space and the operation can continue
    // without throwing the quota error.
    mOriginInfo->mUsage = newUsage;
    groupInfo->mUsage = newGroupUsage;
    quotaManager->mTemporaryStorageUsage = newTemporaryStorageUsage;;

    // Some other thread could increase the size in the meantime, but no more
    // than this one.
    MOZ_ASSERT(mSize < aSize);
    mSize = aSize;

    // Finally, release IO thread only objects and allow next synchronized
    // ops for the evicted origins.
    MutexAutoUnlock autoUnlock(quotaManager->mQuotaMutex);

    quotaManager->FinalizeOriginEviction(origins);

    return true;
  }

  mOriginInfo->mUsage = newUsage;
  groupInfo->mUsage = newGroupUsage;
  quotaManager->mTemporaryStorageUsage = newTemporaryStorageUsage;

  mSize = aSize;

  return true;
}