fds are equivalent to Windows HANDLEs, and WaitForMultipleObjects() is equivalent to poll().
But, Linux also has epoll() which scales better for non-trivial numbers of things, and Windows has IOCP. So WaitForMultipleObjects isn't particularly special.
Both Windows and Linux have things that don't work with these interfaces. Nonetheless, Linux has been trending towards "waiting on all sorts of things" by makng more and more things into fds that can be waited on with pol;/epoll. Examples: timerfd, signalfd, eventfd. It's quite a unixy approach.
In fact, Wine already uses eventfd to implement WaitForMultipleObjects. This kernel change is just an optimisation, to speed up Wine, and a workaround for some distros setting Wine's max fd limit too low for Windows apps.
Futexes used to support waiting on multiple futexes, using FUTEX_FD. That was arguably better than the new patch FUTEX_WAIT_MULTIPLE, because in old Linux you could wait for futexes and other fds at the same time - it did work with "all sorts of things".
But FUTEX_FD was removed after searches online found no code using it, and kernel devs didn't like keeping it. (To my mind, this was a suprising, unusual breakage of system call binary compatibility) The new FUTEX_WAIT_MULTIPLE allows programs like Wine to wait for multiple futexes faster than before, but it's more limited than the old FUTEX_FD because you can't mix them with other things.
The VMS and NT philosophies of everything being an object are a bit more general and easier to follow in practice.
Futex is a special case because futexes themselves are quite special. There is no userspace equivalent to them in Windows anyway as has been mentioned. Windows Events are similar to what is provided by eventfd, but not as featureful.
It's also not something that works on all Unices (e.g. afaik macos has no timerfd). But in all fairness, that problem only exists because OS speciation, as it's biological counterpart, is not as clear cut a concept as one would desire.
In fact windows actually reserves a block of user address space that will never be allocated to disambiguate memory vs non memory handles.
Its really a pitty these two great systems refuse to learn from each other.
I'm calling your bluff too. Which one of the supported waitable handles in Windows are just addresses with no other state? I'm more surprised because they all need an access mask at a minimum, and I thought they all involve an ObCreateObject, even a Mutant... these dusty corners of the kernel are visible through the DDK. Anyway, I would be glad to be shown wrong.
It would be possible to provide an orthogonal handle based API even if windows doesn’t always live up to that ideal.
Ultimately it seems these systems are just too big to maintain a cohesive design - but it is still an ideal to aspire to.
EDIT: And since you dirty edited, can you point to an example of HMODULE or any other dataless HANDLE being used on the syscall interface?
You will find that windows never makes guarantees of what handles actually are - in case it wants to change them.
In windows NT most GDI handles are user mode and not kernel objects. Other objects may or may not be kernel based depending on the version and whims of the implementor.
And can you WFMO on user space only HANDLEs?
Can you use HMODULEs orthogonally to common APIs that use Handles? That's what really matters. Just because something is 4 or 8 bytes wide and you call it the same thing isn't interesting. Like can you pass HMODULE to WaitForSingleObject? Oh Ok, I guess that's mean because to be fair, what does "waiting" on a DLL mean.
Ok, well surely you can pass that HMODULE to CloseHandle, at least closing should be orthogonal.. Why don't you try that? I'll wait.
So what point are you trying to make here? It sound like you're just jerking everyone around, tbh.
Edit: Moreover, it's a bit ridiculous to say that an HMODULE is just an address with no kernel state. It uniquely identifies the loaded DLL, so it a key to a tremendous amount of kernel bookkeeping about the loaded module.
"File descriptor" is just a weird spelling of "handle", for historical reasons.
FDs are pretty much HANDLEs of the nix world.
We are going to soon: "The 5.3 kernel also adds the ability to pass a pidfd to poll(), which will provide a notification when the process represented by that pidfd exits." (https://lwn.net/SubscriberLink/794707/905eb6b5b7287e77/)
[1] https://stackoverflow.com/questions/8057892/epoll-on-regular...
* limited to 64 handles.
* passes the entire handle buffer to the kernel on every call. That is also a key reason poll is worse than epoll/kqueue. A better way is to let the kernel retain the list of handles across calls.
* when two handles are signalled, the one earlier in the array is always the one returned. So handle with a lower array index being frequently signalled can starve out your opportunity to process the later ones.
* since everything happens by returning an index, when multiple handles are signalled, you can only process one at a time, needing a new syscall for each.
This legit isnt really like anything in Windows, the closest thing I can think of is you'd be able to do something like this with XOK wake predicates.
Its also telling Linux has gone through the whole select/poll/epoll madness while WaitForMultipleObjects has worked well in windows NT since the 90s. Its a proven design.
And this better too, you don't need to register futexes with the kernel, the futex wait call is just "I want to sleep until the data at this memory address changes", and now you can say "I want to sleep until _these addresses_ change". NT doesn't give you any equivalent, you need to build in kernel objects to do the same thing.
And if you want to wait for both, you just wrap it into an eventfd and epoll on that.
(P.S. there is a really ugly way to get around this on Windows if for some bizarre reason you really need to, which is to have 1 thread per 64 handles, then wait on the thread handle instead. I've never found a need do even get close to doing such a thing though.)
Which brings me back to my main point against the GPs
> They should just bite the bullet and implement WaitForMultipleObjects instead of having all these disjoint APIs
Is this your way of saying "I can't think of any legitimate response, but I insist the Windows API must suck because that's just how I feel about it"?
I literally told you there is a proper solution that turns out to be different than what you're expecting coming from Linux, and instead of either realizing it's a good solution or telling me why it isn't, you just trashed the OS and told me it sucks.
And staying on the topic of mutexes, that "just spawn another thread for every 64 items you want to wait on" (which I already knew about) is about the hackiest shit ever.
(And FWIW, I started off as a Win32 developer, have code in ReactOS, and have written NT and WinCE drivers. You're not talking to some Linux fanboy)
Is this surprising to you? I already told you it would be a hack because I told you there is a better and proper solution for the actual problem you were encountering. You're stubbornly insisting for no reason on actively doing something bizarre, and you're frustrated you need an obtuse hack to make it happen?
If you're trying so hard to "stay on the topic of mutexes" why do you trash WFMO for the "silly 64 item cap" and then repeatedly refuse to provide a single situation in which waiting on 64 mutexes would actually come up as a legitimate problem? Somehow you find the inability to use a wrong method to solve a problem whose existence you can't even show evidence of to be "silly"?
I admire what Linux accomplishes functionally. But it is just as ugly as win32 in my opinion. The two are really more alike in their pragmatism than they would care to admit - but mutual hatred prevents learning from each others mistakes.
What are you talking about by "wait for both"?
But jesus, the windows API in this area is hot garbage. A hard 64 limit and O(N)? It's a terrible design.