revert my last change
authorThomas Bluemel <thomas@reactsoft.com>
Fri, 13 Jan 2006 17:54:37 +0000 (17:54 +0000)
committerThomas Bluemel <thomas@reactsoft.com>
Fri, 13 Jan 2006 17:54:37 +0000 (17:54 +0000)
svn path=/trunk/; revision=20835

reactos/lib/crt/crt.xml
reactos/lib/crt/include/internal/tls.h
reactos/lib/crt/misc/tls.c
reactos/lib/crt/process/thread.c
reactos/lib/crt/wine/thread.c [new file with mode: 0644]

index 1a2f64f..2db3f46 100644 (file)
                <file>cppexcept.c</file>
                <file>heap.c</file>
                <file>scanf.c</file>
+               <file>thread.c</file>
                <file>undname.c</file>
        </directory>
 </module>
index 79ad295..4adcc83 100644 (file)
 
 typedef struct _ThreadData
 {
-  HANDLE hThread;               /* handle to the current thread */
-  void (__cdecl *start_address)(void*); /* the start address supplied by _beginthread() */
-  void* arglist;                /* the argument list supplied by _beginthread() */
-
   int terrno;                   /* *nix error code */
   unsigned long tdoserrno;      /* Win32 error code (for I/O only) */
   unsigned __int64 tnext;       /* used by rand/srand */
@@ -45,8 +41,7 @@ typedef struct _ThreadData
 int CreateThreadData(void);
 void DestroyThreadData(void);
 
-int SetThreadData(PTHREADDATA ThreadData);
-void FreeThreadData(PTHREADDATA ThreadData);
+void FreeThreadData(PTHREADDATA ptd);
 PTHREADDATA GetThreadData(void);
 
 #endif /* __MSVCRT_INTERNAL_TLS_H */
index 41414f3..9fa6d03 100644 (file)
@@ -4,7 +4,7 @@
 #include <internal/rterror.h>
 
 
-static DWORD TlsIndex = TLS_OUT_OF_INDEXES;
+static unsigned long TlsIndex = (unsigned long)-1;
 
 
 static void InitThreadData(PTHREADDATA ThreadData)
@@ -19,38 +19,40 @@ static void InitThreadData(PTHREADDATA ThreadData)
 }
 
 
-int SetThreadData(PTHREADDATA ThreadData)
+int CreateThreadData(void)
 {
-   if(TlsIndex == TLS_OUT_OF_INDEXES ||
-      !TlsSetValue(TlsIndex, ThreadData))
+   PTHREADDATA ThreadData;
+
+   TlsIndex = TlsAlloc();
+   if (TlsIndex == (unsigned long)-1)
      return FALSE;
 
-   InitThreadData(ThreadData);
+   ThreadData = (PTHREADDATA)calloc(1, sizeof(THREADDATA));
+   if (ThreadData == NULL)
+     return FALSE;
 
-   return TRUE;
-}
+   if(!TlsSetValue(TlsIndex, (LPVOID)ThreadData))
+     return FALSE;
 
+   InitThreadData(ThreadData);
 
