ELocalizationServiceOperationCommandResult::Type FOneSkyLocalizationServiceProvider::Execute(const TSharedRef<ILocalizationServiceOperation, ESPMode::ThreadSafe>& InOperation, const TArray<FLocalizationServiceTranslationIdentifier>& InTranslationIds, ELocalizationServiceOperationConcurrency::Type InConcurrency, const FLocalizationServiceOperationComplete& InOperationCompleteDelegate)
{
	if(!IsEnabled())
	{
		return ELocalizationServiceOperationCommandResult::Failed;
	}

	// Query to see if the we allow this operation
	TSharedPtr<IOneSkyLocalizationServiceWorker, ESPMode::ThreadSafe> Worker = CreateWorker(InOperation->GetName());
	if(!Worker.IsValid())
	{
		// this operation is unsupported by this source control provider
		FFormatNamedArguments Arguments;
		Arguments.Add( TEXT("OperationName"), FText::FromName(InOperation->GetName()) );
		Arguments.Add( TEXT("ProviderName"), FText::FromName(GetName()) );
		FMessageLog("LocalizationService").Error(FText::Format(LOCTEXT("UnsupportedOperation", "Operation '{OperationName}' not supported by source control provider '{ProviderName}'"), Arguments));
		return ELocalizationServiceOperationCommandResult::Failed;
	}

	// fire off operation
	if(InConcurrency == ELocalizationServiceOperationConcurrency::Synchronous)
	{
		FOneSkyLocalizationServiceCommand* Command = new FOneSkyLocalizationServiceCommand(InOperation, Worker.ToSharedRef());
		Command->bAutoDelete = false;
		Command->OperationCompleteDelegate = InOperationCompleteDelegate;
		return ExecuteSynchronousCommand(*Command, InOperation->GetInProgressString(), true);
	}
	else
	{
		FOneSkyLocalizationServiceCommand* Command = new FOneSkyLocalizationServiceCommand(InOperation, Worker.ToSharedRef());
		Command->bAutoDelete = true;
		Command->OperationCompleteDelegate = InOperationCompleteDelegate;
		return IssueCommand(*Command, false);
	}
}
shared_ptr<WorkerThread> WorkerManager::GetWorker()
{
	if(InactiveWorkerExists()) {
		return GetInactiveWorker();
	} else {
		return CreateWorker();
	}
}
/****************************************************************************
 * Function: ThreadPoolAddPersistent
 *
 *  Description:
 *      Adds a long term job to the thread pool.
 *      Job will be run as soon as possible.
 *      Call will block until job is scheduled.
 *  Parameters:
 *      tp - valid thread pool pointer
 *      job-> valid ThreadPoolJob pointer with following fields
 *          func - ThreadFunction to run
 *          arg - argument to function.
 *          priority - priority of job.
 *          free_function - function to use when freeing argument
 *  Returns:
 *      0 on success, nonzero on failure
 *      EOUTOFMEM not enough memory to add job.
 *      EMAXTHREADS not enough threads to add persistent job.
 *****************************************************************************/
