--- origsrc/Python-3.6.1/Python/thread_pthread.h	2017-03-25 08:10:30.784601800 +0900
+++ src/Python-3.6.1/Python/thread_pthread.h	2017-03-25 08:44:21.946596600 +0900
@@ -603,6 +603,80 @@
 
 #define Py_HAVE_NATIVE_TLS
 
+#ifdef __CYGWIN__
+/* Cygwin pthread TLS key type is a pointer, whereas Python 3 assumes
+ * int type. So wrapper functions are used instead.
+ */
+static pthread_key_t key_tbl[PTHREAD_KEYS_MAX];
+
+static int
+py_pthread_key_create(unsigned long *key, void(*func)(void *))
+{
+    int ret;
+    int i;
+    pthread_key_t key_cyg;
+    ret = pthread_key_create(&key_cyg, func);
+    if (ret) {
+        /* Error */
+        *key = 0;
+        return ret;
+    }
+    for (i=0; i<PTHREAD_KEYS_MAX; i++) {
+        if (key_tbl[i] == NULL) {
+            /* Succeeded */
+            *key = i;
+            key_tbl[i] = key_cyg;
+            return 0;
+        }
+    }
+    pthread_key_delete(key_cyg);
+    /* PTHREAD_KEYS_MAX reached */
+    *key = 0;
+    errno = EAGAIN;
+    return EAGAIN;
+}
+
+static int
+py_pthread_key_delete(unsigned long key)
+{
+    int ret;
+    if (key >= PTHREAD_KEYS_MAX || key_tbl[key] == NULL) {
+        errno = EINVAL;
+        return EINVAL;
+    }
+    ret = pthread_key_delete(key_tbl[key]);
+    key_tbl[key] = NULL;
+    return ret;
+}
+
+static int
+py_pthread_setspecific(unsigned long key, const void *p)
+{
+    if (key >= PTHREAD_KEYS_MAX || key_tbl[key] == NULL) {
+        errno = EINVAL;
+        return EINVAL;
+    }
+    return pthread_setspecific(key_tbl[key], p);
+}
+
+static void *
+py_pthread_getspecific(unsigned long key)
+{
+    if (key >= PTHREAD_KEYS_MAX || key_tbl[key] == NULL) {
+        errno = EINVAL;
+        return NULL;
+    }
+    return pthread_getspecific(key_tbl[key]);
+}
+
+#define pthread_key_t unsigned long
+#define pthread_key_create py_pthread_key_create
+#define pthread_key_delete py_pthread_key_delete
+#define pthread_setspecific py_pthread_setspecific
+#define pthread_getspecific py_pthread_getspecific
+
+#endif /* __CYGWIN__ */
+
 long
 PyThread_create_key(void)
 {
@@ -610,15 +684,12 @@
     int fail = pthread_key_create(&key, NULL);
     if (fail)
         return -1L;
-#ifndef __CYGWIN__
-    /* Cygwin pthread types are pointers, which may "overflow" signed long */
     if (key > LONG_MAX) {
         /* Issue #22206: handle integer overflow */
         pthread_key_delete(key);
         errno = ENOMEM;
         return -1L;
     }
-#endif
     return (long)key;
 }
 