-int CreateThreadData(void)
-{
-   TlsIndex = TlsAlloc();
-   return (TlsIndex != TLS_OUT_OF_INDEXES);
+   return TRUE;
 }
 
 
 void DestroyThreadData(void)
 {
-   if (TlsIndex != TLS_OUT_OF_INDEXES)
+   if (TlsIndex != (unsigned long)-1)
      {
        TlsFree(TlsIndex);
-       TlsIndex = TLS_OUT_OF_INDEXES;
+       TlsIndex = (unsigned long)-1;
      }
 }
 
 
 void FreeThreadData(PTHREADDATA ThreadData)
 {
-   if (TlsIndex != TLS_OUT_OF_INDEXES)
+   if (TlsIndex != (unsigned long)-1)
      {
        if (ThreadData == NULL)
           ThreadData = TlsGetValue(TlsIndex);
@@ -82,8 +84,6 @@ PTHREADDATA GetThreadData(void)
             TlsSetValue(TlsIndex, (LPVOID)ThreadData);
 
             InitThreadData(ThreadData);
-
-             ThreadData->hThread = GetCurrentThread();
          }
        else
          {
index 2b86729..d058d72 100644 (file)
 #include <precomp.h>
 
-void _endthread(void);
-
-static DWORD WINAPI
-_beginthread_start(PVOID lpParameter)
-{
-    PTHREADDATA ThreadData = (PTHREADDATA)lpParameter;
-
-    if (SetThreadData(ThreadData))
-    {
-        /* FIXME - wrap start_address in SEH! */
-        ThreadData->start_address(ThreadData->arglist);
-
-        _endthread();
-    }
-    else
-    {
-        /* couldn't set the thread data, free it before terminating */
-        free(ThreadData);
-    }
-
-    ExitThread(0);
-}
-
-
+#if 0
 /*
- * @implemented
- *
- * FIXME: the return type should be uintptr_t
+ * @unimplemented
  */
 unsigned long _beginthread(
     void (__cdecl *start_address)(void*),
     unsigned stack_size,
     void* arglist)
 {
-    HANDLE hThread;
-    PTHREADDATA ThreadData;
-
-    if (start_address == NULL) {
-        __set_errno(EINVAL);
-        return (unsigned long)-1;
-    }
-
-    /* allocate the thread data structure already here instead of allocating the
-       thread data structure in the thread itself. this way we can pass an error
-       code to the caller in case we don't have sufficient resources */
-    ThreadData = malloc(sizeof(THREADDATA));
-    if (ThreadData == NULL)
-    {
-        __set_errno(EAGAIN);
-        return (unsigned long)-1;
-    }
-
-    ThreadData->start_address = start_address;
-    ThreadData->arglist = arglist;
-
-    hThread = CreateThread(NULL,
-                           stack_size,
-                           _beginthread_start,
-                           ThreadData,
-                           CREATE_SUSPENDED,
-                           NULL);
-    if (hThread == NULL)
-    {
-        free(ThreadData);
-        __set_errno(EAGAIN);
-        return (unsigned long)-1;
-    }
-
-    ThreadData->hThread = hThread;
-
-    if (ResumeThread(hThread) == (DWORD)-1)
-    {
-        CloseHandle(hThread);
-
-        /* freeing the ThreadData _could_ cause a crash, but only in case someone
-           else resumed the thread and it got to free the context before we actually
-           get here, but that's _very_ unlikely! */
-        free(ThreadData);
-        __set_errno(EAGAIN);
-        return (unsigned long)-1;
-    }
-
-    return (unsigned long)hThread;
+    __set_errno ( ENOSYS );
+    return (unsigned long)-1;
 }
-
+#endif
 /*
- * @implemented
+ * @unimplemented
  */
 void _endthread(void)
 {
-    PTHREADDATA ThreadData = GetThreadData();
-
-    /* close the thread handle */
-    CloseHandle(ThreadData->hThread);
-
-    /* NOTE: the thread data will be freed in the thread detach routine that will
-             call FreeThreadData */
-
-    ExitThread(0);
 }
+
+/* EOF */
diff --git a/reactos/lib/crt/wine/thread.c b/reactos/lib/crt/wine/thread.c
new file mode 100644 (file)
index 0000000..d1574d6
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * msvcrt.dll thread functions
+ *
+ * Copyright 2000 Jon Griffiths
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <precomp.h>
+#include <internal/wine/msvcrt.h>
+
+#include <malloc.h>
+#include <process.h>
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
+
+void _amsg_exit (int errnum);
+/* Index to TLS */
+DWORD MSVCRT_tls_index;
+
+typedef void (*_beginthread_start_routine_t)(void *);
+typedef unsigned int (__stdcall *_beginthreadex_start_routine_t)(void *);
+
+/********************************************************************/
+
+typedef struct {
+  _beginthread_start_routine_t start_address;
+  void *arglist;
+} _beginthread_trampoline_t;
+
+/*********************************************************************
+ *             msvcrt_get_thread_data
+ *
+ * Return the thread local storage structure.
+ */
+MSVCRT_thread_data *msvcrt_get_thread_data(void)
+{
+    MSVCRT_thread_data *ptr;
+    DWORD err = GetLastError();  /* need to preserve last error */
+
+    if (!(ptr = TlsGetValue( MSVCRT_tls_index )))
+    {
+        if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) )))
+                   _amsg_exit( _RT_THREAD );
+        if (!TlsSetValue( MSVCRT_tls_index, ptr ))
+                       _amsg_exit( _RT_THREAD );
+        if (!TlsSetValue( MSVCRT_tls_index, ptr ))
+                       _amsg_exit( _RT_THREAD );
+    }
+    SetLastError( err );
+    return ptr;
+}
+
+/*********************************************************************
+ *             _beginthread_trampoline
+ */
+static DWORD CALLBACK _beginthread_trampoline(LPVOID arg)
+{
+    _beginthread_trampoline_t local_trampoline;
+
+    /* Maybe it's just being paranoid, but freeing arg right
+     * away seems safer.
+     */
+    memcpy(&local_trampoline,arg,sizeof(local_trampoline));
+       free(arg);
+
+    local_trampoline.start_address(local_trampoline.arglist);
+    return 0;
+}
+
+/*********************************************************************
+ *             _beginthread (MSVCRT.@)
+ */
+unsigned long _beginthread(
+  _beginthread_start_routine_t start_address, /* [in] Start address of routine that begins execution of new thread */
+  unsigned int stack_size, /* [in] Stack size for new thread or 0 */
+  void *arglist)           /* [in] Argument list to be passed to new thread or NULL */
+{
+  _beginthread_trampoline_t* trampoline;
+
+  TRACE("(%p, %d, %p)\n", start_address, stack_size, arglist);
+
+  /* Allocate the trampoline here so that it is still valid when the thread
+   * starts... typically after this function has returned.
+   * _beginthread_trampoline is responsible for freeing the trampoline
+   */
+  trampoline=malloc(sizeof(*trampoline));
+  trampoline->start_address = start_address;
+  trampoline->arglist = arglist;
+
+  /* FIXME */
+  return (unsigned long)CreateThread(NULL, stack_size, _beginthread_trampoline,
+                                    trampoline, 0, NULL);
+}