-
Notifications
You must be signed in to change notification settings - Fork 109
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
Added socket support #65
Conversation
Should merge #64 first. |
/// File Events bitmask | ||
@frozen | ||
// @available(macOS 10.16, iOS 14.0, watchOS 7.0, tvOS 14.0, *) | ||
public struct FileEvents: OptionSet, Hashable, Codable { |
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 this name is a little misleading: we should probably call it PollEvents
or something similar.
private init(_ raw: CInt) { self.init(rawValue: numericCast(raw)) } | ||
} | ||
|
||
public extension FileEvents { |
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.
Let's try to be consistent about where we put extension access modifiers.
@colemancda did you see #30 ? That went through a few rounds of full API design. It ultimately ended up not landing for non-API-design-related reasons. I realize you cover a not-totally-overlapping set of functionality, but its good to refer to for API design. The main reason it didn't land is we need to figure out the linkage situation for Windows (perhaps no initial socket support) as well as figure out the official Darwin story - sockets are supposedly "deprecated" in favor of Network.framework, but their Swift API is not marked deprecated and Network.framework has adoption issues (e.g. depends on ObjC, IIRC). I refactored that PR to be into a separate module "SystemSockets" hoping to help the situation, but it might not be enough. It's unfortunate that Swift's module story is still so monolithic. Ideally, we'd have something more like the following:
E.g. get access to Things in here could even be argued to be considered part of the stdlib.
We don't want separate compilation, much less dynamic linking here. We shouldn't need ABI annotations if there is no ABI. We shouldn't be trying to infer ABI annotations during optimization time if there is no ABI.
This gives you the natively available sys calls without use of extra libraries.
This can include things that need extra linkage, like pthreads on Linux and sockets on Windows. Darwin has
If Darwin is formally deprecating sockets, then we could consider taking those API on that platform out of the "System" namespace and into legacy module on Darwin. Personally, I don't think the distinction between this option and #3 above is that significant, but it's an option too if #3 falls through for some reason. |
@milseman So... would that be another library? Another module in the same package or another package all together? I can't imagine BSD sockets never being a part of Darwin, its more Unix than Linux is. I understand that for Networking it makes sense to possibly not use this, but BSD Sockets are essential or hardware usage on all platforms. I use |
I strongly believe that this package is the correct place for all File Descriptor related APIs, which would include I would suggest the following names for a separate package or module for networking code:
|
@milseman I removed everything related to IP addresses, so this code now really has nothing to do with networking anymore. Local (Unix) sockets (for IPC), terminal |
Sorry, I didn't clarify. Another library doesn't exist, so for now it makes the most sense for it to live in the System package. I'm mostly talking about separate modules inside the package, if feasible (within Swift's monolithic modules and monolithic packages story). The basic point behind a types module is that, long-term, people should be able to access these types without also pulling in syscalls. Syscalls will always have platform differences, but we want to enable a library to provide a cross-platform layer using We have, or will have, the ability to sink types to lower-level layers, so I'm not overly concerned. But this might help provide framing for the library types discussion.
Unfortuantely I have zero say and nearly zero power over this. I agree with you, FWIW.
Yup, also needed additions to System.
Yup, we should find some way to land it that doesn't violate the platform's sensibilities. Have you thought about the linkage story here at all?
This is where I think we might start to diverge. In the bigger-picture API design, generics and protocols define more abstract semantics to be refined and extended elsewhere. Small-picture they're also used for workarounds, reducing API bloat, etc. I think that System should be hesitant to stake out new ground in the former. System intefaces becomes messy and non-orthogonal very quickly, even within a single platform. System can't in general make broad or sweeping semantic guarantees beyond what's afforded by fairly direct surfacing of system interfaces. What are you hoping for libraries to extend for
Yes, and platform-native interfaces like kqueue, epoll, and io_uring (if we can figure out versioning).
I don't know if "networking" is the right line of demarcation here, but if it is that works for me.
Great, I think this is good justification for it being in System (the package). Just figuring out how to make it happen.
Do hold on to that code though, we'll want to figure out a place for it. |
So,
Thats great, but thats not how the library is currently structured for
IDK if extend is the right word, really just provide concrete implementations.
Please view Netlink/FileDescriptor.swift for an example of how the SocketAddress protocol provides a clean APIs while the implementation provides the underlying C buffer.
The way the library is currently structured, we import the C platform library for each platform (Darwin, Glibc, ucrt) and CSystem headers. It was my understanding this would always be a sort of Swift overlay for Darwin and Glibc. Right now I have a cross platform library called On Linux however, using GATT requires importing Bluetooth, BluetoothHCI, BluetoothGATT, BluetoothGAP, and BluetoothLinux, which itself depends now on this System module, and more importantly requires
I did after I started working on this (like 60% done). The problem with that code is that |
Please provide me some guidance on how you would like these APIs implemented so they can be merged, there is a very real use case for all this and I don't want a monolithic library either is a burden on code size for projects, but neither do I want a bunch of code duplication as is currently the case. I would be very interested in Syscalls being a separate module, but not sure how that is possible at the moment. Also I think requiring a POSIX environment is reasonable, I dont think it makes since to consider WASM as a deployment target for this project. |
(Popping in very quickly; I'll read through history and offer some more considered opinions soon.) My baseline expectation is that the APIs in #30 will be the starting point for any socket additions that land in this package. We've spent significant effort on designing those APIs to fit the goals of this module. I don't think we would want to start from scratch without an extremely good reason. As Michael said, exposing socket APIs on Darwin is unlikely to be in the cards, as they are no longer recommended for use there. (The platform position is that sockets are obsolete technology, and newly written code must not use them.) The use cases you listed on Linux are convincing, however; it would likely make sense that this package provided some socket wrappers on that platform. (It's not currently a given that System would ship IPv4/v6 support even on Linux -- our official networking library is Swift NIO, and the party position is that people shouldn't use raw networking APIs.) (Background note: (just to make sure we are on the same page -- not necessarily related to any part of this PR) System is intended to provide high-performance, low-level system call interfaces that eliminate the safety issues that arise from directly calling the underlying C APIs, while remaining extremely faithful to them. There is no expectation that System will provide the same APIs across any two platforms, although we do try to keep common things consistent when it makes sense to do so. This also applies to POSIX interfaces -- e.g. we may very well end up adding sockets on Linux and BSDs, but not on Darwin. Of particular note is that it's not System's job to invent abstractions to improve the usability of these syscalls, or to make them more portable. System's job is (1) to eliminate memory safety problems, (2) to apply the Swift naming conventions, and (3) to faithfully expose the preexisting constructs, warts and all. It is essential that System introduces no non-zero cost abstractions beyond what's absolutely necessary to achieve goal 1: there must be no good technical reason for anyone to prefer using the raw imports rather than System's APIs. Swift System also ships as an ABI stable SDK component on Darwin. As platform owners, Apple has full control over which syscalls in Darwin gain official wrappers in Swift System, and what these wrappers look like. As such, System's Darwin APIs are subject to Apple's internal API review processes, and we in Apple's Swift stdlib team are mediating between open source work and the experts at the company.)
|
Added wrapper for POSIX socket APIs that takes advantage of Swift's generics and protocol extensions.