int ThreadPoolAddPersistent( ThreadPool *tp, ThreadPoolJob *job, int *jobId )
{
	int tempId = -1;
	ThreadPoolJob *temp = NULL;

	assert( tp != NULL );
	assert( job != NULL );
	if( ( tp == NULL ) || ( job == NULL ) ) {
		return EINVAL;
	}

	if( jobId == NULL ) {
		jobId = &tempId;
	}

	*jobId = INVALID_JOB_ID;

	ithread_mutex_lock( &tp->mutex );

	assert( job->priority == LOW_PRIORITY ||
	        job->priority == MED_PRIORITY ||
	        job->priority == HIGH_PRIORITY );

	// Create A worker if less than max threads running
	if( tp->totalThreads < tp->attr.maxThreads ) {
		CreateWorker( tp );
	} else {
		// if there is more than one worker thread
		// available then schedule job, otherwise fail
		if( tp->totalThreads - tp->persistentThreads - 1 == 0 ) {
			ithread_mutex_unlock( &tp->mutex );
			return EMAXTHREADS;
		}
	}

	temp = CreateThreadPoolJob( job, tp->lastJobId, tp );
	if( temp == NULL ) {
		ithread_mutex_unlock( &tp->mutex );
		return EOUTOFMEM;
	}

	tp->persistentJob = temp;

	// Notify a waiting thread
	ithread_cond_signal( &tp->condition );

	// wait until long job has been picked up
	while( tp->persistentJob != NULL ) {
		ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex );
	}

	*jobId = tp->lastJobId++;
	ithread_mutex_unlock( &tp->mutex );

	return 0;
}
Exemple #4
0
void RBench::Start(BOOLEAN trace) {
//    clock_t t1, t2, t3, t4;
    TaskState *t;
    Packet *workQ;

    if (trace) InitTrace(); else tracing = FALSE;
    InitScheduler();
//    t1 = clock();
//    printf("\nRichards benchmark: initializing...\n");
    t = new TaskState; t->Running();				// Idler
    CreateIdler(Idler, 0, NoWork, t);

    workQ = new Packet(NoWork, Worker, WorkPacket);		// Worker
    workQ = new Packet(workQ , Worker, WorkPacket);
    t = new TaskState; t->WaitingWithPacket();
    CreateWorker(Worker, 1000, workQ, t);

    workQ = new Packet(NoWork, DeviceA, DevicePacket);		// HandlerA
    workQ = new Packet(workQ , DeviceA, DevicePacket);
    workQ = new Packet(workQ , DeviceA, DevicePacket);
    t = new TaskState; t->WaitingWithPacket();
    CreateHandler(HandlerA, 2000, workQ, t);

    workQ = new Packet(NoWork, DeviceB, DevicePacket);		// HandlerB
    workQ = new Packet(workQ , DeviceB, DevicePacket);
    workQ = new Packet(workQ , DeviceB, DevicePacket);
    t = new TaskState; t->WaitingWithPacket();
    CreateHandler(HandlerB, 3000, workQ, t);

    t = new TaskState; t->Waiting();				// DeviceA
    CreateDevice(DeviceA, 4000, NoWork, t);
    t = new TaskState; t->Waiting();				// DeviceB
    CreateDevice(DeviceB, 5000, NoWork, t);

//    printf("starting...\n");
//    t2 = clock();
    Schedule();
//    t3 = clock();
//    printf("done.\n");

//    printf("QueuePacketCount = %d, HoldCount = %d.\nThese results are %s",
//           queuePacketCount, holdCount,
//           (queuePacketCount == 23246 && holdCount == 9297) ? 
//                "correct." : "wrong!"
//          );
    if (! (queuePacketCount == 23246 && holdCount == 9297)) {
      printf("error: richards results are incorrect\n");
    }

//    t4 = clock();
//    printf("\nScheduler time = %g seconds, total time = %g\n",
//           (double)(t3 - t2) / CLK_TCK,
//           (double)(t4 - t1) / CLK_TCK);
}
/****************************************************************************
 * Function: AddWorker
 *
 *  Description:
 *      Determines whether or not a thread should be added
 *      based on the jobsPerThread ratio.
 *      Adds a thread if appropriate.
 *      Internal to Thread Pool.
 *  Parameters:
 *      ThreadPool* tp
 *
 *****************************************************************************/
static void AddWorker( ThreadPool *tp )
{
	int jobs = 0;
	int threads = 0;

	assert( tp != NULL );

	jobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size;
	threads = tp->totalThreads - tp->persistentThreads;
	while( threads == 0 || (jobs / threads) >= tp->attr.jobsPerThread ) {
		if( CreateWorker( tp ) != 0 ) {
			return;
		}
		threads++;
	}
}
/****************************************************************************
 * Function: ThreadPoolSetAttr
 *
 *  Description:
 *      Sets the attributes for the thread pool.
 *      Only affects future calculations.
 *  Parameters:
 *      tp - valid thread pool pointer
 *      attr - pointer to attributes, null sets attributes to default.
 *  Returns:
 *      0 on success, nonzero on failure
 *      Returns INVALID_POLICY if policy can not be set.
 *****************************************************************************/
int ThreadPoolSetAttr( ThreadPool *tp, ThreadPoolAttr *attr )
{
	int retCode = 0;
	ThreadPoolAttr temp;
	int i = 0;

	assert( tp != NULL );
	if( tp == NULL ) {
		return EINVAL;
	}
	ithread_mutex_lock( &tp->mutex );

	if( attr != NULL ) {
		temp = ( *attr );
	} else {
		TPAttrInit( &temp );
	}

	if( SetPolicyType( temp.schedPolicy ) != 0 ) {
		ithread_mutex_unlock( &tp->mutex );

		return INVALID_POLICY;
	}

	tp->attr = ( temp );

	// add threads
	if( tp->totalThreads < tp->attr.minThreads )
	{
		for( i = tp->totalThreads; i < tp->attr.minThreads; i++ ) {
			if( ( retCode = CreateWorker( tp ) ) != 0 ) {
				break;
			}
		}
	}

	// signal changes 
	ithread_cond_signal( &tp->condition ); 
	ithread_mutex_unlock( &tp->mutex );

	if( retCode != 0 ) {
		// clean up if the min threads could not be created
		ThreadPoolShutdown( tp );
	}

	return retCode;
}
Exemple #7
0
int ThreadPoolAddPersistent(ThreadPool *tp, ThreadPoolJob *job, int *jobId)
{
	int ret = 0;
	int tempId = -1;
	ThreadPoolJob *temp = NULL;

	if (!tp || !job) {
		return EINVAL;
	}
	if (!jobId) {
		jobId = &tempId;
	}
	*jobId = INVALID_JOB_ID;

	ithread_mutex_lock(&tp->mutex);

	/* Create A worker if less than max threads running */
	if (tp->totalThreads < tp->attr.maxThreads) {
		CreateWorker(tp);
	} else {
		/* if there is more than one worker thread
		 * available then schedule job, otherwise fail */
		if (tp->totalThreads - tp->persistentThreads - 1 == 0) {
			ret = EMAXTHREADS;
			goto exit_function;
		}
	}
	temp = CreateThreadPoolJob(job, tp->lastJobId, tp);
	if (!temp) {
		ret = EOUTOFMEM;
		goto exit_function;
	}
	tp->persistentJob = temp;

	/* Notify a waiting thread */
	ithread_cond_signal(&tp->condition);

	/* wait until long job has been picked up */
	while (tp->persistentJob)
		ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex);
	*jobId = tp->lastJobId++;

