-
Notifications
You must be signed in to change notification settings - Fork 202
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
feature: resumed read syscall after interrupted #15
Conversation
@@ -166,6 +166,15 @@ static void io_file_readall(lua_State *L, FILE *fp) | |||
char *buf = lj_buf_tmp(L, m); | |||
n += (MSize)fread(buf+n, 1, m-n, fp); | |||
if (n != m) { | |||
if (ferror(fp) != 0 && errno == EINTR) { | |||
do { | |||
n += (MSize)fread(buf+n, 1, m-n, fp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should check n == m
inside this do ... while
loop as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@agentzh
I think if ferror(fp) != 0
is ture
, n
should be smaller than m
. So there is no need to add another check. If I am wrong, please let me know.
if (n == m) { | ||
continue; | ||
} | ||
} | ||
setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alas, seems like readall does not detect or return any errors occurred in the fread()
calls. This is bad.
@@ -166,6 +166,15 @@ static void io_file_readall(lua_State *L, FILE *fp) | |||
char *buf = lj_buf_tmp(L, m); | |||
n += (MSize)fread(buf+n, 1, m-n, fp); | |||
if (n != m) { | |||
if (ferror(fp) != 0 && errno == EINTR) { | |||
do { | |||
n += (MSize)fread(buf+n, 1, m-n, fp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should call clearerr()
to clear the file error indicator before this line because "the error indicator can be reset only by the clearerr() function" according to the manpage of ferror()
. Otherwise we may have an infinite loop here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@agentzh
My stupid mistake. I will fix it later.
I too have been intrigued by this. I used this test case to consistently reproduce this behavior: -- io_intr.lua
local ffi = require "ffi"
ffi.cdef [[
int getpid(void);
]]
local pid = ffi.C.getpid()
assert(io.popen("kill -17 " .. pid .. " && sleep 0.1"):read("*a")) Called like so:
I confirm that the proposed patch in this current form produces an infinite loop. I would like to propose a more concise patch which I believe should work and is closer to the LuaJIT style: diff --git a/src/lib_io.c b/src/lib_io.c
index 9763ed4..662df42 100644
--- a/src/lib_io.c
+++ b/src/lib_io.c
@@ -164,8 +164,14 @@ static void io_file_readall(lua_State *L, FILE *fp)
MSize m, n;
for (m = LUAL_BUFFERSIZE, n = 0; ; m += m) {
char *buf = lj_buf_tmp(L, m);
- n += (MSize)fread(buf+n, 1, m-n, fp);
- if (n != m) {
+ for (;;) {
+ n += (MSize)fread(buf+n, 1, m-n, fp);
+ if (n == m) break;
+ else if (ferror(fp) != 0) {
+ if (errno != EINTR) return;
+ clearerr(fp); /* EINTR, retry */
+ continue;
+ }
setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
lj_gc_check(L);
return; The other benefit of this patch is that upon erroring (non |
@thibaultcha |
@spacewander I haven't changed the error-free code path from what it was. |
Ah, I see what you mean - when we reach the buffer size. |
Updated the patch with a simple |
In this patch, I was trying to avoid calling |
@thibaultcha |
(Slightly shortened the above proposed patch.) |
@thibaultcha Will you please create a new PR based on your new patch? It would be great if you can also create a PR for resty-cli to have this covered by its test suite :) @spacewander asked me privately to ask you to take this job over :) Many thanks! |
No description provided.