Skip to content

Commit

Permalink
Fix double dispatch on linux (dotnet#43931)
Browse files Browse the repository at this point in the history
* Fix double dispatch on linux
  * Fixing a regression introduced into linux sockets workloads when removing double dispatching on windows. We only want to dispatch by default if we're running on the old windows IO threadpool.
* Update src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionContextFactory.cs

Co-authored-by: Aditya Mandaleeka <[email protected]>
  • Loading branch information
davidfowl and adityamandaleeka authored Sep 13, 2022
1 parent 5772c03 commit 1e9b6d6
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public SocketSenderPool(PipeScheduler scheduler)
_scheduler = scheduler;
}

public PipeScheduler Scheduler => _scheduler;

public SocketSender Rent()
{
if (_queue.TryDequeue(out var sender))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ public SocketConnectionContextFactory(SocketConnectionFactoryOptions options, IL
var maxWriteBufferSize = _options.MaxWriteBufferSize ?? 0;
var applicationScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : PipeScheduler.ThreadPool;

// Socket callbacks run on the threads polling for IO if we're using the old Windows thread pool
var dispatchSocketCallbacks = OperatingSystem.IsWindows() &&
(Environment.GetEnvironmentVariable("DOTNET_ThreadPool_UsePortableThreadPoolForIO") == "0" ||
Environment.GetEnvironmentVariable("COMPlus_ThreadPool_UsePortableThreadPoolForIO") == "0");

PipeScheduler SelectSocketsScheduler(PipeScheduler dispatchingScheduler) =>
dispatchSocketCallbacks ? dispatchingScheduler : PipeScheduler.Inline;

if (_settingsCount > 0)
{
_settings = new QueueSettings[_settingsCount];
Expand All @@ -56,13 +64,14 @@ public SocketConnectionContextFactory(SocketConnectionFactoryOptions options, IL
{
var memoryPool = _options.MemoryPoolFactory();
var transportScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : new IOQueue();
var socketsScheduler = SelectSocketsScheduler(transportScheduler);

_settings[i] = new QueueSettings()
{
Scheduler = transportScheduler,
InputOptions = new PipeOptions(memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false),
OutputOptions = new PipeOptions(memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false),
SocketSenderPool = new SocketSenderPool(transportScheduler),
SocketSenderPool = new SocketSenderPool(socketsScheduler),
MemoryPool = memoryPool,
};
}
Expand All @@ -71,14 +80,16 @@ public SocketConnectionContextFactory(SocketConnectionFactoryOptions options, IL
{
var memoryPool = _options.MemoryPoolFactory();
var transportScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : PipeScheduler.ThreadPool;
var socketsScheduler = SelectSocketsScheduler(transportScheduler);

_settings = new QueueSettings[]
{
new QueueSettings()
{
Scheduler = transportScheduler,
InputOptions = new PipeOptions(memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false),
OutputOptions = new PipeOptions(memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false),
SocketSenderPool = new SocketSenderPool(PipeScheduler.Inline),
SocketSenderPool = new SocketSenderPool(socketsScheduler),
MemoryPool = memoryPool,
}
};
Expand All @@ -97,7 +108,7 @@ public ConnectionContext Create(Socket socket)

var connection = new SocketConnection(socket,
setting.MemoryPool,
PipeScheduler.Inline,
setting.SocketSenderPool.Scheduler,
_logger,
setting.SocketSenderPool,
setting.InputOptions,
Expand Down

0 comments on commit 1e9b6d6

Please sign in to comment.