exit_function:
	ithread_mutex_unlock(&tp->mutex);

	return ret;
}
Exemple #8
0
int CMapFileIO::SaveMap(const CLevelMap &map, HANDLE hFile) const
{
	XML_MANAGER_HANDLE xml = 0;
	std::wostringstream os;
	xml = CreateWorker();
	if(!xml)
		return 1;
	BeginDoc(xml, L"map");
	XML_NODE_HANDLE root = GetRootNode(xml);
	if(!root)
		return 1;
	XML_NODE_HANDLE node;

	int w, h;
	D3DXVECTOR3 pos;

	//dimensions
	node = AddNode(xml, root, L"dimensions");
	if(!node)
		return 1;
	w = map.GetWidth();
	h = map.GetHeight();
	os << w;
	SetNodeAttr(xml, node, L"width", os.str().c_str());
	os.str(L"");
	os << h;
	SetNodeAttr(xml, node, L"height", os.str().c_str());
	os.str(L"");
	ReleaseNode(node);

	//background
	SaveBackground(*map.GetBackground(), xml, root);

	//player
	SavePlayer( map.GetPlayer(), xml, root );

	//tiles
	SaveTileList(map.m_pTiles, xml, root);

	//creatures
	SaveCreatureList(map.m_pCreatures, xml, root);

	SaveToFileHandle(xml, hFile, true);
	CloseHandle(hFile);
	ReleaseWorker(xml);
	return 0;
}
Exemple #9
0
/*!
 * \brief Determines whether or not a thread should be added based on the
 * jobsPerThread ratio. Adds a thread if appropriate.
 *
 * \remark The ThreadPool object mutex must be locked prior to calling this
 * function.
 *
 * \internal
 */
