Implement Socket for win32#10784
Conversation
os_error value may be nil, hence the message can be nil, too
| output_buffer.to_unsafe.as(Void*), buffer_size.to_u32!, | ||
| address_size.to_u32!, address_size.to_u32!, pointerof(received_bytes), overlapped) |
There was a problem hiding this comment.
Don't see the point of these conversions, is there any reason to not create them as u32 from the start?
There was a problem hiding this comment.
The value is based on sizeof which returns Int32, so there must be a conversion at some point. I suppose it could be done earlier, though.
The main reason for this is that the proc call resembles a lib call. The lib call would handle all this type casting (and to_unsafe conversion), but we need to make it explicit here.
There was a problem hiding this comment.
Fair enough. comment was also about buffer_size though.
There was a problem hiding this comment.
buffer_size is also used in an arithmetic expresssion above, and signed integers is better for this. There needs to be a conversion somewhere, but I prefer to do it closely to the proc call.
|
I'm really confused about the CI error: (I've isolated the TCPSocket specs because that's consistently where it breaks) The specs run fine and successfully locally. What could be causing the process to exit? Without any kind of error message? It's seemingly between specs: the first line |
cfsamson
left a comment
There was a problem hiding this comment.
Great work! Left a few comments, but over all this looks good to me.
|
There is something very strange going on here. I'm pretty sure this is some kind of codegen error, or anything else outside the scope of this patch. The same code works locally, but fails in CI. The minimal difference between failing and succeeding that I could identify by now is this: --- c/src/socket/addrinfo.cr
+++ w/src/socket/addrinfo.cr
@@ -66,6 +66,8 @@ class Socket
if value.is_a?(Socket::ConnectError)
raise Socket::ConnectError.from_os_error("Error connecting to '#{domain}:#{service}'", value.os_error)
else
+ StaticArray(UInt8, 0).new(0_u8)
+
raise value
end
endThe only relevant changes to the LLVM IR are these: @@ -155358,8 +155407,7 @@ then98: ; preds = %else95
to label %invoke_out100 unwind label %rescue
else99: ; pqreds = %else95
- %234 = load i32*, i32** %value
- invoke void @.2A.raise.3C.Socket.3A..3A.Error.2B..3E..3A.NoReturn(i32* %234)
+ %234 = invoke [0 x i8] @.2A.StaticArray.28.UInt8.2C..20.0.29..40.StaticArray.28.T.2C..20.N.29..3A..3A.new.3C.UInt8.3E..3A.StaticArray.28.UInt8.2C..20.0.29.(i32 1435, i8 0)
to label %invoke_out103 unwind label %rescue
invoke_out100: ; preds = %then98
@@ -155378,21 +155426,26 @@ invoke_out102: ; preds = %invoke_out101
unreachable
invoke_out103: ; preds = %else99
+ %240 = load i32*, i32** %value
+ invoke void @.2A.raise.3C.Socket.3A..3A.Error.2B..3E..3A.NoReturn(i32* %240)
+ to label %invoke_out104 unwind label %rescue
+
+invoke_out104: ; preds = %invoke_out103
unreachableI used But, with that call missing, the process seems to immediately terminate around this location. I don't think it actually goes into this branch. If everything else is green, I'd probably leave that weird workaround for this PR and open a new issue to investigate the error. |
beta-ziliani
left a comment
There was a problem hiding this comment.
I left some superficial questions for now.
beta-ziliani
left a comment
There was a problem hiding this comment.
Besides of the puzzling-looking (to me at least) FIXME, I'd say this is good to go
This patch implements
Crystal::System::Socketfor Windows using the winsock2 API, as proposed in #10696.Most IO methods are implemented as overlapped operations based on IO completion ports. Since the event loop implementation is still missing, the fiber swapping mechanism is currently stubbed as a wait for the current operation to complete. In a follow up, this can be replaced by a proper event loop implementation without requiring any changes to the socket implementation. I already have a dev branch with the event loop.
A new
IO::Overlappedmodule is introduced as the counterpart ofIO::Eventedfor overlapped operations. This setup is subject to refactorings as currently discussed in #10766, but this should be fine for the initial implementation.There are still a couple of minor issues documented in the specs (either as
pending_win32or excluded viaflag?(:win32). I'll keep on working on that, but it's not critical for the basic implementation.Thanks to @andraantariksa, @cfsamson, @kubo, @neatorobito, @yxhuvud et al. for your preliminary work, exploration, ideas and hopefully reviews on this one.
The first two commits are from #10782. I'll rebase the branch once that's merged.
Closes #9544
Closes #10696