Close sockets properly in the portability headers
authorChristopher Dykes <cdykes@fb.com>
Wed, 23 Nov 2016 19:07:11 +0000 (11:07 -0800)
committerFacebook Github Bot <facebook-github-bot-bot@fb.com>
Wed, 23 Nov 2016 19:08:32 +0000 (11:08 -0800)
commit215636b205466f9823662d08d0db588b4e671775
tree28f92e64d1355e2e37251ba6255d7ab5591eb474
parente6d69248da39a1618352a2040f6d26f95ff86196
Close sockets properly in the portability headers

Summary:
Even when linked against the dynamic runtime.
In truth, the old way was far cleaner, but we do need to be able to close the file descriptors as there is a hard global limit set by the CRT when it's compiled of 8k file descriptors.
This closes it by applying a flag that prevents calls to `CloseHandle` from actually closing the handle, then we call `_close` to get the file descriptor itself closed, then we can call `_closesocket` to close the socket and handle.
This is complicated by the fact that attempting to close a handle that you've marked as being prevented from being closed will trigger an SEH exception, but only if you have a debugger attached. That means that, for anything closing sockets to be debuggable, we have to handle that exception (as a no-op) and then get to have fun trying to get `STATUS_HANDLE_NOT_CLOSABLE`, which for some absurd reason, is only defined as part of the driver developer kit's headers. Some fun ensued where VS was nice enough to point out that the bcrypt headers also defines `NTSTATUS`, and doesn't require building as a driver to use it. For that reason we borrow its definition of `NTSTATUS` rather than declaring it ourselves.
We also have to prevent the main windows headers from defining the base SEH exceptions, because those will be redefined by `ntstatus.h` otherwise :(

Reviewed By: yfeldblum

Differential Revision: D4222625

fbshipit-source-id: 6ed7e91b7a735b5506eb189e452983cd8cace34b
folly/portability/Unistd.cpp