This is an archive of the discontinued LLVM Phabricator instance.

[Support] Add functions that return native file handles on Windows instead of fds.
ClosedPublic

Authored by zturner on Jun 3 2018, 10:08 AM.

Details

Summary

Windows' CRT has a limit of 512 open file descriptors, and fds which are generated by converting a HANDLE via _get_osfhandle count towards this limit as well.

Regardless, often you find yourself marshalling back and forth between native HANDLE objects and fds anyway. If we know from the getgo that we're going to need to work directly with the handle, we can cut out the marshalling layer while also not contributing to filling up the CRT's very limited handle table.

On Unix these functions just delegate directly to the existing set of functions since an fd *is* the native file type. It would be nice, very long term, if we could convert most uses of fds to native_file_t.

Diff Detail

Repository
rL LLVM

Event Timeline

zturner created this revision.Jun 3 2018, 10:08 AM

I like the direction. Just a question about the implicit type conversion.

llvm/include/llvm/Support/FileSystem.h
848 ↗(On Diff #149649)

s/the freeing//

881 ↗(On Diff #149649)

s/the freeing//

llvm/lib/Support/Windows/Path.inc
1070 ↗(On Diff #149649)

Does this work? Function returns Expected<native_file_t> which is Expected<void *>. Can you assign that to Expected<HANDLE> and get the implicit (reinterpret) cast from void * to HANDLE?

zturner added inline comments.Jun 4 2018, 9:06 AM
llvm/lib/Support/Windows/Path.inc
1070 ↗(On Diff #149649)

HANDLE and void* are literally the same type, so yes it should work. From winnt.h:

#ifdef STRICT
typedef void *HANDLE;
#else
typedef PVOID HANDLE;
#endif
amccarth accepted this revision.Jun 4 2018, 9:37 AM
amccarth added inline comments.
llvm/lib/Support/Windows/Path.inc
1070 ↗(On Diff #149649)

Oh, duh! I should have realized that.

This revision is now accepted and ready to land.Jun 4 2018, 9:37 AM
rnk added a comment.Jun 4 2018, 10:40 AM

We discussed this in person, and I think the best way forward is to use this new typedef everywhere in all code. As a migration path, I think it would be best to rename the existing integer FD APIs to openFileDescriptorForRead/Write. Then we can add back openFileForRead and have it return the new handle / FD wrapper typedef. The new typedef be called file_t so we don't have to use the word "native" everywhere and we can just talk about "files".

zturner updated this revision to Diff 149815.Jun 4 2018, 11:37 AM

Changes from first revision:

  1. Renamed native_file_t -> file_t
  2. Added a global constant kInvalidFile that is -1 on Unix and INVALID_FILE_HANDLE on Windows.
  3. Added a closeFile(file_t &) method that calls ::close or ::CloseHandle, and then sets the parameter to kInvalidFile so it can't be re-used.

The in/out parameter of #3 might be objectionable, so if anyone has a strong opinion I can just pass by value and not modify the argument on output.

This revision was automatically updated to reflect the committed changes.