more complete pseudo-fork() support for Windows
[p5sagit/p5-mst-13.2.git] / win32 / win32.h
index 0f6f708..856232a 100644 (file)
@@ -248,6 +248,13 @@ typedef long               gid_t;
 #define flushall       _flushall
 #define fcloseall      _fcloseall
 
+#undef __attribute__
+#define __attribute__(x)
+
+#ifndef CP_UTF8
+#  define CP_UTF8      65001
+#endif
+
 #ifdef PERL_OBJECT
 #  define MEMBER_TO_FPTR(name) &(name)
 #endif
@@ -341,26 +348,53 @@ EXT void win32_strip_return(struct sv *sv);
 #define win32_strip_return(sv) NOOP
 #endif
 
+/* 
+ * Now Win32 specific per-thread data stuff 
+ */
+
+struct thread_intern {
+    /* XXX can probably use one buffer instead of several */
+    char               Wstrerror_buffer[512];
+    struct servent     Wservent;
+    char               Wgetlogin_buffer[128];
+#    ifdef USE_SOCKETS_AS_HANDLES
+    int                        Winit_socktype;
+#    endif
+#    ifdef HAVE_DES_FCRYPT
+    char               Wcrypt_buffer[30];
+#    endif
+#    ifdef USE_RTL_THREAD_API
+    void *             retv;   /* slot for thread return value */
+#    endif
+};
+
+#ifdef USE_THREADS
+#  ifndef USE_DECLSPEC_THREAD
+#    define HAVE_THREAD_INTERN
+#  endif /* !USE_DECLSPEC_THREAD */
+#endif /* USE_THREADS */
+
 #define HAVE_INTERP_INTERN
 typedef struct {
     long       num;
     DWORD      pids[MAXIMUM_WAIT_OBJECTS];
+    HANDLE     handles[MAXIMUM_WAIT_OBJECTS];
 } child_tab;
 
-struct host_link {
-    char *     nameId;
-    void *     host_data;
-    struct host_link * next;
-};
-
 struct interp_intern {
     char *     perlshell_tokens;
     char **    perlshell_vec;
     long       perlshell_items;
     struct av *        fdpid;
     child_tab *        children;
-    HANDLE     child_handles[MAXIMUM_WAIT_OBJECTS];
-    struct host_link * hostlist;
+#ifdef USE_ITHREADS
+    DWORD      pseudo_id;
+    child_tab *        pseudo_children;
+#endif
+    void *     internal_host;
+#ifndef USE_THREADS
+    struct thread_intern       thr_intern;
+#endif
 };
 
 
@@ -371,34 +405,25 @@ struct interp_intern {
 #define w32_children           (PL_sys_intern.children)
 #define w32_num_children       (w32_children->num)
 #define w32_child_pids         (w32_children->pids)
-#define w32_child_handles      (PL_sys_intern.child_handles)
-#define w32_host_link          (PL_sys_intern.hostlist)
-
-/* 
- * Now Win32 specific per-thread data stuff 
- */
-
+#define w32_child_handles      (w32_children->handles)
+#define w32_pseudo_id          (PL_sys_intern.pseudo_id)
+#define w32_pseudo_children    (PL_sys_intern.pseudo_children)
+#define w32_num_pseudo_children                (w32_pseudo_children->num)
+#define w32_pseudo_child_pids          (w32_pseudo_children->pids)
+#define w32_pseudo_child_handles       (w32_pseudo_children->handles)
+#define w32_internal_host              (PL_sys_intern.internal_host)
 #ifdef USE_THREADS
-#  ifndef USE_DECLSPEC_THREAD
-#    define HAVE_THREAD_INTERN
-
-struct thread_intern {
-    /* XXX can probably use one buffer instead of several */
-    char               Wstrerror_buffer[512];
-    struct servent     Wservent;
-    char               Wgetlogin_buffer[128];
-    char               Ww32_perllib_root[MAX_PATH+1];
-#    ifdef USE_SOCKETS_AS_HANDLES
-    int                        Winit_socktype;
-#    endif
-#    ifdef HAVE_DES_FCRYPT
-    char               Wcrypt_buffer[30];
-#    endif
-#    ifdef USE_RTL_THREAD_API
-    void *             retv;   /* slot for thread return value */
-#    endif
-};
-#  endif /* !USE_DECLSPEC_THREAD */
+#  define w32_strerror_buffer  (thr->i.Wstrerror_buffer)
+#  define w32_getlogin_buffer  (thr->i.Wgetlogin_buffer)
+#  define w32_crypt_buffer     (thr->i.Wcrypt_buffer)
+#  define w32_servent          (thr->i.Wservent)
+#  define w32_init_socktype    (thr->i.Winit_socktype)
+#else
+#  define w32_strerror_buffer  (PL_sys_intern.thr_intern.Wstrerror_buffer)
+#  define w32_getlogin_buffer  (PL_sys_intern.thr_intern.Wgetlogin_buffer)
+#  define w32_crypt_buffer     (PL_sys_intern.thr_intern.Wcrypt_buffer)
+#  define w32_servent          (PL_sys_intern.thr_intern.Wservent)
+#  define w32_init_socktype    (PL_sys_intern.thr_intern.Winit_socktype)
 #endif /* USE_THREADS */
 
 /* UNICODE<>ANSI translation helpers */
@@ -413,6 +438,20 @@ struct thread_intern {
 
 #define USING_WIDE()   (PerlEnv_os_id() == VER_PLATFORM_WIN32_NT)
 
+#ifdef USE_ITHREADS
+#  define PERL_WAIT_FOR_CHILDREN \
+    STMT_START {                                                       \
+       if (w32_pseudo_children && w32_num_pseudo_children) {           \
+           long children = w32_num_pseudo_children;                    \
+           WaitForMultipleObjects(children,                            \
+                                  w32_pseudo_child_handles,            \
+                                  TRUE, INFINITE);                     \
+           while (children)                                            \
+               CloseHandle(w32_pseudo_child_handles[--children]);      \
+       }                                                               \
+    } STMT_END
+#endif
+
 /*
  * This provides a layer of functions and macros to ensure extensions will
  * get to use the same RTL functions as the core.