static void AddWorker(
	/*! A pointer to the ThreadPool object. */
	ThreadPool *tp)
{
	long jobs = 0;
	int threads = 0;

	jobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size;
	threads = tp->totalThreads - tp->persistentThreads;
	while (threads == 0 ||
	       (jobs / threads) >= tp->attr.jobsPerThread ||
	       (tp->totalThreads == tp->busyThreads) ) {
		if (CreateWorker(tp) != 0) {
			return;
		}
		threads++;
	}
}
ECommandResult::Type FSubversionSourceControlProvider::Execute( const TSharedRef<ISourceControlOperation, ESPMode::ThreadSafe>& InOperation, const TArray<FString>& InFiles, EConcurrency::Type InConcurrency, const FSourceControlOperationComplete& InOperationCompleteDelegate )
{
	if(!IsEnabled())
	{
		return ECommandResult::Failed;
	}

	if(!SubversionSourceControlUtils::CheckFilenames(InFiles))
	{
		return ECommandResult::Failed;
	}

	TArray<FString> AbsoluteFiles = SourceControlHelpers::AbsoluteFilenames(InFiles);

	// Query to see if the we allow this operation
	TSharedPtr<ISubversionSourceControlWorker, ESPMode::ThreadSafe> Worker = CreateWorker(InOperation->GetName());
	if(!Worker.IsValid())
	{
		// this operation is unsupported by this source control provider
		FFormatNamedArguments Arguments;
		Arguments.Add( TEXT("OperationName"), FText::FromName(InOperation->GetName()) );
		Arguments.Add( TEXT("ProviderName"), FText::FromName(GetName()) );
		FMessageLog("SourceControl").Error(FText::Format(LOCTEXT("UnsupportedOperation", "Operation '{OperationName}' not supported by source control provider '{ProviderName}'"), Arguments));
		return ECommandResult::Failed;
	}

	// fire off operation
	if(InConcurrency == EConcurrency::Synchronous)
	{
		FSubversionSourceControlCommand* Command = new FSubversionSourceControlCommand(InOperation, Worker.ToSharedRef());
		Command->bAutoDelete = false;
		Command->Files = AbsoluteFiles;
		Command->OperationCompleteDelegate = InOperationCompleteDelegate;
		return ExecuteSynchronousCommand(*Command, InOperation->GetInProgressString(), true);
	}
	else
	{
		FSubversionSourceControlCommand* Command = new FSubversionSourceControlCommand(InOperation, Worker.ToSharedRef());
		Command->bAutoDelete = true;
		Command->Files = AbsoluteFiles;
		Command->OperationCompleteDelegate = InOperationCompleteDelegate;
		return IssueCommand(*Command, false);
	}
}
Exemple #11
0
int ThreadPoolSetAttr(ThreadPool *tp, ThreadPoolAttr *attr)
{
	int retCode = 0;
	ThreadPoolAttr temp;
	int i = 0;

	if (!tp)
		return EINVAL;

	ithread_mutex_lock(&tp->mutex);

	if (attr)
		temp = *attr;
	else
		TPAttrInit(&temp);
	if (SetPolicyType(temp.schedPolicy) != 0) {
		ithread_mutex_unlock(&tp->mutex);
		return INVALID_POLICY;
	}
	tp->attr = temp;
	/* add threads */
	if (tp->totalThreads < tp->attr.minThreads) {
		for (i = tp->totalThreads; i < tp->attr.minThreads; i++) {
			retCode = CreateWorker(tp);
			if (retCode != 0) {
				break;
			}
		}
	}
	/* signal changes */
	ithread_cond_signal(&tp->condition); 

	ithread_mutex_unlock(&tp->mutex);

	if (retCode != 0)
		/* clean up if the min threads could not be created */
		ThreadPoolShutdown(tp);

	return retCode;
}
Exemple #12
0
int CMapFileIO::LoadTileTypesDict(CTileTypesDict& Dict) const
{
	WCHAR* fname = new WCHAR[MAX_PATH];
	wsprintf(fname, L"%s\\tiles\\*", g_ContentPath);
	WIN32_FIND_DATA ffd;

	XML_MANAGER_HANDLE xml = 0;
	HANDLE file = INVALID_HANDLE_VALUE;
	WCHAR* listpath = new WCHAR[MAX_PATH];
	WCHAR* imgpath = new WCHAR[MAX_PATH];
	CTileType *t;

	HANDLE search = FindFirstFile(fname, &ffd);
	do
	{
		if((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && ffd.cFileName[0] != '.')
		{
			wsprintf(listpath, L"%s\\tiles\\%s\\tiles.xml", g_ContentPath, ffd.cFileName);
			file = INVALID_HANDLE_VALUE;
			file = CreateFile(listpath, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
			if(file == INVALID_HANDLE_VALUE)
				return 1;   
			xml = 0;
			xml = CreateWorker();
			if(!xml)
				return 1;
			DWORD res = ReadFromFileHandle(xml, file);
			if(res != ERROR_SUCCESS) 
				return 1;
			CloseHandle(file);
			XML_NODE_HANDLE node = RetrieveNode(xml, 0, L"tile");
			while(node)
			{
				//name
				LPWSTR name = GetNodeAttr(xml, node, L"name");
				XML_NODE_HANDLE hImg = RetrieveNode(xml, node, L"img");
				XML_NODE_HANDLE hSt = RetrieveNode(xml, node, L"stats");
				XML_NODE_HANDLE hMov = RetrieveNode(xml, node, L"movement");
				//img
				LPWSTR img = GetNodeAttr(xml, hImg, L"path");
				//hp
				LPWSTR hpt = GetNodeAttr(xml, hSt, L"hp");
				int hp = _wtoi(hpt);
				//hrd
				LPWSTR hrdt = GetNodeAttr(xml, hSt, L"hardness");
				int hrd = _wtoi(hrdt);
				LPWSTR rgnt = GetNodeAttr(xml, hSt, L"regenspeed");
				float regenval = (float)_wtof(rgnt);

				LPWSTR blok = GetNodeAttr(xml, hMov, L"blocks");
				bool block = _wcsicmp(blok, L"YES") == 0;

				t = Dict.Give(name);
				t->SetHardness(hrd);
				t->SetMaxHP(hp);
				t->SetRegen(regenval);
				wsprintf(imgpath, L"tiles\\%s\\%s", ffd.cFileName, img);
				t->SetImageFile(imgpath);
				t->SetType(ffd.cFileName);

				ReleaseNode(hImg);
				ReleaseNode(hSt);
				ReleaseNode(hMov);

				ReleaseTextString(name);
				ReleaseTextString(img);
				ReleaseTextString(hrdt);
				ReleaseTextString(hpt);
				ReleaseTextString(blok);

				node = GetNextNode(xml, node);
			}
		} 
	}while(FindNextFile(search, &ffd) != 0);
	ReleaseWorker(xml);
	FindClose(search);
	delete[] imgpath;
	delete[] fname;
	delete[] listpath;
	return 0;
}
static void PR_CALLBACK Server(void *arg)
{
    PRStatus rv;
    PRNetAddr serverAddress;
    PRThread *me = PR_GetCurrentThread();
    CSServer_t *server = (CSServer_t*)arg;
    PRSocketOptionData sockOpt;

    server->listener = PR_Socket(domain, SOCK_STREAM, protocol);

    sockOpt.option = PR_SockOpt_Reuseaddr;
    sockOpt.value.reuse_addr = PR_TRUE;
    rv = PR_SetSocketOption(server->listener, &sockOpt);
    TEST_ASSERT(PR_SUCCESS == rv);

    memset(&serverAddress, 0, sizeof(serverAddress));
	if (PR_AF_INET6 != domain)
		rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress);
	else
		rv = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, DEFAULT_PORT,
													&serverAddress);
    rv = PR_Bind(server->listener, &serverAddress);
    TEST_ASSERT(PR_SUCCESS == rv);

    rv = PR_Listen(server->listener, server->backlog);
    TEST_ASSERT(PR_SUCCESS == rv);

    server->started = PR_IntervalNow();
    TimeOfDayMessage("Server started at", me);

    PR_Lock(server->ml);
    server->state = cs_run;
    PR_NotifyCondVar(server->stateChange);
    PR_Unlock(server->ml);

    /*
    ** Create the first worker (actually, a thread that accepts
    ** connections and then processes the work load as needed).
    ** From this point on, additional worker threads are created
    ** as they are needed by existing worker threads.
    */
    rv = CreateWorker(server, &server->pool);
    TEST_ASSERT(PR_SUCCESS == rv);

    /*
    ** From here on this thread is merely hanging around as the contact
    ** point for the main test driver. It's just waiting for the driver
    ** to declare the test complete.
    */
    TEST_LOG(
        cltsrv_log_file, TEST_LOG_VERBOSE,
        ("\tServer(0x%p): waiting for state change\n", me));

    PR_Lock(server->ml);
    while ((cs_run == server->state) && !Aborted(rv))
    {
        rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
    }
    PR_Unlock(server->ml);
    PR_ClearInterrupt();

    TEST_LOG(
        cltsrv_log_file, TEST_LOG_INFO,
        ("\tServer(0x%p): shutting down workers\n", me));

    /*
    ** Get all the worker threads to exit. They know how to
    ** clean up after themselves, so this is just a matter of
    ** waiting for clorine in the pool to take effect. During
    ** this stage we're ignoring interrupts.
    */
    server->workers.minimum = server->workers.maximum = 0;

    PR_Lock(server->ml);
    while (!PR_CLIST_IS_EMPTY(&server->list))
    {
        PRCList *head = PR_LIST_HEAD(&server->list);
        CSWorker_t *worker = (CSWorker_t*)head;
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_VERBOSE,
            ("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker));
        rv = PR_Interrupt(worker->thread);
        TEST_ASSERT(PR_SUCCESS == rv);
        PR_REMOVE_AND_INIT_LINK(head);
    }

    while (server->pool.workers > 0)
    {
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_NOTICE,
            ("\tServer(0x%p): waiting for %u workers to exit\n",
            me, server->pool.workers));
        (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT);
    }

    server->state = cs_exit;
    PR_NotifyCondVar(server->stateChange);
    PR_Unlock(server->ml);

    TEST_LOG(
        cltsrv_log_file, TEST_LOG_ALWAYS,
        ("\tServer(0x%p): stopped after %u operations and %u bytes\n",
        me, server->operations, server->bytesTransferred));

    if (NULL != server->listener) PR_Close(server->listener);
    server->stopped = PR_IntervalNow();

}  /* Server */
static void PR_CALLBACK Worker(void *arg)
{
    PRStatus rv;
    PRNetAddr from;
    PRFileDesc *fd = NULL;
    PRThread *me = PR_GetCurrentThread();
    CSWorker_t *worker = (CSWorker_t*)arg;
    CSServer_t *server = worker->server;
    CSPool_t *pool = &server->pool;

    TEST_LOG(
        cltsrv_log_file, TEST_LOG_NOTICE,
        ("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1));

    PR_Lock(server->ml);
    PR_APPEND_LINK(&worker->element, &server->list);
    pool->workers += 1;  /* define our existance */

    while (cs_run == server->state)
    {
        while (pool->accepting >= server->workers.accepting)
        {
            TEST_LOG(
                cltsrv_log_file, TEST_LOG_VERBOSE,
                ("\t\tWorker(0x%p): waiting for accept slot[%d]\n",
                me, pool->accepting));
            rv = PR_WaitCondVar(pool->acceptComplete, PR_INTERVAL_NO_TIMEOUT);
            if (Aborted(rv) || (cs_run != server->state))
            {
                TEST_LOG(
                    cltsrv_log_file, TEST_LOG_NOTICE,
                    ("\tWorker(0x%p): has been %s\n",
                    me, (Aborted(rv) ? "interrupted" : "stopped")));
                goto exit;
            }
        } 
        pool->accepting += 1;  /* how many are really in accept */
        PR_Unlock(server->ml);

        TEST_LOG(
            cltsrv_log_file, TEST_LOG_VERBOSE,
            ("\t\tWorker(0x%p): calling accept\n", me));
        fd = PR_Accept(server->listener, &from, PR_INTERVAL_NO_TIMEOUT);

        PR_Lock(server->ml);        
        pool->accepting -= 1;
        PR_NotifyCondVar(pool->acceptComplete);

        if ((NULL == fd) && Aborted(PR_FAILURE))
        {
            if (NULL != server->listener)
            {
                PR_Close(server->listener);
                server->listener = NULL;
            }
            goto exit;
        }

        if (NULL != fd)
        {
            /*
            ** Create another worker of the total number of workers is
            ** less than the minimum specified or we have none left in
            ** accept() AND we're not over the maximum.
            ** This sort of presumes that the number allowed in accept
            ** is at least as many as the minimum. Otherwise we'll keep
            ** creating new threads and deleting them soon after.
            */
            PRBool another =
                ((pool->workers < server->workers.minimum) ||
                ((0 == pool->accepting)
                    && (pool->workers < server->workers.maximum))) ?
                    PR_TRUE : PR_FALSE;
            pool->active += 1;
            PR_Unlock(server->ml);

            if (another) (void)CreateWorker(server, pool);

            rv = ProcessRequest(fd, server);
            if (PR_SUCCESS != rv)
                TEST_LOG(
                    cltsrv_log_file, TEST_LOG_ERROR,
                    ("\t\tWorker(0x%p): server process ended abnormally\n", me));
            (void)PR_Close(fd); fd = NULL;

            PR_Lock(server->ml);
            pool->active -= 1;
        }
    }

exit:
    PR_ClearInterrupt();    
    PR_Unlock(server->ml);

    if (NULL != fd)
    {
        (void)PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
        (void)PR_Close(fd);
    }

    TEST_LOG(
        cltsrv_log_file, TEST_LOG_NOTICE,
        ("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool->workers));

    PR_Lock(server->ml);
    pool->workers -= 1;  /* undefine our existance */
    PR_REMOVE_AND_INIT_LINK(&worker->element);
    PR_NotifyCondVar(pool->exiting);
    PR_Unlock(server->ml);

    PR_DELETE(worker);  /* destruction of the "worker" object */

}  /* Worker */
ECommandResult::Type FProvider::Execute(
	const TSharedRef<ISourceControlOperation, ESPMode::ThreadSafe>& InOperation,
	const TArray<FString>& InFiles, 
	EConcurrency::Type InConcurrency,
	const FSourceControlOperationComplete& InOperationCompleteDelegate
)
{
	// the "Connect" operation is the only operation that can be performed while the
	// provider is disabled, if the operation is successful the provider will be enabled
	if (!IsEnabled() && (InOperation->GetName() != OperationNames::Connect))
	{
		return ECommandResult::Failed;
	}

	// attempt to create a worker to perform the requested operation
	FWorkerPtr WorkerPtr = CreateWorker(InOperation->GetName());
	if (!WorkerPtr.IsValid())
	{
		// apparently we don't support this particular operation
		FFormatNamedArguments Arguments;
		Arguments.Add(TEXT("OperationName"), FText::FromName(InOperation->GetName()));
		Arguments.Add(TEXT("ProviderName"), FText::FromName(GetName()));
		LogError(
			FText::Format(
				LOCTEXT(
					"UnsupportedOperation", 
					"Operation '{OperationName}' not supported by source control provider '{ProviderName}'"
				),
				Arguments
			)
		);
		return ECommandResult::Failed;
	}
	
	auto* Command = new FCommand(
		GetWorkingDirectory(), AbsoluteContentDirectory, InOperation,
		WorkerPtr.ToSharedRef(), InOperationCompleteDelegate
	);

	TArray<FString> AbsoluteFiles;
	if (InOperation->GetName() == OperationNames::Connect)
	{
		AbsoluteFiles.Add(Settings.GetMercurialPath());
	}
	else if (InOperation->GetName() == OperationNames::MarkForAdd)
	{
		TArray<FString> AbsoluteLargeFiles;
		PrepareFilenamesForAddCommand(InFiles, AbsoluteFiles, AbsoluteLargeFiles);
		
		if (AbsoluteLargeFiles.Num() > 0)
		{
			Command->SetAbsoluteLargeFiles(AbsoluteLargeFiles);
		}
	}
	else
	{
		for (const auto& Filename : InFiles)
		{
			AbsoluteFiles.Add(FPaths::ConvertRelativePathToFull(Filename));
		}
	}

	if (AbsoluteFiles.Num() > 0)
	{
		Command->SetAbsoluteFiles(AbsoluteFiles);
	}

	if (InConcurrency == EConcurrency::Synchronous)
	{
		auto Result = ExecuteSynchronousCommand(Command, InOperation->GetInProgressString());
		delete Command;
		return Result;
	}
	else
	{
		return ExecuteCommand(Command, true);
	}
}
Exemple #16
0
int ThreadPoolInit(ThreadPool *tp, ThreadPoolAttr *attr)
{
	int retCode = 0;
	int i = 0;

	if (!tp) {
		return EINVAL;
	}

	retCode += ithread_mutex_init(&tp->mutex, NULL);
	retCode += ithread_mutex_lock(&tp->mutex);

	retCode += ithread_cond_init(&tp->condition, NULL);
	retCode += ithread_cond_init(&tp->start_and_shutdown, NULL);
	if (retCode) {
		ithread_mutex_unlock(&tp->mutex);
		ithread_mutex_destroy(&tp->mutex);
		ithread_cond_destroy(&tp->condition);
		ithread_cond_destroy(&tp->start_and_shutdown);
		return EAGAIN;
	}
	if (attr) {
		tp->attr = *attr;
	} else {
		TPAttrInit(&tp->attr);
	}
	if (SetPolicyType(tp->attr.schedPolicy) != 0) {
		ithread_mutex_unlock(&tp->mutex);
		ithread_mutex_destroy(&tp->mutex);
		ithread_cond_destroy(&tp->condition);
		ithread_cond_destroy(&tp->start_and_shutdown);

		return INVALID_POLICY;
	}
	retCode += FreeListInit(
		&tp->jobFreeList, sizeof(ThreadPoolJob), JOBFREELISTSIZE);
	StatsInit(&tp->stats);
	retCode += ListInit(&tp->highJobQ, CmpThreadPoolJob, NULL);
	retCode += ListInit(&tp->medJobQ, CmpThreadPoolJob, NULL);
	retCode += ListInit(&tp->lowJobQ, CmpThreadPoolJob, NULL);
	if (retCode) {
		retCode = EAGAIN;
	} else {
		tp->persistentJob = NULL;
		tp->lastJobId = 0;
		tp->shutdown = 0;
		tp->totalThreads = 0;
		tp->busyThreads = 0;
		tp->persistentThreads = 0;
		tp->pendingWorkerThreadStart = 0;
		for (i = 0; i < tp->attr.minThreads; ++i) {
			retCode = CreateWorker(tp);
			if (retCode) {
				break;
			}
		}
	}

	ithread_mutex_unlock(&tp->mutex);

	if (retCode) {
		/* clean up if the min threads could not be created */
		ThreadPoolShutdown(tp);
	}

	return retCode;
}
/****************************************************************************
 * Function: ThreadPoolInit
 *
 *  Description:
 *      Initializes and starts ThreadPool. Must be called first.
 *      And only once for ThreadPool.
 *  Parameters:
 *      tp  - must be valid, non null, pointer to ThreadPool.
 *      minWorkerThreads - minimum number of worker threads
 *                         thread pool will never have less than this
 *                         number of threads.
 *      maxWorkerThreads - maximum number of worker threads
 *                         thread pool will never have more than this
 *                         number of threads.
 *      maxIdleTime      - maximum time that a worker thread will spend
 *                         idle. If a worker is idle longer than this
 *                         time and there are more than the min
 *                         number of workers running, than the
 *                         worker thread exits.
 *      jobsPerThread    - ratio of jobs to thread to try and maintain
 *                         if a job is scheduled and the number of jobs per
 *                         thread is greater than this number,and
 *                         if less than the maximum number of
 *                         workers are running then a new thread is
 *                         started to help out with efficiency.
 *      schedPolicy      - scheduling policy to try and set (OS dependent)
 *  Returns:
 *      0 on success, nonzero on failure.
 *      EAGAIN if not enough system resources to create minimum threads.
 *      INVALID_POLICY if schedPolicy can't be set
 *      EMAXTHREADS if minimum threads is greater than maximum threads
 *****************************************************************************/
int ThreadPoolInit( ThreadPool *tp, ThreadPoolAttr *attr )
{
	int retCode = 0;
	int i = 0;
	//printf("%s, %d\n", __FUNCTION__, __LINE__);

	assert( tp != NULL );
	if( tp == NULL ) {
		return EINVAL;
	}
#ifdef WIN32
#ifdef PTW32_STATIC_LIB
	pthread_win32_process_attach_np();
#endif
#endif
	//printf("%s, %d\n", __FUNCTION__, __LINE__);

	retCode += ithread_mutex_init( &tp->mutex, NULL );
	assert( retCode == 0 );

	retCode += ithread_mutex_lock( &tp->mutex );
	assert( retCode == 0 );

	retCode += ithread_cond_init( &tp->condition, NULL );
	assert( retCode == 0 );

	retCode += ithread_cond_init( &tp->start_and_shutdown, NULL );
	assert( retCode == 0 );
	//printf("%s, %d\n", __FUNCTION__, __LINE__);

	if( retCode != 0 ) {
		return EAGAIN;
	}

	if( attr ) {
		tp->attr = ( *attr );
	} else {
		TPAttrInit( &tp->attr );
	}
	//printf("%s, %d, minthreads: %d\n", __FUNCTION__, __LINE__, tp->attr.minThreads);

	if( SetPolicyType( tp->attr.schedPolicy ) != 0 ) {
		ithread_mutex_unlock( &tp->mutex );
		ithread_mutex_destroy( &tp->mutex );
		ithread_cond_destroy( &tp->condition );
		ithread_cond_destroy( &tp->start_and_shutdown );
		return INVALID_POLICY;
	}
	//printf("%s, %d\n", __FUNCTION__, __LINE__);

	retCode += FreeListInit(
		&tp->jobFreeList, sizeof( ThreadPoolJob ), JOBFREELISTSIZE );
	assert( retCode == 0 );

	StatsInit( &tp->stats );

	retCode += ListInit( &tp->highJobQ, CmpThreadPoolJob, NULL );
	assert( retCode == 0 );

	retCode += ListInit( &tp->medJobQ, CmpThreadPoolJob, NULL );
	assert( retCode == 0 );

	retCode += ListInit( &tp->lowJobQ, CmpThreadPoolJob, NULL );
	assert( retCode == 0 );
	//printf("%s, %d, retcode is %d\n", __FUNCTION__, __LINE__, retCode);

	if( retCode != 0 ) {
		retCode = EAGAIN;
		//printf("%s, %d\n", __FUNCTION__, __LINE__);
	} else {
	//printf("%s, %d\n", __FUNCTION__, __LINE__);
		tp->persistentJob = NULL;
		tp->lastJobId = 0;
		tp->shutdown = 0;
		tp->totalThreads = 0;
		tp->persistentThreads = 0;
		//printf("%s, %d\n", __FUNCTION__, __LINE__);
		for( i = 0; i < tp->attr.minThreads; ++i ) {
			if( ( retCode = CreateWorker( tp ) ) != 0 ) {
				//printf("%s, %d\n", __FUNCTION__, __LINE__);

				break;
			}
		}
	}
	//printf("%s, %d\n", __FUNCTION__, __LINE__);

	ithread_mutex_unlock( &tp->mutex );

	if( retCode != 0 ) {
		// clean up if the min threads could not be created
		ThreadPoolShutdown( tp );
	}
	//printf("%s, %d\n", __FUNCTION__, __LINE__);

	return retCode;
}
Exemple #18
0
int CMapFileIO::LoadMap(CLevelMap &map, HANDLE hFile) const
{
	XML_MANAGER_HANDLE xml = 0;
	xml = CreateWorker();
	if(!xml)
		return 1;
	DWORD res = ReadFromFileHandle(xml, hFile);
	if(res != ERROR_SUCCESS) 
		return 1;
	CloseHandle(hFile);
	XML_NODE_HANDLE group;

	//dimensions
	group = RetrieveNode(xml, 0, L"dimensions");
	if(!group)
		return 1;
	LPWSTR mapwt = GetNodeAttr(xml, group, L"width");
	if(!mapwt)
		return 1;
	LPWSTR mapht = GetNodeAttr(xml, group, L"height");
	if(!mapht)
		return 1;
	int mapw = _wtoi(mapwt);
	int maph = _wtoi(mapht);
	map.SetDimensions(mapw, maph);
	ReleaseTextString(mapwt);
	ReleaseTextString(mapht);
	ReleaseNode(group);

	//background
	group = RetrieveNode(xml, 0, L"background");
	if(!group)
		return 1;
	map.SetBackground(LoadBackground(xml, group));
	ReleaseNode(group);

	//player
	group = RetrieveNode(xml, 0, L"player");
	CStubCreature* pPlr = 0;
	if(group)
	{
		pPlr = LoadPlayer(xml, group);
		map.SetPlayerPos(pPlr->GetPosition());
		delete pPlr;
	}
	ReleaseNode(group);

	//tiletypes
	LoadTileTypesDict(map.m_TilesDictionary);

	//tiles
	group = RetrieveNode(xml, 0, L"tiles");
	if(!group)
		return 1;
	LoadTileList(map.m_pTiles, map.m_TilesDictionary, xml, group);
	ReleaseNode(group);

	//creatures
	group = RetrieveNode(xml, 0, L"creatures");
	if(group)
		LoadCreaturesList( map.m_pCreatures, xml, group );
	ReleaseNode(group);
	map.AssignMyEnviroment();

	ReleaseWorker(xml);
	return 0;
}