Skip to content
This repository has been archived by the owner on Jan 7, 2024. It is now read-only.

tcdrain is always blocking ... #5

Closed
Apollon77 opened this issue Mar 2, 2018 · 12 comments
Closed

tcdrain is always blocking ... #5

Apollon77 opened this issue Mar 2, 2018 · 12 comments

Comments

@Apollon77
Copy link

... can it be because of the fact that the CreateFile is done in "non overlapping" mode ?!

When I understood it correctly "non overlapping" means that the WriteFile call returns after everything is written. So when you call a drain after the Write you will wait for an Event that never comes (because already was there?)

Could this be possible?

I also tried to set mode to overlapping, but then I got no successfull connect (or I forgot something).

For now I removed the drain, but if my above "idea" is true then the tcdrain should always return directly, or ?! Or you need to move to overlapping mode.

What fo you think?

@veeso
Copy link
Owner

veeso commented Mar 8, 2018

Sorry if I haven't answered you for a few days, but I'm very busy these days.
Well, I'm not sure at 100% it works like that, but from the termiwin documentation:
"tcdrain() waits until all output written to the object referred to by fd has been transmitted."

So, isn't it supposed to be blocking?

@Apollon77
Copy link
Author

Yes, But you initialize the "CreateFile" in a way (as I understand it) that a Write-call only returns after write is complete ... you use it "non-overlapping" = "Synchron".
On Linux it seems to be "overlapping = asynchronous" by default (?) and so in Linus you do the write call and then wait using "drain" till it was written.

But on windows the Write returnsonly after the write ewas complete, so a drain wait forever because No other write can happen ...

@veeso
Copy link
Owner

veeso commented Mar 9, 2018

Ok, understood.
Have you tried to replace the last NULL argument with FILE_FLAG_OVERLAPPED ?
I can't try by myself at the moment.

@Apollon77
Copy link
Author

Yes, got an compile error then for some other code part, but not started to look deeper into it :-)
So it seems that you also need to consider other things when using overlapping mode.

If you want I can try to reproduce?!

@Apollon77
Copy link
Author

Hm ... tried it (it is the parameter after "OPEN_EXISTING") ... no compile error anymore ... hm ...
Will try later if it still works

@veeso
Copy link
Owner

veeso commented Mar 9, 2018

yeah sorry, was the 6th argument, not the 7th

@Apollon77
Copy link
Author

test bresults:

with

		com.hComm = CreateFile(com.port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

I get Error 87 on write to that serial socket.
According to https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx it is:

ERROR_INVALID_PARAMETER

    87 (0x57)

    The parameter is incorrect.

Also tried "FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED" as in one Windows example from https://msdn.microsoft.com/de-de/library/windows/desktop/bb540534(v=vs.85).aspx

More infos an overlapping I found on https://msdn.microsoft.com/en-us/library/windows/desktop/aa365683(v=vs.85).aspx ...

for now I remove tcdrain usage with ifndef _WIN32 ... :-(

@Apollon77
Copy link
Author

Ok, digged deeper :-)

When you do Overlapping communication then you also need to provide an OVERLAPPED struct to Read/Write operations and they become Really async. means: Directly after write you only get an info back but no info on bytes written. This you need to query with other commands and such.

But I had an other idea: When I use this:

int tcdrain(int fd) {
    if(fd != com.fd) return -1;
    return FlushFileBuffers(com.hComm);
}

it works as expected or ?!

See also: https://www.winehq.org/pipermail/wine-patches/2013-August/126115.html

what you think ?!

@Apollon77
Copy link
Author

PS: I already use it that way in my version and it works :-)

@veeso
Copy link
Owner

veeso commented Mar 12, 2018

Ok, so it's enough to add FILE_FLAG_OVERLAPPED to createFile and change tcdrain in the way you did, right?
Does FILE_FLAG_OVERLAPPED have any effect if I use it but I don't need an asynchronous communication (I mean, should it be used only if someone needs an asynchronous communication, or it can be used everytime?)

@Apollon77
Copy link
Author

NO!
FILE_FLAG_OVERLAPPED at all means higher effort. So leave all as is and only use FlushFileBuffers in the drain method.
Normally all data are alreyd written when Write returns, and if there are some left then FlushFileBuffers will block until they are written (as drain means) ... if everything is already written FlushFileBuffers simply does nothing. :-)

@veeso
Copy link
Owner

veeso commented Mar 12, 2018

Ok, thank you

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants