3c0e5ea4d7
A .NET pipe opened Asynchronous completes even its synchronous Read/Write through the thread pool's completion port, so every frame on Windows cost a completion packet plus a pool work item (and the pool's spin-wait). New WindowsBlockingPipeStream issues its own overlapped ReadFile/WriteFile with the OVERLAPPED.hEvent low bit set (no completion packet) and waits on that event on the calling thread; reads and writes stay concurrent, unlike a synchronous handle. ScriptWorkerFrameCodec.BlockingStream picks it on Windows and the pipe itself on Unix, so both ends now use the dedicated blocking reader + synchronous combining writer on every OS (UseBlockingIo and the async read loops are gone). Claude-Session: https://claude.ai/code/session_01GT67AD99zQQqpLCVm3p7xk
31 lines
1.2 KiB
XML
31 lines
1.2 KiB
XML
<Project Sdk="Microsoft.NET.Sdk">
|
|
|
|
<PropertyGroup>
|
|
<RootNamespace>ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol</RootNamespace>
|
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
|
<!-- protoc-generated members carry no XML docs. -->
|
|
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
|
<!-- WindowsBlockingPipeStream issues its own overlapped pipe I/O (lmxopcua#789). -->
|
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|
</PropertyGroup>
|
|
|
|
<!-- lmxopcua#780: the host <-> ScriptWorker frame protocol (design §4). Shared by the host-side runner and the
|
|
worker, so it references nothing but Google.Protobuf: the worker's assembly set stays small (design §6). -->
|
|
<ItemGroup>
|
|
<PackageReference Include="Google.Protobuf"/>
|
|
<PackageReference Include="Grpc.Tools">
|
|
<PrivateAssets>all</PrivateAssets>
|
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
</PackageReference>
|
|
</ItemGroup>
|
|
|
|
<ItemGroup>
|
|
<Protobuf Include="Protos\script_worker.proto" GrpcServices="None"/>
|
|
</ItemGroup>
|
|
|
|
<ItemGroup>
|
|
<InternalsVisibleTo Include="ZB.MOM.WW.OtOpcUa.ScriptWorker.Tests"/>
|
|
</ItemGroup>
|
|
|
|
</Project>
|