Skip to content

Commit 162fe67

Browse files
annie-liYanVugenfirer
authored andcommitted
viogpusc: Fix the timeout issue when stopping viogpusc service
When the user stops the viogpusc service either through SCM or console command line, a timeout error is thrown out as the following, From the console, The service did not respond to the start or control request in a timely fashion. From SCM A timeout was reached while waiting for a transaction response from the viogpusc service. This error is due to the incomplete initialization of the Session creating viogpuap process. This initialization is blocked until the process is terminated. When SCM or console command tries to stop the service, it always fails because the Session is waiting for the process to be terminated. Actually, the process is waiting for the service to trigger an event to terminate itself. This is a dead loop. To fix this issue, the Session initialization should be completed, and the Session Manager should monitor the termination of the process and release the resources after the process is terminated. Signed-off-by: Annie Li <[email protected]>
1 parent 96b358e commit 162fe67

File tree

4 files changed

+62
-39
lines changed

4 files changed

+62
-39
lines changed

viogpu/viogpusc/Session.cpp

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@
3232
#include "pipe.h"
3333

3434

35-
CSession::CSession(ULONG Id) : m_PipeServer(NULL)
35+
CSession::CSession(ULONG Id) :
36+
m_PipeServer(NULL),
37+
m_hToken(NULL),
38+
m_lpvEnv(NULL)
3639
{
3740
PrintMessage(L"%ws Id = %d\n", __FUNCTIONW__, Id);
3841

@@ -71,6 +74,30 @@ void CSession::Close(void)
7174
delete m_PipeServer;
7275
m_PipeServer = NULL;
7376
}
77+
78+
if (m_hToken)
79+
{
80+
CloseHandle(m_hToken);
81+
m_hToken = NULL;
82+
}
83+
84+
if (m_lpvEnv)
85+
{
86+
DestroyEnvironmentBlock(m_lpvEnv);
87+
m_lpvEnv = NULL;
88+
}
89+
90+
if (m_ProcessInfo.hProcess)
91+
{
92+
CloseHandle(m_ProcessInfo.hProcess);
93+
m_ProcessInfo.hProcess = NULL;
94+
}
95+
96+
if (m_ProcessInfo.hThread)
97+
{
98+
CloseHandle(m_ProcessInfo.hThread);
99+
m_ProcessInfo.hThread = NULL;
100+
}
74101
}
75102

76103
void CSession::Pause(void)
@@ -83,13 +110,10 @@ void CSession::Resume(void)
83110

84111
bool CSession::CreateProcessInSession(const std::wstring & commandLine)
85112
{
86-
HANDLE hToken = NULL;
87113
STARTUPINFO si = { sizeof(si) };
88-
LPVOID lpvEnv = NULL;
89114
DWORD dwError = ERROR_SUCCESS;
90115
wchar_t szUserProfileDir[MAX_PATH];
91116
DWORD cchUserProfileDir = ARRAYSIZE(szUserProfileDir);
92-
DWORD ExitCode;
93117
DWORD dwWaitResult;
94118

95119
PrintMessage(L"%ws\n", __FUNCTIONW__);
@@ -101,7 +125,7 @@ bool CSession::CreateProcessInSession(const std::wstring & commandLine)
101125
break;
102126
}
103127

104-
if (!WTSQueryUserToken(m_SessionInfo.SessionId, &hToken))
128+
if (!WTSQueryUserToken(m_SessionInfo.SessionId, &m_hToken))
105129
{
106130
dwError = GetLastError();
107131
PrintMessage(L"WTSQueryUserToken failed with error 0x%x\n", dwError);
@@ -111,23 +135,23 @@ bool CSession::CreateProcessInSession(const std::wstring & commandLine)
111135
TOKEN_LINKED_TOKEN admin = {};
112136
HANDLE hAdmToken = 0;
113137
DWORD dw = 0;
114-
if (GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS)TokenLinkedToken, &admin, sizeof(TOKEN_LINKED_TOKEN), &dw))
138+
if (GetTokenInformation(m_hToken, (TOKEN_INFORMATION_CLASS)TokenLinkedToken, &admin, sizeof(TOKEN_LINKED_TOKEN), &dw))
115139
{
116140
hAdmToken = admin.LinkedToken;
117141
}
118142
else
119143
{
120-
DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hAdmToken);
144+
DuplicateTokenEx(m_hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hAdmToken);
121145
}
122146

123-
if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE))
147+
if (!CreateEnvironmentBlock(&m_lpvEnv, m_hToken, TRUE))
124148
{
125149
dwError = GetLastError();
126150
PrintMessage(L"CreateEnvironmentBlock failed with error 0x%x\n", dwError);
127151
break;
128152
}
129153

