-
Notifications
You must be signed in to change notification settings - Fork 849
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
windows (mingw-w64) support for libh2o #380
Conversation
#2 This could be considered as an updated version :) |
👍 |
Wow!! 👍 |
Okay so I have done some more work on this. I will try to add mmap functions and readdir_r emulation to mingw-w64. I think supporting MSVC would be a big overhaul that destroys the neatness of the project which is why I went for mingw-w64 as that it much closer to h2o because it supports posix in most places and we can keep the changes to a minimal and mostly about header includes. |
@kazuho: this should be good to merge. Please review :) |
relative readdir_r patch thread for mingw-w64 |
if (cloexec_pipe(fds) != 0) { | ||
perror("pipe"); | ||
abort(); | ||
} | ||
fcntl(fds[1], F_SETFL, O_NONBLOCK); | ||
#else | ||
u_long nonblock = 1; |
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.
Call to cloexec_pipe
(or an equivalent function) is missing.
I presume that this is the reason why you are seeing timeout errors.
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.
If you look a few lines above this is only relevant for the evloop implementation
#if H2O_USE_LIBUV
#else
With reguard to the evloop implementation I do need some advice here :)
In cloexec to setup fds[0] and fds[1] on windows we have to create the socket before hand
This means we need to know if it is tcp or udp a stream etc beforehand which I don't think we know at this point ?
This is done in the set_cloexec function
I think I should focus on supporting doing 1 of the 2 first and not both at the same time.
libuv seemed like the easiest one as it already supports windows and mingw-w64.
Your thoughts ?
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.
In cloexec to setup fds[0] and fds[1] on windows we have to create the socket before hand
This means we need to know if it is tcp or udp a stream etc beforehand which I don't think we know at this point ?
This is done in the set_cloexec function
In the unix-side, fds[0] and fds[1] are initialized by calling cloexec_pipe
(which in turn calls pipe(2)
). So on the Windows-side, the descriptors should be initialized as well, before setting them to non-blocking mode.
The file descriptors being created are used for signalling between the threads, and the threads listen to the sockets using the event loop. So I think on Windows you would need to create a pair of TCP sockets connected to each other under my understanding that the HANDLEs created by CreatePipe
cannot be passed to select
.
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.
libuv seemed like the easiest one as it already supports windows and mingw-w64.
Your thoughts ?
The H2O standalone server only supports the embedded event loop (evloop). Libuv binding exists for users of libh2o (since it is a popular event loop that is used, with rich documentation and other protocol bindings that application developers can use).
I agree that porting the libuv-side would be faster, but if your intention is to make the H2O standalone server runnable on Windows, you would need to port evloop (and it seems like that you have already done that to some extent!).
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.
So I think on Windows you would need to create a pair of TCP sockets connected to each other under my understanding that the HANDLEs created by CreatePipe cannot be passed to select.
Yes I did this yesterday evening using the socket function and making it a stream socket with ipv4 support and tcp but it didn't change much in that the in ev-loop mode example-httpclient hangs (still stuck in the loop)
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 agree that porting the libuv-side would be faster, but if your intention is to make the H2O standalone server runnable on Windows, you would need to port evloop (and it seems like that you have already done that to some extent!).
Yes I started working on that because I couldn't get the examples that use libuv working :(
I would like to get libh2o working first if possible because I want to create a few mockups with it.
I still intend to get the full h2o package working on windows but I would like to focus on the lib aspect first.
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.
Yes I did this yesterday evening using the socket function and making it a stream socket with ipv4 support and tcp but it didn't change much in that the in ev-loop mode example-httpclient hangs (still stuck in the loop)
To which part of the callbacks does the client proceed? exmaples/libh2o/http1client.c defines a number of callbacks that are called one by one. on_connect
is called first, then on_head
, and on_body
. You could also set breakpoints to (or emit logs in) the callback functions within socketpool.c or http1client.c to determine which callbacks are called, and which are not.
That would help you analyze the cause of the issue.
Should I focus on the evloop version first or the libuv ?
That depends on what you want to do.
If your intention is to use libh2o, then you should better concentrate on libh2o and the examples under examples/libh2o. OTOH if your intention is porting the standalone server to Windows, I would suggest concentrating on evloop and then working on the libuv-side.
Personally I did not expect somebody to start porting the standalone server to Windows, and am fascinated by how far you have achieved so far.
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.
To which part of the callbacks does the client proceed? exmaples/libh2o/http1client.c defines a number of callbacks that are called one by one. on_connect is called first, then on_head, and on_body. You could also set breakpoints to (or emit logs in) the callback functions within socketpool.c or http1client.c to determine which callbacks are called, and which are not.
When using libuv on_connect is called and it doesn't complain and that comes from a call stack of
1 on_connect
2 call_connect_cb
3 uv_process_tcp_connect_req
4 uv_process_reqs
5 uv_run
then after that it hits on_head and exits on line 108 after fprintf "I/O timeout"
the stack for this is
1 on_head
2 on_error_before_head
3 h2o_timeout_run
4 on_timeout
After debugging in fiddler2 the http req debugger I can see that the http request is infact never made to argv[1] in my case hxxp://google.com (xx = tt)
now the only strange piece of code left is this
/uv-binding.c.h:147:25: warning: passing argument 1 of 'dup' makes integer from pointer without a cast
if ((info->fd = dup(fd)) == -1)
I tried using _get_osfhanle but it doesn't change anything :/
I'm not quite sure whats going on here exactly.
The handle is being duplicated for some reason to hold on to after close ?
If your intention is to use libh2o, then you should better concentrate on libh2o and the examples under examples/libh2o. OTOH if your intention is porting the standalone server to Windows, I would suggest concentrating on evloop and then working on the libuv-side.
I would like to get the lib working first, but I do intend to get the server working after that :)
Personally I did not expect somebody to start porting the standalone server to Windows, and am fascinated by how far you have achieved so far.
Someone was bound to try it sooner or later :D
In addition to the in-line comments, I see following high-level issues.
|
After some though I would like to narrow the scope of the PR to libh2o and libh2o-evloop. All commits will be tidied squashed force re pushed once we get the lib working
I use msys2 for this as I am one of the maintainers http://msys2.github.io/ |
Attached is a log of t-00unit-libuv.t.exe https://gist.github.com/martell/30fc1fc5570f24c49673 looking at the tests for file.c ok 31 - E:/msys64/home/Martell/h2o/t/00unit/lib/handler/file.c 703
not ok 33 - E:/msys64/home/Martell/h2o/t/00unit/lib/handler/file.c 712
200 ok requests succeed while 301 redirects fail conn->req.res.status is actually returned as 403 instead :( when it hits line 112 in request.c
this essintially becomes if(10 == 0) which is of no use to us on windows. |
The test case is asserting that the server redirects the client to a path with So it might be the case that
No, that not the path that is taken by the test case. It is one of the calls to
I understand how you feel. I do not have an Windows machine, and have the same issue when I look into your code. |
FYI, in #385 the select backend has been replaced by a |
After doing some research into WSAPoll I came across these curl/curl@8bad5f2a6169e2e This probably is an issue on cygwin also if it uses WSAPoll to emulate the poll function |
@martell Thank you for the information. If I read correctly the difference of the behavior is limited to when connecting to a non-responding server. If that is right then the impact of the problem to H2O will be fairly limited, since it mostly runs as a server (and if it connects to an upstream server when acting as a proxy, it connects to a predefined server that can be expected to be running and up). That said, I would not mind if you keep the select-based implementation for Windows considering the fact that the platform is capable of modifying |
Just following up on this old PR to update the status. I've been working with a new linux emulation layer called midipix which is like cygwin but it aparently performs even better then mingw-w64 for networked projects like this. It also uses musl libc so it already works. I'll post an update when that project gets closer to release. |
Sounds interesting! Looking forward to hearing the updates. |
Hey guys,
I'm not putting this up for merging.
Everything compiles with mingw-w64 but it still doesn't quite run.
I'm leaving this here for everyone to use, debug, test :)