Example #1
0
BOOL Dlg_OnInitDialog(HWND hWnd, HWND hWndFocus, LPARAM lParam) {

   chSETDLGICONS(hWnd, IDI_QUEUE);

   g_hWnd = hWnd; // Used by client/server threads to show status

   // Prepare the SRWLock to be used
   InitializeSRWLock(&g_srwLock);

   // Prepare the condition variables to be used
   InitializeConditionVariable(&g_cvReadyToConsume);
   InitializeConditionVariable(&g_cvReadyToProduce);

   // Will be set to TRUE in order to end threads
   g_fShutdown = FALSE;

   // Create the writer threads
   DWORD dwThreadID;
   for (int x = 0; x < 4; x++)
      g_hThreads[g_nNumThreads++] = 
         chBEGINTHREADEX(NULL, 0, WriterThread, (PVOID) (INT_PTR) x, 
            0, &dwThreadID);

   // Create the reader threads
   for (int x = 0; x < 2; x++)
      g_hThreads[g_nNumThreads++] = 
         chBEGINTHREADEX(NULL, 0, ReaderThread, (PVOID) (INT_PTR) x, 
            0, &dwThreadID);

   return(TRUE);
}
Example #2
0
void CDbControllerTimer::Create( void )
{
	DWORD dwThreadId	= 0;
	m_hCloseTick	= CreateEvent( NULL, FALSE, FALSE, NULL );
	m_hTickThread	= chBEGINTHREADEX( NULL, 0, _Tick, (LPVOID)this, 0, &dwThreadId );
	ASSERT( m_hCloseTick );
	ASSERT( m_hTickThread );
}
BOOL CEnvironment::CreateWorkers( void )
{
	DWORD dwThreadId;
	m_hCloseWorker	= CreateEvent( NULL, FALSE, FALSE, NULL );
	m_hWorker	= chBEGINTHREADEX( NULL, 0, _Worker, this, 0, &dwThreadId );
	if( m_hWorker == NULL )
		return FALSE;
	return TRUE;
}
Example #4
0
bool base_thread::CreateThread( void * psa, unsigned cbStatck, PTHREAD_START pfn, void * param, unsigned fdwCreate )
{
//	m_param.m_arg = param;
	if( m_hMsgEvent == NULL )
		m_hMsgEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
	ResetEvent( m_hMsgEvent );
	ResetEvent( m_hEvent );
	m_hThread = chBEGINTHREADEX( psa, cbStatck, pfn, param, fdwCreate, &m_dwThreadID );
	if( m_hThread == NULL )
		return false;
	return true;
}
Example #5
0
BOOL CDbController::CreateDbHandler( DWORD dwMilliseconds )
{
	m_hIocp		= ::CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 0 );
	if( !m_hIocp )
		return FALSE;
	DWORD dwThreadId;
	m_hDbHndlr	= chBEGINTHREADEX( NULL, 0, _DbHandler, (LPVOID)this, 0, &dwThreadId );
	if( !m_hDbHndlr )
	{
		::CloseHandle( m_hIocp );
		return FALSE;
	}

	SetTimer( dwMilliseconds );

	return TRUE;
}
Example #6
0
VOID FirstFunc(BOOL fLocal, COptex& optex) {

   optex.Enter();  // Gain ownership of the optex

   // Since this thread owns the optex, we should be able to get it again
   chVERIFY(optex.TryEnter()); 

   HANDLE hOtherThread = NULL;
   if (fLocal) {
      // Spawn a secondary thread for testing purposes (pass it the optex)

      DWORD dwThreadId;
      hOtherThread = chBEGINTHREADEX(NULL, 0, 
         SecondFunc, (PVOID) &optex, 0, &dwThreadId);

   } else {
      // Spawn a secondary process for testing purposes
      STARTUPINFO si = { sizeof(si) };
      PROCESS_INFORMATION pi;
      TCHAR szPath[MAX_PATH];
      GetModuleFileName(NULL, szPath, chDIMOF(szPath));
      CreateProcess(NULL, szPath, NULL, NULL, 
         FALSE, 0, NULL, NULL, &si, &pi);
      hOtherThread = pi.hProcess;
      CloseHandle(pi.hThread);
   }

   // Wait for the second thread to own the optex
   chMB("Primary: Hit OK to give optex to secondary");

   // Let the second thread gain ownership of the optex
   optex.Leave();
   optex.Leave();

   // Wait for the second thread to own the optex
   chMB("Primary: Hit OK to wait for the optex\n(Dismiss me 1st)");

   optex.Enter();  // Try to gain ownership back

   WaitForSingleObject(hOtherThread, INFINITE);
   CloseHandle(hOtherThread);
   optex.Leave();
}
Example #7
0
BOOL CDbManager::CreateDbWorkers()
{
	s_hHandle = CreateEvent( NULL, FALSE, FALSE, NULL );

	for( int i = 0; i < DEFAULT_DB_WORKER_THREAD_NUM; i++ )
	{
		m_hIOCP[i]	= CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 0 );
		ASSERT( m_hIOCP[i] );

		HANDLE hThread	= chBEGINTHREADEX( NULL, 0, DbWorkerThread, (LPVOID)i, 0, NULL );
		ASSERT( hThread );

		m_hDbWorkerThreadTerminate[i]	= hThread;
		if( WaitForSingleObject( s_hHandle, SEC( 10 ) ) == WAIT_TIMEOUT )
		{
			OutputDebugString( "COLLECTIONSERVER.EXE\t// TIMEOUT\t// ODBC" );
			return FALSE;
		}
	}

	CloseHandle( s_hHandle );
	return TRUE;
}
Example #8
0
void Dlg_OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify) {

   switch (id) {
      case IDCANCEL:
         EndDialog(hWnd, id);
         break;

      case IDC_BTN_STOP: 
      {
         // StopProcessing can't be called from the UI thread
         // or a deadlock will occur: SendMessage() is used 
         // to fill up the listboxes
         // --> Another thread is required
         DWORD dwThreadID;
         CloseHandle(chBEGINTHREADEX(NULL, 0, StoppingThread, 
            NULL, 0, &dwThreadID));
         
         // This button can't be pushed twice
         Button_Enable(hWndCtl, FALSE);
      }
      break;
   }
}
Example #9
0
int _tmain(int argc, _TCHAR* argv[])
{
	if(argc < 2)
	{
		_tprintf(TEXT("PI <number-of-threads> <time>\n\n"));		
		return -1;
	}
	_tsetlocale( LC_ALL, TEXT("portuguese_portugal") );
	
	//ler do standart output o numero de tarefas a criar
//	DWORD NumThreads = _wtoi(argv[1]);
	DWORD NumThreads = 5;
	
	//ler numero de pontos a criar
//	DWORD Pontos  = _wtoi(argv[2]);
	DWORD Pontos = 5000000;

	_tprintf( TEXT("Tarefas: %d , Pontos: %d\n"), NumThreads, Pontos );
	
	DWORD NumPointForThread = NumThreads/Pontos;

	HANDLE* hThreads = (HANDLE*)calloc(NumThreads,sizeof(HANDLE));
	DWORD* idThreads = (DWORD *)calloc(NumThreads,sizeof(DWORD));
	int numPointAndId[2];

	for(DWORD i = 0; i < NumThreads; ++i)
	{
		numPointAndId[0] = NumPointForThread;
		numPointAndId[1] = &idThreads[i];
		hThreads[i] = chBEGINTHREADEX(NULL,
										0,
										FunctionOfThreads,
										(LPVOID) numPointAndId,
										NULL, 
										&idThreads[i] );
	}

	_tprintf( TEXT("Aguarde pela terminação das threads.\n") );
	WaitForMultipleObjects( NumThreads, hThreads, TRUE, INFINITE );

	_tprintf( TEXT("Fechar os HANDLES das tarefas.\n") );

	DWORD numOfPointsInCircle = 0;

	for (DWORD i=0; i<NumThreads; ++i)
	{
		DWORD in = 0;
		GetExitCodeThread(hThreads[i],&in);
		CloseHandle(hThreads[i]);
		numOfPointsInCircle =+ in;
	}
	
	_tprintf( TEXT("A percentagem de pontos dentro da circunferencia foram:\n%d"), (numOfPointsInCircle/(float)Pontos)*100 );


	_tprintf( TEXT("[main] Função principal a terminar.\nPrima uma tecla para continuar.\n") );
    _gettch();

	free(idThreads);
	free(hThreads);
	return 0;
}
Example #10
0
BOOL CRunObject::Init( void )
{
	if( LoadAIScript() == FALSE )
		return FALSE;

// 
	m_hClose	= CreateEvent( NULL, FALSE, FALSE, NULL );
	DWORD dwThreadId;
	m_hRunObject	= chBEGINTHREADEX( NULL, 0, _Run, (LPVOID)this, 0, &dwThreadId ); 
//
	/*
#ifdef __GIFTBOX0213
	if( !CDPAccountClient::GetInstance()->ConnectToServer( s_szAccountAddr, PN_ACCOUNTSRVR_2, TRUE ) )
	{
		OutputDebugString( "Can't connect to account server." );
		return FALSE;
	}
	CGiftboxMan::GetInstance()->Upload( CDPAccountClient::GetInstance() );
#endif	// __GIFTBOX0213
	*/
	if( !g_DPSrvr.StartServer( (u_short)( g_uKey + PN_WORLDSRVR ), TRUE ) )
	{
		OutputDebugString( "Can't start server." );
		return FALSE;
	}
	if( !g_DPCoreClient.Run( g_szCoreAddr, PN_CORESRVR + 0, g_uKey ) )
	{
		OutputDebugString( "Can't connect to core server." );
		return FALSE;
	}
	if( !g_dpDBClient.ConnectToServer( g_szDBAddr, PN_DBSRVR_1, TRUE ) )
	{
		OutputDebugString( "Can't connect to database server." );
		return FALSE;
	}
	if ( g_eLocal.GetState( ENABLE_GUILD_INVENTORY ) )
		g_dpDBClient.SendQueryGuildBank();
	if( g_eLocal.GetState( EVE_WORMON ) )
		g_dpDBClient.SendQueryGuildQuest();

#if __VER >= 13 // __RAINBOW_RACE
	if( g_eLocal.GetState( EVE_RAINBOWRACE ) )
		g_dpDBClient.SendRainbowRaceReqLoad();
#endif // __RAINBOW_RACE

#ifdef __INVALID_LOGIN_0320
	g_dpDBClient.CalluspXXXMultiServer( g_uIdofMulti, NULL );
#else	// __INVALID_LOGIN_0320
	g_dpDBClient.CalluspXXXMultiServer( g_uIdofMulti, 0 );
#endif	// __INVALID_LOGIN_0320
	if( !CXMasEvent::GetInstance()->LoadScript( "spevent.txt" ) )
	{
		OutputDebugString( "can't read spevent.txt" );
		return FALSE;
	}
	if( g_eLocal.GetState( EVE_SCHOOL ) )
	{
#ifdef __IDC
		if( !CEveSchool::GetInstance()->LoadPos( "..\\script\\school.txt" ) )	//
#else	// __IDC
		if( !CEveSchool::GetInstance()->LoadPos( "school.txt" ) )
#endif	// __IDC
		{
			OutputDebugString( "school.txt not found" );
			return FALSE;
		}
	}
	if( g_eLocal.GetState( EVE_GUILDCOMBAT ) && !g_GuildCombatMng.LoadScript( "GuildCombat.txt" ) )
	{
		OutputDebugString( "GuildCombat.txt not found" );
		return FALSE;
	}
#if __VER >= 12 // __ITEMCREATEMON_S0602
#if __VER < 12 // __NEW_ITEMCREATEMON_SERVER
	if( !g_CreateMonster.LoadScript( "CreateMonster.txt" ) )
	{
		OutputDebugString( "CreateMonster.txt Not Found!" );
		return FALSE;
	}
#endif // __NEW_ITEMCREATEMON_SERVER
#endif // __ITEMCREATEMON_S0602

	return TRUE;
}
Example #11
0
int start_server (int argc, char *argv[])
{
    int      i;
    int      threadCount = 0;
    int      thread_id;
    HANDLE   g_hThread[MAX_THREAD];
    char     doers_number[MAXDOER][SPACE_FOR_THREAD_ID];
    char     movers_number[MAXMOVER][SPACE_FOR_THREAD_ID];

#ifdef INFORMIX
    MI_CONNECTION_INFO conn_info;

    // This works around a bug in Informix's isqlt09a.dll that causes memory
    // access violation when our program exits.
    memset (&conn_info, '\0', sizeof (conn_info));
    mi_server_connect (&conn_info);
#endif
    // Don't let the user start the middleware server as a standalone program.
    // Check whether the argument matches the magic string.
    if ((argc != 2) || (stricmp(argv[1], SERVER_MAGIC_STR) != 0))
    {
        puts("Vigilert Middleware Server cannot be started as a standalone program.");
        puts("Start the Velara Vigilert service.\n");
        Sleep (4000);
        exit(EXIT_FAILURE);
    }

    // Assign IDs to the multiple movers and doers
    for (i = 0; i < MAXDOER; i++)
    {
        sprintf (doers_number[i], "%d", i + 1);
    }

    for (i = 0; i < MAXMOVER; i++)
    {
        sprintf (movers_number[i], "%d", i + 1);
    }

    /* Initialize the global variables */
    num_doer = 0;
    num_mover = 0;
    g_fTerminate = FALSE;
    num_doers_accessing_global_SPI = 0;

    puts ("\n.:. Vigilert Server .:.");

    // Save the memory state so we can diff against it in vl_gather_stats.
    _CrtMemCheckpoint (&s1);

    // Initialize the mutexes
    InitializeCriticalSection(&suspend_mutex);
    InitializeCriticalSection(&mover_cleaner_mutex);
    InitializeCriticalSection(&doer_num_mutex);
    InitializeCriticalSection(&mover_num_mutex);
    InitializeCriticalSection(&num_doers_accessing_global_SPI_mutex);
    InitializeCriticalSection(&Global_SPI_mutex);

#ifdef _MIDDLE
    init_named_mem();
#endif

    load_keys();

#ifdef _MIDDLE
    InitializeCriticalSection(&logwrite_mutex);
    InitializeCriticalSection(&begin_udr_mutex);
    tm_init_conn_pool();
#endif

    // Initialize the semaphores that wakeup the movers and the doers

    // Doers can be woken up by doer dispatcher, mover (that moves the database tokens
    // to the database task queue) and the TCP-IP server thread that builds and moves the stream
    // tokens to the stream task queue.
    wakeup_doer_by_doer_dispatcher_sem = CreateSemaphore(NULL, 0, MAXDOER, NULL);    // Semaphore for doer-dispatcher
    wakeup_doer_by_mover_sem = CreateSemaphore(NULL, 0, MAXDOER, NULL);              // Semaphore for mover
    wakeup_doer_by_tcpip_server_sem = CreateSemaphore(NULL, 0, MAXDOER, NULL);       // Semahpore for TCP-IP server
    // Mover can be wpken up by mover dispatcher.
    wakeup_mover_by_mover_dispatcher_sem = CreateSemaphore(NULL, 0, MAXMOVER, NULL); // Semaphore for mover-dispatcher

    // Initialize the array of semaphore handles that can wake up the doers
    wakeup_doer_array[0] = wakeup_doer_by_doer_dispatcher_sem;
    wakeup_doer_array[1] = wakeup_doer_by_mover_sem;
    wakeup_doer_array[2] = wakeup_doer_by_tcpip_server_sem;

    // Initialize the event variable to say whether a command execute thread is waiting to access global SPI.
    command_execute_waiting_event = CreateEvent(NULL, TRUE, TRUE, NULL);

    /* start threads */
    g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, wait_end, NULL, CREATE_SUSPENDED, &thread_id);
    tm_associate_thread_id_to_connection(threadCount, thread_id);
    threadCount++;

    g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, mover_dispatcher, NULL, CREATE_SUSPENDED, &thread_id);
    tm_associate_thread_id_to_connection(threadCount, thread_id);
    threadCount++;

    g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, doer_dispatcher, NULL, CREATE_SUSPENDED, &thread_id);
    tm_associate_thread_id_to_connection(threadCount, thread_id);
    threadCount++;

    g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, TCPIPserver, NULL, CREATE_SUSPENDED, &thread_id);
    tm_associate_thread_id_to_connection(threadCount, thread_id);
    threadCount++;

    g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, cleaner, NULL, CREATE_SUSPENDED, &thread_id);
    tm_associate_thread_id_to_connection(threadCount, thread_id);
    threadCount++;

#ifdef _DEBUG
    g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, GatherStatsServer, NULL, CREATE_SUSPENDED, &thread_id);
    tm_associate_thread_id_to_connection(threadCount, thread_id);
    threadCount++;
#endif

    for (i = 0; i < MAXDOER; i++)
    {
        g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, doer,(LPVOID)doers_number[i], CREATE_SUSPENDED,  &thread_id);
        tm_associate_thread_id_to_connection(threadCount, thread_id);
        threadCount++;
    }

    for (i = 0; i < MAXMOVER; i++)
    {
        g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, mover,(LPVOID)movers_number[i], CREATE_SUSPENDED,  &thread_id);
        tm_associate_thread_id_to_connection(threadCount, thread_id);
        threadCount++;
    }

    // Before starting the various threads, let the main thread run the initializing routine
    // to initialize all main memory data structures
    tm_associate_thread_id_to_connection(threadCount, tm_get_thread_id());

    tman_init();

    // Resume the various suspended threads one by one
    for (i = 0; i < threadCount; i++)
    {
        int result;
        result = ResumeThread(g_hThread[i]);
        if (result == -1)
        {
#ifdef _MIDDLE
            printf ("Error: unable to start thread %d.\n", tm_own_connpool_1[i].thread_id);
#endif
            exit (EXIT_FAILURE);
        }
    }

    // Wait for all the currently active threads to die or terminate before performing the cleanup
    // of all main memory objects and exiting the middleware server
    WaitForMultipleObjects(threadCount, g_hThread, TRUE, INFINITE);

    for (i = 0; i< threadCount; i++)
        CloseHandle(g_hThread[i]);

    DeleteCriticalSection(&mover_num_mutex);
    DeleteCriticalSection(&doer_num_mutex);
    DeleteCriticalSection(&mover_cleaner_mutex);
    DeleteCriticalSection(&suspend_mutex);
    DeleteCriticalSection(&num_doers_accessing_global_SPI_mutex);
    DeleteCriticalSection(&Global_SPI_mutex);

    CloseHandle(wakeup_mover_by_mover_dispatcher_sem);
    CloseHandle(wakeup_doer_by_doer_dispatcher_sem);
    CloseHandle(wakeup_doer_by_tcpip_server_sem);
    CloseHandle(wakeup_doer_by_mover_sem);
    CloseHandle(command_execute_waiting_event);

