[w32 Api] Get Exit Code from Thread without blocking program

This is a discussion on [w32 Api] Get Exit Code from Thread without blocking program within the Windows Programming forums, part of the Platform Specific Boards category; Hello, Before starting please forgive me for my english, I wrote you from France I've a problem to retrieve a ...

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    14

    [w32 Api] Get Exit Code from Thread without blocking program

    Hello,

    Before starting please forgive me for my english, I wrote you from France
    I've a problem to retrieve a thread exit code.

    I'm programming an application in C using w32 api to manage some windows.

    In one of them when I click on "Host Game" (so WM_COMMAND, LOWORD(wParam) = ID_LAUNCH_SERVER) i'm starting a thread which open UDP socket. It waits for asks about my game on the network.

    So all is right it works perfect.

    When the thread is executing, my application needs to continue to work, especially if I click on "CANCEL HOST" button. (it's ok for the moment)
    So after launch thread, my program exiting for the LOWORD(wParam) = ID_LAUNCH_SERVER case, to manage messages loop.

    BUT now, I need to know if thread is terminated (by error, or if a client had been connected to the game).

    So I have the GetExitCodeThread(hdlThreadServeur, &CodeRetourThread); but I don't know where to put it in my program !

    Because if I put it after my CreateThread call, I said program exiting of my ID_LAUNCH_SERVER case, so GetExitCodeThread will be executed once time juste after thread creation and of course thread is not terminated !

    If I make a loop while GetExitCodeThread == STILL_ACTIVE, my application is blocked, impossible to click on any button.

    I don't know how retrive exit code without block application !!!

    My code to help me :
    Code:
    void GestBoutonsFHebergerPartie(HWND fenetre,UINT message, WPARAM wParam, LPARAM lParam)
    {
        char NomPartie[256],PortSaisi[6],NomJoueur1[13],IPChoisie[16],NiveauChoisi[3];
        int PortConverti;
        static InfosPartie MaPartie; // On met les variables du thread en memoire car on va sortir de cette fonction et donc les perdre
        static HANDLE hdlThreadServeur; // Le thread va donc recevoir n'importe quoi puisque c'était un pointeur!
        static DWORD CodeRetourThread;
    
        switch(LOWORD(wParam)) // Quand btn enfoncé, une partie de wParam vaut Id du bouton => recup avec LOWORD()
        {
        case ID_LANCER_SERVEUR:
             GetDlgItemText(fenetre, ID_NOM_PARTIE, NomPartie, 23); // On recupere toutes les valeurs entree par le joueur
             GetDlgItemText(fenetre, ID_COMBOBOX_LISTEIPS, IPChoisie, 16);
             GetDlgItemText(fenetre, ID_PORT_CHOISI, PortSaisi, 6);
             GetDlgItemText(fenetre, ID_COMBOBOX_LISTENIVEAUX, NiveauChoisi, 3);
             GetDlgItemText(fenetre, ID_PSEUDO_JOUEUR1, NomJoueur1, 13);
             sscanf(PortSaisi, "%d", &PortConverti); // Obligé de faire une conversion char->int pour tester si le port est correct
    
                   strcpy(MaPartie.NomPartie, NomPartie); // On remplie la structure qu'on enverra sur le reseau en reponse aux broadcasts
                   strcpy(MaPartie.IPServeur, IPChoisie);
    
                   
                   hdlThreadServeur = CreateThread(NULL, 0, HebergementPartie, &MaPartie, 0, NULL); // On lance le thread pour une ecoute UDP en attente de demande d'infos, ou de connexion
                   // faire une animation d'attente
    
                   
                   while(1)
                   {
                         GetExitCodeThread(hdlThreadServeur, &CodeRetourThread); // Puis on recupere le code de retour du thread
                         
                         if (CodeRetourThread == 1)
                         {
                              MessageBox(NULL,"Pas de probleme thread termine OK","OK",MB_OK | MB_ICONWARNING);
                               // On ferme toutes les fenetres et on demarrer la partie
                              break;
                         }
                         else if (CodeRetourThread == -1)
                         {
                              MessageBox(NULL,"Erreur dans le thread","Erreur !",MB_OK | MB_ICONWARNING);
                              break;
                         }
                   }
             }
            break;
        case ID_CANCEL_HOST:
            ShowWindow(fenetre, SW_HIDE);
            break;
        }
    }

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    What you do is set up a timer with a callback function to poll the thread exit code a couple of times a second. In the call back function take the action appropriate to the status of your thread...

    A timer with callback (not messages) runs in it's own thread so nothing gets blocked.

    Link ---> SetTimer()

    The timer is free running so once you start it, the thing keeps going until you stop it.
    Last edited by CommonTater; 04-05-2011 at 12:42 PM.

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,662
    >> A timer with callback (not messages) runs in it's own thread so nothing gets blocked.
    Not in a different thread...
    Quote Originally Posted by msdn
    When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.
    But that's in the provided link.

    gg

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Codeplug View Post
    >> A timer with callback (not messages) runs in it's own thread so nothing gets blocked.
    Not in a different thread...
    But that's in the provided link.

    gg
    What I meant was that the timer itself runs in a separate thread so it doesn't block.
    The callback is of course, part of whatever thread you create the timer in.

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,662
    >> What I meant was that the timer itself runs in a separate thread so it doesn't block.
    There is no "separate thread". It runs in the same thread that is pumping messages. It's no different if you had just caught WM_TIMER and called the function yourself. There is nothing non-blocking about it.

    gg

  6. #6
    Registered User
    Join Date
    Apr 2011
    Posts
    14
    Thank you very much wonderful idea!

    I'll try this this tonight, but how get my thread handle in my WM_TIMER case ?
    For windows there is FindWindow(..) but it doesn't exist for thread ! And I don't want to put this handle in a extern variable!

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by theclem35 View Post
    Thank you very much wonderful idea!

    I'll try this this tonight, but how get my thread handle in my WM_TIMER case ?
    For windows there is FindWindow(..) but it doesn't exist for thread ! And I don't want to put this handle in a extern variable!
    That's easy... Just save the handle of the thread in a global variable when you create it.
    Code:
    HANDLE hTread;  // global thread handle
    
    hThread = CreateThread( ...
    I do this with windows, threads, menus, accellerators, etc. as routine. Saves a lot of messing around trying to discover things the function is happy to tell you.

    Also, if you use the callback process there's no WM_TIMER message to worry about. You can write the callback function to do the job for you. (Your choice)

  8. #8
    Registered User
    Join Date
    Apr 2011
    Posts
    14
    Well, with global variable it works.

    Thank you

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    No worries... Glad to help.

  10. #10
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    Why not have the thread send a message to your event loop when it terminates
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. An efficient approach to TicTacToe AI?
    By xofvc4rqb in forum C++ Programming
    Replies: 11
    Last Post: 01-15-2011, 04:09 PM
  2. Program Plan
    By Programmer_P in forum C++ Programming
    Replies: 0
    Last Post: 05-11-2009, 01:42 AM
  3. Help with multithreaded sockets program
    By ceclauson in forum C Programming
    Replies: 3
    Last Post: 12-13-2008, 03:15 PM
  4. What is wrong with my code? My first program......
    By coreyt1111 in forum C++ Programming
    Replies: 11
    Last Post: 11-14-2006, 01:03 PM
  5. Thread Synchronization in Win32
    By passionate_guy in forum C Programming
    Replies: 0
    Last Post: 02-06-2006, 04:34 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21