Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bugfix: resume read system call upon EINTR during file readall. #16

Closed
wants to merge 1 commit into from

Conversation

thibaultcha
Copy link
Member

Patch proposed in #15, ported to its own PR. Test case located at openresty/resty-cli#37.

@thibaultcha thibaultcha changed the title bugfix: resume read system call upon EINTR during file readall. feature: resume read system call upon EINTR during file readall. Dec 21, 2017
@agentzh
Copy link
Member

agentzh commented Dec 21, 2017

@thibaultcha Awesome. Thanks! Will you also have a shot on proposing the same PR to the mainstream LuaJIT repo below at the same time?

https://github.com/LuaJIT/LuaJIT/pulls

It would be great if this can be accepted upstream :)

src/lib_io.c Outdated
n += (MSize)fread(buf+n, 1, m-n, fp);
if (n == m) break;
else if (ferror(fp) != 0) {
if (errno != EINTR) return;
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we should use break instead of return here.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, break is not right either. Better return the partially read data here before returning?

Copy link
Member Author

Choose a reason for hiding this comment

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

Do we need to? It seems to me like the only code path we are following after this is luaL_fileresult which returns nil, errno, string to the Lua-land? We also avoid repeating the GC step).

Copy link
Member Author

Choose a reason for hiding this comment

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

On second thought, maybe we do need the GC step anyway for the buffer allocated above. I originally wasn't sure it was needed, but I do think so now.

@thibaultcha
Copy link
Member Author

I agree, yes I will! Making sure it is square first :)

@agentzh
Copy link
Member

agentzh commented Dec 22, 2017

@thibaultcha I should be a bugfix, I believe.

@thibaultcha
Copy link
Member Author

Ha, I’ll re-rename it back then.

@thibaultcha
Copy link
Member Author

Renamed the commit and updated the (ferror(fp) != 0) check to be more consistent with such checks elsewhere in the codebase.

@thibaultcha thibaultcha changed the title feature: resume read system call upon EINTR during file readall. bugfix: resume read system call upon EINTR during file readall. Dec 22, 2017
@thibaultcha
Copy link
Member Author

I just updated the patch to run a GC step upon error. I believe it is close to completion now (and the test case has been improved as per your request a few days ago). Mind taking a look? If it looks ok, I will submit it against the upstream repository as discussed.

src/lib_io.c Outdated
for (;;) {
n += (MSize)fread(buf+n, 1, m-n, fp);
if (n == m) break;
else if (ferror(fp)) {
Copy link
Member

Choose a reason for hiding this comment

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

We can save the else word here since the previous branch never falls through.

Copy link
Member Author

Choose a reason for hiding this comment

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

This branch is to prevent adding the read data to the stack upon an error, because I believe the previous behavior was an oversight due to the previous design of this function, which had no error handling at all.

Copy link
Member

Choose a reason for hiding this comment

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

@thibaultcha OK, I see we now have proper error handling for general file I/O errors. Huh, more than I expected :)

Copy link
Member

Choose a reason for hiding this comment

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

@thibaultcha The else here does not make any difference, no? the previous branch never falls through (it always breaks).

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry, on mobile (still) I just realized this is the above branch you are talking about. I’ll gladly remove the else here :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed!

src/lib_io.c Outdated
n += (MSize)fread(buf+n, 1, m-n, fp);
if (n == m) break;
else if (ferror(fp)) {
if (errno == EINTR) { clearerr(fp); continue; }
Copy link
Member

Choose a reason for hiding this comment

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

I think the previous behavior is to read until the end of the stream or until an error occurred. here we throw away all the already read data when an error happens. This looks wrong to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don’t see any path when an error occurs where this value would be used. From my understanding, the previous behavior simply did not consider errors, and thus did not need to deal with such cases.

Choose a reason for hiding this comment

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

io_file_readall() is a helper function of io_file_read() which check if error take place.

Interruption should not be considered as a real error, also it's difficult to resume read/write in io_file_read(), so I guess this piece of code needs some change.

That being said, I don't think this fix is enough. For one thing, other helper function (say io_file_readnum()) have similar problem, and this patch does not cover them. On the other hand, this is the problem specific the OR environment. Maybe you can explain the problem to Luajit mailing list and solicit comment from broader audiences?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, this fix is only contained to readall. I know there are other areas that require similar attention.

@agentzh
Copy link
Member

agentzh commented Jan 2, 2018

@thibaultcha Merged. Thanks!

@agentzh agentzh closed this Jan 2, 2018
@thibaultcha
Copy link
Member Author

Awesome! Back tomorrow, I will try to push this into upstream as well as maybe fixing a few other places. Thanks!

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

Successfully merging this pull request may close these issues.

None yet

3 participants