From 04429ca10ece5542dd3648033c62c9d2bc7d4d04 Mon Sep 17 00:00:00 2001 From: Christopher Dykes Date: Mon, 19 Jun 2017 17:23:19 -0700 Subject: [PATCH] Switch pid_t to be defined as int rather than void* Summary: Because an `int` plays much much nicer with code already written for Windows than `void*` does. It takes quite a bit of hackery to make it possible with the pthread implementation we support using, but it is possible and is worth the effort. Reviewed By: yfeldblum Differential Revision: D5276968 fbshipit-source-id: 4cd0d3120a4f19976e76853ef4b337e96d5005a8 --- folly/portability/PThread.h | 69 +++++++++++++++++++++++++++++++----- folly/portability/SysTypes.h | 7 ++-- 2 files changed, 64 insertions(+), 12 deletions(-) diff --git a/folly/portability/PThread.h b/folly/portability/PThread.h index 8b2f3051..38066908 100755 --- a/folly/portability/PThread.h +++ b/folly/portability/PThread.h @@ -18,13 +18,13 @@ #include -#if !FOLLY_HAVE_PTHREAD +#if !defined(_WIN32) -#ifndef _WIN32 -#error Building Folly without pthreads is only supported on Windows. -#endif +#include // nolint + +#elif !FOLLY_HAVE_PTHREAD -#include +#include // nolint #include namespace folly { @@ -43,14 +43,66 @@ int pthread_setspecific(pthread_key_t key, const void* value); /* using override */ using namespace folly::portability::pthread; #else +// The pthread implementation we support on Windows is a bit of a pain to work +// with in certain places. This entire mess here exists for exactly one reason: +// `using pid_t = int;` +// Without all of this mess, the pthread implementation will attempt to define +// `pid_t` as `void*` which is incompatible with just about every other +// definition of `pid_t` used by other libraries defining it on Windows, for +// example, python. + +// On Windows, define mode_t and pid_t +#include + +// HANDLE and DWORD for the declarations further down. +#include // nolint + +// Because of INCLUDE_NP, `errno.h` doesn't get included by pthread, causing it +// to define the errno values itself, which causes conflicts when `errno.h` ends +// up actually getting included, so we include it explicitly here to prevent it +// from defining the values itself. +#include + +// Pretend we are building with AT&T's UWIN project, which is a Unix API for +// Windows 95 & Windows NT. Yes, really. https://github.com/att/uwin +// This is the core define that keeps `pthread.h` from defining `pid_t`. +#define _UWIN 1 + +// Because we've defined `_UWIN`, the pthread implementation thinks that the +// pthread types have all also already been defined by default. By defining +// this, we force `PTW32_LEVEL` to be defined as `2`, which is enough to get it +// to define the pthread types for us. +#define INCLUDE_NP 1 + +// By defining `_UWIN` we cause the pthread implementation to aggressively +// define `HAVE_MODE_T`, which we define in `folly/portability/SysTypes.h` to +// keep it from defining an incompatible version of it. We undefine the macro +// here to keep from generating warnings when the implementation defines it. +// Note that the implementation leaks its definition of `HAVE_MODE_T`, so we +// don't need to re-define it after. +#undef HAVE_MODE_T + +#include // nolint + +#ifndef HAVE_MODE_T +#error We expected pthread.h to define HAVE_MODE_T but that did not happen. +#endif + +// Now clean up our mess so nothing else thinks we're doing crazy things. +#undef _UWIN +#undef INCLUDE_NP -#include +// Because we defined `INCLUDE_NP` above, the non-portable APIs don't actually +// get declared. We still need them, so declare them ourselves instead. +PTW32_DLLPORT HANDLE PTW32_CDECL +pthread_getw32threadhandle_np(pthread_t thread); +PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_np(pthread_t thread); + +// And now everything else that isn't just here for `pid_t`. -#ifdef _WIN32 // We implement a sane comparison operand for // pthread_t and an integer so that it may be // compared against 0. - inline bool operator==(pthread_t ptA, unsigned int b) { if (ptA.p == nullptr) { return b == 0; @@ -123,4 +175,3 @@ struct hash { }; } #endif -#endif diff --git a/folly/portability/SysTypes.h b/folly/portability/SysTypes.h index 0d081fe5..60168506 100755 --- a/folly/portability/SysTypes.h +++ b/folly/portability/SysTypes.h @@ -23,9 +23,10 @@ #define HAVE_MODE_T 1 -// This is actually defined in our pthread implementation on -// Windows, but we don't want to include all of that just for this. -using pid_t = void*; +// This is a massive pain to have be an `int` due to the pthread implementation +// we support, but it's far more compatible with the rest of the windows world +// as an `int` than it would be as a `void*` +using pid_t = int; // This isn't actually supposed to be defined here, but it's the most // appropriate place without defining a portability header for stdint.h // with just this single typedef. -- 2.34.1