mirror of https://github.com/OpenVPN/openvpn-gui
				
				
				
			Replace Sleep by a Wait function that pumps messages
- The wait function optionally calls IsDialogMessage() if a dialog handle is specified. For other customizations the caller can install a WH_MSGFILTER hook. The hook will get called with nCode = MSGF_OVPN_WAIT and lParam = &msg. - Use this in place of Sleep in main.c, scripts.c and PLAP dll. Fixes #576 Signed-off-by: Selva Nair <selva.nair@gmail.com>pull/608/head
							parent
							
								
									141a687ddd
								
							
						
					
					
						commit
						2b1e5867f0
					
				
							
								
								
									
										9
									
								
								main.c
								
								
								
								
							
							
						
						
									
										9
									
								
								main.c
								
								
								
								
							| 
						 | 
				
			
			@ -376,11 +376,14 @@ StopAllOpenVPN()
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Wait for all connections to terminate (Max 5 sec) */
 | 
			
		||||
    for (i = 0; i < 20; i++, Sleep(250))
 | 
			
		||||
    /* Wait for all connections to terminate (Max 20 rounds of 250 msec = 5 sec) */
 | 
			
		||||
    for (i = 0; i < 20; i++)
 | 
			
		||||
    {
 | 
			
		||||
        if (CountConnState(disconnected) + CountConnState(detached) == o.num_configs)
 | 
			
		||||
        if (CountConnState(disconnected) + CountConnState(detached) == o.num_configs
 | 
			
		||||
            || !OVPNMsgWait(250, NULL)) /* Quit received */
 | 
			
		||||
        {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								main.h
								
								
								
								
							
							
						
						
									
										2
									
								
								main.h
								
								
								
								
							| 
						 | 
				
			
			@ -65,6 +65,8 @@
 | 
			
		|||
#define WM_OVPN_STATE          (WM_APP + 23)
 | 
			
		||||
#define WM_OVPN_DETACH         (WM_APP + 24)
 | 
			
		||||
 | 
			
		||||
#define MSGF_OVPN_WAIT         (MSGF_USER + 1)
 | 
			
		||||
 | 
			
		||||
/* bool definitions */
 | 
			
		||||
#define bool int
 | 
			
		||||
#define true 1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								manage.c
								
								
								
								
							
							
						
						
									
										2
									
								
								manage.c
								
								
								
								
							| 
						 | 
				
			
			@ -345,7 +345,7 @@ OnManagement(SOCKET sk, LPARAM lParam)
 | 
			
		|||
                else if (strncmp(pos, "INFO:", 5) == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    /* delay until management interface accepts input */
 | 
			
		||||
                    Sleep(100);
 | 
			
		||||
                    OVPNMsgWait(100, c->hwndStatus);
 | 
			
		||||
                    c->manage.connected = 2;
 | 
			
		||||
                    if (rtmsg_handler[ready_])
 | 
			
		||||
                        rtmsg_handler[ready_](c, pos + 5);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										36
									
								
								misc.c
								
								
								
								
							
							
						
						
									
										36
									
								
								misc.c
								
								
								
								
							| 
						 | 
				
			
			@ -1046,3 +1046,39 @@ RunAsAdmin(const WCHAR *cmd, const WCHAR *params)
 | 
			
		|||
    }
 | 
			
		||||
    return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Like sleep but service messages. If hdlg is not NULL
 | 
			
		||||
 * dialog messages for it are checked. Also services
 | 
			
		||||
 * MSG_FILTER hooks if caller wants further special processing.
 | 
			
		||||
 * Returns false on if WM_QUIT received else returns true (on timeout).
 | 
			
		||||
 */
 | 
			
		||||
bool
 | 
			
		||||
OVPNMsgWait(DWORD timeout, HWND hdlg)
 | 
			
		||||
{
 | 
			
		||||
    ULONGLONG now = GetTickCount64();
 | 
			
		||||
    ULONGLONG end = now + timeout;
 | 
			
		||||
 | 
			
		||||
    while (end > now)
 | 
			
		||||
    {
 | 
			
		||||
        if (MsgWaitForMultipleObjectsEx(0, NULL, end - now, QS_ALLINPUT, MWMO_INPUTAVAILABLE) == WAIT_OBJECT_0)
 | 
			
		||||
        {
 | 
			
		||||
            MSG msg;
 | 
			
		||||
            while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
 | 
			
		||||
            {
 | 
			
		||||
                if (msg.message == WM_QUIT)
 | 
			
		||||
                {
 | 
			
		||||
                    PostQuitMessage((int) msg.wParam);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                else if (!CallMsgFilter(&msg, MSGF_OVPN_WAIT)
 | 
			
		||||
                         && (!hdlg || !IsDialogMessage(hdlg, &msg)))
 | 
			
		||||
                {
 | 
			
		||||
                    TranslateMessage(&msg);
 | 
			
		||||
                    DispatchMessage(&msg);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        now = GetTickCount64();
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										9
									
								
								misc.h
								
								
								
								
							
							
						
						
									
										9
									
								
								misc.h
								
								
								
								
							| 
						 | 
				
			
			@ -150,4 +150,13 @@ DWORD SetPLAPRegistration(BOOL action);
 | 
			
		|||
 */
 | 
			
		||||
DWORD RunAsAdmin(const WCHAR *cmd, const WCHAR *params);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Wait for a timeout while pumping messages. If hdlg is not NULL
 | 
			
		||||
 * IsDialogMessage(hdlg, ...) is checked before dispatching messages.
 | 
			
		||||
 * caller can install a WH_MSGFILTER hook if any other special processing
 | 
			
		||||
 * is necessary. The hook will get called with ncode = MSGF_OVPN_WAIT.
 | 
			
		||||
 * @returns false if WM_QUIT was received, else returns true on timeout.
 | 
			
		||||
 */
 | 
			
		||||
bool OVPNMsgWait(DWORD timeout, HWND hdlg);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2753,7 +2753,7 @@ ReadLineFromStdOut(HANDLE hStdOut, char *line, DWORD size)
 | 
			
		|||
        if (read == size)
 | 
			
		||||
            return FALSE;
 | 
			
		||||
 | 
			
		||||
        Sleep(100);
 | 
			
		||||
        Sleep(100); /* called when no UI is yet initialized */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!ReadFile(hStdOut, line, len, &read, NULL) || read != len)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,8 @@
 | 
			
		|||
#include "resource.h"
 | 
			
		||||
#include "localization.h"
 | 
			
		||||
#include "openvpn-gui-res.h"
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
 | 
			
		||||
/* A "class" that implements IConnectableCredentialProviderCredential */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -607,7 +609,7 @@ again:
 | 
			
		|||
 | 
			
		||||
    ConnectHelper(oc->c);
 | 
			
		||||
 | 
			
		||||
    Sleep(100);
 | 
			
		||||
    OVPNMsgWait(100, NULL);
 | 
			
		||||
 | 
			
		||||
    /* if not immediately connected, show a progress dialog with
 | 
			
		||||
     * service state changes and retry/cancel options. Progress dialog
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -405,7 +405,7 @@ DetachAllOpenVPN()
 | 
			
		|||
        {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        Sleep(100);
 | 
			
		||||
        OVPNMsgWait(100, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (connection_t *c = o.chead; c; c = c->next)
 | 
			
		||||
| 
						 | 
				
			
			@ -481,7 +481,7 @@ DisconnectHelper(connection_t *c)
 | 
			
		|||
    time_t timeout = time(NULL) + 5;
 | 
			
		||||
    while (timeout > time(NULL) && c->state != onhold && c->state != disconnected)
 | 
			
		||||
    {
 | 
			
		||||
        Sleep(100);
 | 
			
		||||
        OVPNMsgWait(100, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ShowWindowAsync(GetDlgItem(c->hwndStatus, ID_DISCONNECT), SW_HIDE);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										34
									
								
								scripts.c
								
								
								
								
							
							
						
						
									
										34
									
								
								scripts.c
								
								
								
								
							| 
						 | 
				
			
			@ -94,17 +94,17 @@ RunPreconnectScript(connection_t *c)
 | 
			
		|||
                       NULL, c->config_dir, &si, &pi))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    /* Wait process without blocking msg pump */
 | 
			
		||||
    for (i = 0; i <= (int) o.preconnectscript_timeout; i++)
 | 
			
		||||
    {
 | 
			
		||||
        if (!GetExitCodeProcess(pi.hProcess, &exit_code))
 | 
			
		||||
            goto out;
 | 
			
		||||
 | 
			
		||||
        if (exit_code != STILL_ACTIVE)
 | 
			
		||||
            goto out;
 | 
			
		||||
 | 
			
		||||
        Sleep(1000);
 | 
			
		||||
        if (!GetExitCodeProcess(pi.hProcess, &exit_code)
 | 
			
		||||
            || exit_code != STILL_ACTIVE
 | 
			
		||||
            || !OVPNMsgWait(1000, NULL))
 | 
			
		||||
        {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
out:
 | 
			
		||||
 | 
			
		||||
    CloseHandle(pi.hThread);
 | 
			
		||||
    CloseHandle(pi.hProcess);
 | 
			
		||||
    if (logfile_handle != NULL)
 | 
			
		||||
| 
						 | 
				
			
			@ -180,7 +180,7 @@ RunConnectScript(connection_t *c, int run_as_service)
 | 
			
		|||
    {
 | 
			
		||||
        if (!GetExitCodeProcess(pi.hProcess, &exit_code))
 | 
			
		||||
        {
 | 
			
		||||
            ShowLocalizedMsg(IDS_ERR_GET_EXIT_CODE, cmdline);
 | 
			
		||||
            ShowLocalizedMsgEx(MB_OK|MB_ICONERROR, c->hwndStatus, TEXT(PACKAGE_NAME), IDS_ERR_GET_EXIT_CODE, cmdline);
 | 
			
		||||
            goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -191,7 +191,10 @@ RunConnectScript(connection_t *c, int run_as_service)
 | 
			
		|||
            goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Sleep(1000);
 | 
			
		||||
        if (!OVPNMsgWait(1000, c->hwndStatus)) /* WM_QUIT -- do not popup error */
 | 
			
		||||
        {
 | 
			
		||||
            goto out;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ShowLocalizedMsgEx(MB_OK|MB_ICONERROR, c->hwndStatus, TEXT(PACKAGE_NAME), IDS_ERR_RUN_CONN_SCRIPT_TIMEOUT, o.connectscript_timeout);
 | 
			
		||||
| 
						 | 
				
			
			@ -266,13 +269,12 @@ RunDisconnectScript(connection_t *c, int run_as_service)
 | 
			
		|||
 | 
			
		||||
    for (i = 0; i <= (int) o.disconnectscript_timeout; i++)
 | 
			
		||||
    {
 | 
			
		||||
        if (!GetExitCodeProcess(pi.hProcess, &exit_code))
 | 
			
		||||
        if (!GetExitCodeProcess(pi.hProcess, &exit_code)
 | 
			
		||||
            || exit_code != STILL_ACTIVE
 | 
			
		||||
            || !OVPNMsgWait(1000, c->hwndStatus)) /* WM_QUIT -- do not popup error */
 | 
			
		||||
        {
 | 
			
		||||
            goto out;
 | 
			
		||||
 | 
			
		||||
        if (exit_code != STILL_ACTIVE)
 | 
			
		||||
            goto out;
 | 
			
		||||
 | 
			
		||||
        Sleep(1000);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
out:
 | 
			
		||||
    free(env);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue