Skip to content

Possible deadlock using serial communication #52

@RevZero

Description

@RevZero

NuGet Package Version

3.4.0

Payment service provider

irrelevant

Payment terminal

irrelevant

Communication Logs

13:35:17.560 info: Portalum.Zvt.ZvtClient[0] RegistrationAsync - Execute
13:35:17.564 dbug: Portalum.Zvt.ZvtClient[0] SendCommandAsync - Send command to PT
13:35:17.568 dbug: Portalum.Zvt.SerialPortDeviceCommunication[0] SendRaw - 10-02-06-00-10-10-00-00-00-BE-09-78-03-01-06-06-26-04-0A-02-06-D3-10-03-D7-DE

More information

Should be easy to reproduce, by just sending a command without any device attached.

The SerialPortDeviceCommunication.SendAsync() may never return from

var byte1 = (byte)this._serialPort.ReadByte();

I am not sure, why ReadByte() doesn't return -1 as stated in the MS documentation.

The byte, cast to an Int32, or -1 if the end of the stream has been read.

To avoid the synchronous blocking, we could check if there is any data to be read before calling ReadByte() like this:

if (_serialPort.BytesToRead <= 0)
{
    await Task.Delay(10, cancellationToken).ConfigureAwait(false);
    continue;
}

However, there is still the issue, that if no timeout based CancellationToken was supplied to the SendAsync(), it will never exit the loop. Looking at the code, there are quite a lot of calls where the token is ommitted:

Image

The call from SendCommandAsync() also does not implement an internal timeout. The user supplied token will be considered, but the timeout should be an implementation detail and not something, the user of the API has to consider by providing a timeout.

I am not sure about the best approach here. The ACK seems to belong to the serial protocol layer, so SendAsync() should probably implement a timeout directly instead of relying on a CancellationToken.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions