PSReadLine: OnIdle Doesn't Seem to Fire Until PowerShell is Not Idle

Environment data

PS version: 7.0.0-preview.4 PSReadline version: 2.0.0-beta5 os: Darwin Nick-Coxs-Macbook-Pro.local 18.7.0 Darwin Kernel Version 18.7.0: Tue Aug 20 16:57:14 PDT 2019; root:xnu-4903.271.2~2/RELEASE_X86_64 x86_64 PS file version: 7.0.0.0 HostName: ConsoleHost BufferWidth: 238 BufferHeight: 59

Steps to reproduce or exception report

Without PSReadLine

❯ pwsh -nologo -noprofile
PS /Users/nick.cox> Remove-Module PSReadline
PS /Users/nick.cox> $null = Register-EngineEvent -SourceIdentifier PowerShell.OnIdle -Action {Write-Host  '*idle*'} -MaxTriggerCount 3
PS /Users/nick.cox> *idle*
*idle*
*idle*

With PSReadLine

❯ pwsh -nologo -noprofile
PS /Users/nick.cox> Get-Module PSReadline
ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     2.0.0      PSReadLine                          {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PSReadLineKeyHandler, Set-PSReadLineKeyHandler…}

PS /Users/nick.cox> $null = Register-EngineEvent -SourceIdentifier PowerShell.OnIdle -Action {Write-Host  '*idle*'} -MaxTriggerCount 3
PS /Users/nick.cox> *idle*
# ... (nothing happens until I press a key)
a*idle*
aa*idle*

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 15 (9 by maintainers)

Most upvoted comments

Of course, please update the environment data. Thanks

👍Works for me on preview 4, @daxian-dbw

Right now the issue is that Console.ReadKey is blocking on one thread, and then on the pipeline thread cursor position is checked before triggering events. The call to ReadKey will hold corefx’s internal lock on stdin, then the cursor position query will attempt to acquire that same lock (in core 3.0 it’s not every time, but frequently enough that it’s not a fix). That causes the pipeline thread to block until ReadKey completes. Afaict that wouldn’t change if PSConsoleHostReadLine was skipped.

I think you discussed removing that cursor position check in the ReadKey timeout loop at one point. If nothing else queries cursor position that will work. I vaguely remember something in the general pipeline spin up/wind down code path that queries cursor position but I might be thinking of ConsoleHost. Though if an event handler needed to check cursor position it would still lock.