Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET
Roslyn
提交
b3bba197
R
Roslyn
项目概览
dotNET
/
Roslyn
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
b3bba197
编写于
4月 03, 2018
作者:
J
Jared Parsons
提交者:
GitHub
4月 03, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #25650 from jaredpar/fix-server
Account for Mutex ctor throwing
上级
8120db1a
35dedea7
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
80 addition
and
29 deletion
+80
-29
src/Compilers/Server/VBCSCompilerTests/DesktopBuildClientTests.cs
...ilers/Server/VBCSCompilerTests/DesktopBuildClientTests.cs
+27
-0
src/Compilers/Shared/BuildServerConnection.cs
src/Compilers/Shared/BuildServerConnection.cs
+53
-29
未找到文件。
src/Compilers/Server/VBCSCompilerTests/DesktopBuildClientTests.cs
浏览文件 @
b3bba197
...
...
@@ -15,6 +15,7 @@
using
Roslyn.Test.Utilities
;
using
System.Threading
;
using
System.IO.Pipes
;
using
System.Security.AccessControl
;
namespace
Microsoft.CodeAnalysis.CompilerServer.UnitTests
{
...
...
@@ -145,6 +146,32 @@ public void ConnectToServerFails()
}
}
#if NET461
[
Fact
]
public
void
TestMutexConstructorException
()
{
using
(
var
outer
=
new
Mutex
(
initiallyOwned
:
true
,
name
:
BuildServerConnection
.
GetClientMutexName
(
_pipeName
),
out
bool
createdNew
))
{
Assert
.
True
(
createdNew
);
var
mutexSecurity
=
outer
.
GetAccessControl
();
var
user
=
Environment
.
UserDomainName
+
"\\"
+
Environment
.
UserName
;
mutexSecurity
.
AddAccessRule
(
new
MutexAccessRule
(
user
,
MutexRights
.
FullControl
,
AccessControlType
.
Deny
));
outer
.
SetAccessControl
(
mutexSecurity
);
var
ranLocal
=
false
;
var
client
=
CreateClient
(
compileFunc
:
delegate
{
ranLocal
=
true
;
return
0
;
});
var
exitCode
=
client
.
RunCompilation
(
new
[]
{
"/shared"
},
_buildPaths
).
ExitCode
;
Assert
.
Equal
(
0
,
exitCode
);
Assert
.
True
(
ranLocal
);
}
}
#endif
[
Fact
]
public
async
Task
ConnectToPipe
()
{
...
...
src/Compilers/Shared/BuildServerConnection.cs
浏览文件 @
b3bba197
...
...
@@ -118,47 +118,62 @@ internal sealed class BuildServerConnection
var
clientDir
=
buildPaths
.
ClientDirectory
;
var
timeoutNewProcess
=
timeoutOverride
??
TimeOutMsNewProcess
;
var
timeoutExistingProcess
=
timeoutOverride
??
TimeOutMsExistingProcess
;
var
clientMutexName
=
GetClientMutexName
(
pipeName
);
Task
<
NamedPipeClientStream
>
pipeTask
=
null
;
using
(
var
clientMutex
=
new
Mutex
(
initiallyOwned
:
true
,
name
:
clientMutexName
,
createdNew
:
out
var
holdsMutex
))
Mutex
clientMutex
=
null
;
var
holdsMutex
=
false
;
try
{
try
{
if
(!
holdsMutex
)
var
clientMutexName
=
GetClientMutexName
(
pipeName
);
clientMutex
=
new
Mutex
(
initiallyOwned
:
true
,
name
:
clientMutexName
,
out
holdsMutex
);
}
catch
{
// The Mutex constructor can throw in certain cases. One specific example is docker containers
// where the /tmp directory is restricted. In those cases there is no reliable way to execute
// the server and we need to fall back to the command line.
//
// Example: https://github.com/dotnet/roslyn/issues/24124
return
new
RejectedBuildResponse
();
}
if
(!
holdsMutex
)
{
try
{
try
{
holdsMutex
=
clientMutex
.
WaitOne
(
timeoutNewProcess
);
holdsMutex
=
clientMutex
.
WaitOne
(
timeoutNewProcess
);
if
(!
holdsMutex
)
{
return
new
RejectedBuildResponse
();
}
}
catch
(
AbandonedMutexException
)
if
(!
holdsMutex
)
{
holdsMutex
=
true
;
return
new
RejectedBuildResponse
()
;
}
}
// Check for an already running server
var
serverMutexName
=
GetServerMutexName
(
pipeName
);
bool
wasServerRunning
=
WasServerMutexOpen
(
serverMutexName
);
var
timeout
=
wasServerRunning
?
timeoutExistingProcess
:
timeoutNewProcess
;
if
(
wasServerRunning
||
tryCreateServerFunc
(
clientDir
,
pipeName
))
catch
(
AbandonedMutexException
)
{
pipeTask
=
TryConnectToServerAsync
(
pipeName
,
timeout
,
cancellationToken
)
;
holdsMutex
=
true
;
}
}
finally
// Check for an already running server
var
serverMutexName
=
GetServerMutexName
(
pipeName
);
bool
wasServerRunning
=
WasServerMutexOpen
(
serverMutexName
);
var
timeout
=
wasServerRunning
?
timeoutExistingProcess
:
timeoutNewProcess
;
if
(
wasServerRunning
||
tryCreateServerFunc
(
clientDir
,
pipeName
))
{
pipeTask
=
TryConnectToServerAsync
(
pipeName
,
timeout
,
cancellationToken
);
}
}
finally
{
if
(
clientMutex
!=
null
)
{
if
(
holdsMutex
)
{
clientMutex
.
ReleaseMutex
();
}
clientMutex
.
Dispose
();
}
}
...
...
@@ -555,12 +570,21 @@ internal static string GetBasePipeName(string compilerExeDirectory)
internal
static
bool
WasServerMutexOpen
(
string
mutexName
)
{
Mutex
mutex
;
var
open
=
Mutex
.
TryOpenExisting
(
mutexName
,
out
mutex
);
if
(
open
)
try
{
mutex
.
Dispose
();
return
true
;
Mutex
mutex
;
var
open
=
Mutex
.
TryOpenExisting
(
mutexName
,
out
mutex
);
if
(
open
)
{
mutex
.
Dispose
();
return
true
;
}
}
catch
{
// In the case an exception occured trying to open the Mutex then
// the assumption is that it's not open.
return
false
;
}
return
false
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录