#ifdef _MIDDLE
    {
        tm_close_conn_pool();
        close_named_mem();
        DeleteCriticalSection(&begin_udr_mutex);
        DeleteCriticalSection(&logwrite_mutex);
        socket_shutdown();
    }
#endif

    puts ("Vigilert run complete.");
    return EXIT_SUCCESS;
}
Example #12
0
int main(int argc, char** argv) {

	/*
	int outlen = 0;
	Compressor::lzo_encode(buffer, strlen(buffer) + 1, b2, outlen);

	int out3;
	Compressor::lzo_decode(b2, outlen, b3, out3);
	puts(b3);
	*/
	

	init_fptable();

	
	Log::init("game_client.log");

	if(argc == 2) {
		printf("start game: %s\n", argv[1]);
		cc.load_port(1);
		dic = new CommonNet(2, 1);
	}
	else if(argc == 3) {
		printf("start game: %s\n", argv[1]);
		use_server_style = true;
		
		game_name = string(argv[1]);

		cc.load_port(1);
		dic = new CommonNet(2, 1);
	}
	else if(argc == 4) {
		printf("start game: %s\n", argv[1]);
		use_server_style = true;
		
		game_name = string(argv[1]);

		int c_id = atoi(argv[3]);

		if(c_id > 1) {
			client_render = false;
		}

		cc.load_port(c_id);
		dic = new CommonNet(2, c_id);
	}
	else {
		usage();
		return 0;
	}
	
	cc.init();

	// input client connect to the server
	dic->ConnectServer(100);

	cc.send_raw_buffer(string(argv[1]));


	// initial the section
	InitializeCriticalSection(&main_section);
	p_main_section = &main_section;
	// begin the input thread
	DWORD dwThreadId;

#ifdef USE_CLIENT_INPUT
	HANDLE hThreadInput = chBEGINTHREADEX(NULL, 0, InputThread, dic, 0, &dwThreadId);
#endif

	MSG xmsg = {0};
	while(xmsg.message != WM_QUIT) {
		if(PeekMessage(&xmsg, NULL, 0U, 0U, PM_REMOVE)) {
			TranslateMessage(&xmsg);
			DispatchMessage(&xmsg);
		}
		else {
			cc.take_command(op_code, obj_id);
			Log::log("op_code=%d, obj_id=%d\n", op_code, obj_id);
			
			if(op_code >= 0 && op_code < MaxSizeUntilNow_Opcode) {
				if(client_render)
					(*(funcs[op_code].func))();
			}
			else {
				if(op_code == MaxSizeUntilNow_Opcode) {
					Log::slog("game_client exit normally.");
				}
				else {
					Log::slog("game client exit, unexpected op_code");
				}
				break;
			}
		}
	}
	EnterCriticalSection(p_main_section);
	main_thread_running = false;
	LeaveCriticalSection(p_main_section);

	cc.~CommandClient();
	dic->~CommonNet();

	return 0;
}
Example #13
0
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {

   // Obtain the user's settings from the dialog box controls.
   TCHAR szExpression[100];
   ComboBox_GetText(GetDlgItem(hwnd, IDC_EXPRESSION), szExpression,
      sizeof(szExpression) / sizeof(szExpression[0]));

   int nObjects = GetDlgItemInt(hwnd, IDC_NUMOBJS, NULL, FALSE);

   switch (id) {
   case IDCANCEL:
      EndDialog(hwnd, id);
      break;

   case IDC_OBJLIST:
      switch (codeNotify) {
      case LBN_SELCHANGE:
         // An item changed state, reset all items and set the selected ones.
         for (int n = 0; n < nObjects; n++)
            ResetEvent(g_ahObjs[n]);

         for (n = 0; n < nObjects; n++) {
            if (ListBox_GetSel(GetDlgItem(hwnd, IDC_OBJLIST), n)) 
               SetEvent(g_ahObjs[n]);
         }
         break;
      }
      break;

   case IDOK:
      // Prevent the user from changing values while the test is running
      SetFocus(GetDlgItem(hwnd, IDC_OBJLIST));
      EnableWindow(GetDlgItem(hwnd, IDC_NUMOBJS),    FALSE);
      EnableWindow(GetDlgItem(hwnd, IDC_TIMEOUT),    FALSE);
      EnableWindow(GetDlgItem(hwnd, IDC_EXPRESSION), FALSE);
      EnableWindow(GetDlgItem(hwnd, IDOK),           FALSE);

      // Notify the user that the test is running
      SetDlgItemText(hwnd, IDC_RESULT, TEXT("Waiting..."));

      // Create all of the desired kernel objects
      ZeroMemory(g_ahObjs, sizeof(g_ahObjs));
      g_awfme.m_nExpObjects = 0;
      ZeroMemory(g_awfme.m_ahExpObjs, sizeof(g_awfme.m_ahExpObjs));
      g_awfme.m_hwnd = hwnd;
      g_awfme.m_dwMilliseconds = GetDlgItemInt(hwnd, IDC_TIMEOUT, NULL, FALSE);

      ListBox_ResetContent(GetDlgItem(hwnd, IDC_OBJLIST));
      for (int n = 0; n < nObjects; n++) {
         TCHAR szBuf[20];
         g_ahObjs[n] = CreateEvent(NULL, FALSE, FALSE, NULL);

         wsprintf(szBuf, TEXT("  %d"), n + 1);
         ListBox_AddString(GetDlgItem(hwnd, IDC_OBJLIST), 
            &szBuf[lstrlen(szBuf) - 3]);
      }

      PTSTR p = _tcstok(szExpression, TEXT(" "));
      while (p != NULL) {
         g_awfme.m_ahExpObjs[g_awfme.m_nExpObjects++] = 
            (*p == TEXT('|')) ? NULL : g_ahObjs[_ttoi(p) - 1];
         p = _tcstok(NULL, TEXT(" "));
      }

      DWORD dwThreadId;
      CloseHandle(chBEGINTHREADEX(NULL, 0, 
         AsyncWaitForMultipleExpressions, &g_awfme, 
         0, &dwThreadId));
      break;
   }   
}
Example #14
0
int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) 
{
   /* Check if we are not already associated with a job.
    * If this is the case, there is no way to switch to
    * another job.
	*/
   BOOL bInJob = FALSE;
   IsProcessInJob(GetCurrentProcess(), NULL, &bInJob);
   if (bInJob) 
   {
      MessageBox(
		  NULL, 
		  TEXT("Process already in a job"), 
          TEXT(""), 
		  MB_ICONINFORMATION | MB_OK);

      return(-1);
   }

   /* Create the completion port that receives job notifications 
    * Creates an input/output (I/O) completion port 
	* and associates it with a specified file handle, 
	* or creates an I/O completion port that is not 
	* yet associated with a file handle, allowing association at a later time.
    * 
	*  Associating an instance of an opened file handle with an I/O completion 
	*  port allows a process to receive notification of the completion 
	*  of asynchronous I/O operations involving that file handle.
	*
    * FileHandle [in] 
    *   An open file handle or INVALID_HANDLE_VALUE.
    *   The handle must be to an object that supports overlapped I/O.
    *   If a handle is provided, it has to have been opened 
	*   for overlapped I/O completion. 
	*   For example, you must specify the FILE_FLAG_OVERLAPPED flag
	*   when using the CreateFile function to obtain the handle.
	*
    *   If INVALID_HANDLE_VALUE is specified, 
	*   the function creates an I/O completion port without associating it 
	*   with a file handle. In this case, the ExistingCompletionPort parameter 
	*   must be NULL and the CompletionKey parameter is ignored.
    * 
	* ExistingCompletionPort [in, optional] 
    *   A handle to an existing I/O completion port or NULL.
    *   If this parameter is NULL, the function creates a new I/O completion port and, 
	*   if the FileHandle parameter is valid, associates it with the new I/O completion port. 
	*   Otherwise no file handle association occurs. 
	*   The function returns the handle to the new I/O completion port if successful.
	*  
	*  
    */
   g_hIOCP = CreateIoCompletionPort(
	   INVALID_HANDLE_VALUE, 
	   NULL, 
	   0, 
	   0);

   /* Create a thread that waits on the completion port */
   g_hThreadIOCP = chBEGINTHREADEX(
	   NULL, 
	   0, 
	   JobNotify, 
	   NULL, 
	   0, 
	   NULL);

   /* Create the job object */
   g_job.Create(NULL, TEXT("JobLab"));
   g_job.SetEndOfJobInfo(JOB_OBJECT_POST_AT_END_OF_JOB);
   g_job.AssociateCompletionPort(g_hIOCP, COMPKEY_JOBOBJECT);

   DialogBox(hinstExe, MAKEINTRESOURCE(IDD_JOBLAB), NULL, Dlg_Proc);

   /* Post a special key that tells the completion port thread to terminate 
    * Posts an I/O completion packet to an I/O completion port.
	*
	* CompletionPort [in] 
    *   A handle to an I/O completion port to which 
	*   the I/O completion packet is to be posted.
    * 
	* dwNumberOfBytesTransferred [in] 
    *   The value to be returned through the lpNumberOfBytesTransferred 
	*   parameter of the GetQueuedCompletionStatus function.
    *
	* dwCompletionKey [in] 
    *   The value to be returned through the lpCompletionKey parameter 
	*   of the GetQueuedCompletionStatus function.
    * 
	* lpOverlapped [in, optional] 
    *   The value to be returned through the lpOverlapped parameter 
	*   of the GetQueuedCompletionStatus function.
    *
    */
   PostQueuedCompletionStatus(g_hIOCP, 0, COMPKEY_TERMINATE, NULL);

   /* Wait for the completion port thread to terminate */
   WaitForSingleObject(g_hThreadIOCP, INFINITE);
   
   // Clean up everything properly
   CloseHandle(g_hIOCP);
   CloseHandle(g_hThreadIOCP);

   // NOTE: The job is closed when the g_job's destructor is called.
   return(0);
}