130-
if (!GetUserProfileDirectory(hToken, szUserProfileDir,
154+
if (!GetUserProfileDirectory(m_hToken, szUserProfileDir,
131155
&cchUserProfileDir))
132156
{
133157
dwError = GetLastError();
@@ -138,43 +162,14 @@ bool CSession::CreateProcessInSession(const std::wstring & commandLine)
138162
si.lpDesktop = TEXT("winsta0\\default");
139163

140164
if (!CreateProcessAsUser(hAdmToken, NULL, const_cast<wchar_t *>(commandLine.c_str()), NULL, NULL, FALSE,
141-
CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW, lpvEnv, szUserProfileDir, &si, &m_ProcessInfo))
165+
CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW, m_lpvEnv, szUserProfileDir, &si, &m_ProcessInfo))
142166
{
143167
dwError = GetLastError();
144168
PrintMessage(L"CreateProcessAsUser failed with error 0x%x\n", dwError);
145169
break;
146170
}
147-
148-
WaitForSingleObject(m_ProcessInfo.hProcess, INFINITE);
149-
GetExitCodeProcess(m_ProcessInfo.hProcess, &ExitCode);
150-
PrintMessage(L"Process finished with code 0x%x\n", ExitCode);
151-
152171
} while (0);
153172

154-
if (hToken)
155-
{
156-
CloseHandle(hToken);
157-
hToken = NULL;
158-
}
159-
160-
if (lpvEnv)
161-
{
162-
DestroyEnvironmentBlock(lpvEnv);
163-
lpvEnv = NULL;
164-
}
165-
166-
if (m_ProcessInfo.hProcess)
167-
{
168-
CloseHandle(m_ProcessInfo.hProcess);
169-
m_ProcessInfo.hProcess = NULL;
170-
}
171-
172-
if (m_ProcessInfo.hThread)
173-
{
174-
CloseHandle(m_ProcessInfo.hThread);
175-
m_ProcessInfo.hThread = NULL;
176-
}
177-
178173
if (dwError != ERROR_SUCCESS)
179174
{
180175
SetLastError(dwError);

viogpu/viogpusc/Session.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class CSession
4848
HANDLE GetProcess(void) { return m_SessionInfo.hProcess; }
4949
void SetProcess(HANDLE Handle) { m_SessionInfo.hProcess = Handle; }
5050
ULONG GetId(void) { return m_SessionInfo.SessionId; }
51+
HANDLE GetCreateProcess(void) { return m_ProcessInfo.hProcess; }
5152
private:
5253
bool PipeServerActive(void) { return (m_PipeServer != NULL); }
5354
bool CreateProcessInSession(const std::wstring & commandLine);
@@ -56,5 +57,7 @@ class CSession
5657
PipeServer* m_PipeServer;
5758
SESSION_INFORMATION m_SessionInfo;
5859
PROCESS_INFORMATION m_ProcessInfo;
60+
HANDLE m_hToken;
61+
LPVOID m_lpvEnv;
5962
};
6063

viogpu/viogpusc/SessionMgr.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,18 @@ CSessionMgr::~CSessionMgr()
4343

4444
DWORD WINAPI CSessionMgr::ServiceThread(CSessionMgr* prt)
4545
{
46+
HANDLE hProcessHandle;
47+
DWORD ExitCode;
48+
4649
prt->Run();
50+
for (Iterator it = prt->Sessions.begin(); it != prt->Sessions.end(); it++)
51+
{
52+
hProcessHandle = prt->GetSessioinCreateProcess((*it)->GetId());
53+
WaitForSingleObject(hProcessHandle, INFINITE);
54+
GetExitCodeProcess(hProcessHandle, &ExitCode);
55+
PrintMessage(L"Process finished with code 0x%x\n", ExitCode);
56+
}
57+
4758
return 0;
4859
}
4960

@@ -106,6 +117,7 @@ void CSessionMgr::Close()
106117

107118
for (Iterator it = Sessions.begin(); it != Sessions.end(); it++)
108119
{
120+
(*it)->Close();
109121
delete *it;
110122
}
111123

@@ -135,6 +147,18 @@ void CSessionMgr::SetSessionStatus(UINT Indx, SESSION_STATUS status)
135147
}
136148
}
137149

150+
HANDLE CSessionMgr::GetSessioinCreateProcess(UINT Indx)
151+
{
152+
PrintMessage(L"%ws\n", __FUNCTIONW__);
153+
154+
CSession* ptr = FindSession(Indx);
155+
if (ptr) {
156+
return (ptr)->GetCreateProcess();
157+
}
158+
159+
return (HANDLE)NULL;
160+
}
161+
138162
HANDLE CSessionMgr::GetSessioinProcess(UINT Indx)
139163
{
140164
PrintMessage(L"%ws\n", __FUNCTIONW__);

viogpu/viogpusc/SessionMgr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class CSessionMgr
4444
void SetSessionStatus(UINT Indx, SESSION_STATUS status);
4545
HANDLE GetSessioinProcess(UINT Indx);
4646
void SetSessionProcess(UINT Indx, HANDLE Handle);
47+
HANDLE GetSessioinCreateProcess(UINT Indx);
4748
private:
4849
CSession* FindSession(ULONG Indx, bool bCreate = false);
4950
void AddSession(CSession* session);

0 commit comments

Comments
 (0)