Skip to content

Add non-blocking read mode to SocketCan CanRaw - #2557

Open
raffaeler with Copilot wants to merge 5 commits into
mainfrom
copilot/tryreadframe-nonblocking-mode
Open

Add non-blocking read mode to SocketCan CanRaw#2557
raffaeler with Copilot wants to merge 5 commits into
mainfrom
copilot/tryreadframe-nonblocking-mode

Conversation

Copilot AI commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

CanRaw.TryReadFrame always blocks until a frame arrives, with no way to poll the bus. This adds an opt-in non-blocking mode (the O_NONBLOCK / MSG_DONTWAIT equivalent).

Changes

  • CanRaw.Blocking property — defaults to true (existing behavior). Set to false to switch the socket to non-blocking mode via fcntl(O_NONBLOCK).
  • Interop.Read — now uses SetLastError and treats EAGAIN/EWOULDBLOCK as "no data" (returns a sentinel) instead of throwing.
  • TryReadFrame — returns false immediately when no frame is available in non-blocking mode; the timestamp overload skips the SIOCGSTAMP ioctl when no frame was read.
  • README — added a non-blocking usage example.

Usage

using CanRaw can = new CanRaw();
can.Blocking = false;
byte[] buffer = new byte[8];

while (true)
{
    if (can.TryReadFrame(buffer, out int frameLength, out CanId id))
    {
        // process frame
    }
    else
    {
        // no frame available right now — do other work instead of blocking
        Thread.Sleep(10);
    }
}

Notes

  • Default callers are unaffected; non-blocking is strictly opt-in.
  • In non-blocking mode false now also signals "no frame available" in addition to the existing "invalid frame" case — both indicate no usable frame was returned.
  • The fcntl flag constants are Linux-specific, consistent with this Linux-only device binding.

@dotnet-policy-service dotnet-policy-service Bot added the area-device-bindings Device Bindings for audio, sensor, motor, and display hardware that can used with System.Device.Gpio label Jun 2, 2026
Copilot AI changed the title [WIP] Add non-blocking mode option for TryReadFrame in SocketCan Add non-blocking read mode to SocketCan CanRaw Jun 2, 2026
Copilot AI requested a review from raffaeler June 2, 2026 16:01

@raffaeler raffaeler left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to test this on a real project.
Any volunteer?

Comment thread src/devices/SocketCan/CanRaw.cs Outdated
/// non-blocking mode and <see cref="TryReadFrame(Span{byte}, out int, out CanId)"/> returns
/// <see langword="false"/> immediately when no frame is available to read.
/// </remarks>
public bool Blocking

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot please rename Blocking property it so it has Read and something with waiting in the name. Do research what good descriptive name could be. Also change interop method name to match the new name

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed Blocking to WaitForFrameOnRead (includes Read and the waiting concept) and renamed the interop method to SetWaitForFrameOnRead to match. Done in c6702b5.

@krwq
krwq marked this pull request as ready for review August 13, 2026 15:58
Copilot AI and others added 2 commits August 13, 2026 16:00
Co-authored-by: krwq <660048+krwq@users.noreply.github.com>
Co-authored-by: krwq <660048+krwq@users.noreply.github.com>
Copilot AI requested a review from krwq August 13, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-device-bindings Device Bindings for audio, sensor, motor, and display hardware that can used with System.Device.Gpio

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Iot.Device.SocketCan -> TryReadFrame() offer nonblocking mode?

4 participants