1 /*
2  * pthread_self.c
3  *
4  * Description:
5  * This translation unit implements miscellaneous thread functions.
6  *
7  * --------------------------------------------------------------------------
8  *
9  *      Pthreads-win32 - POSIX Threads Library for Win32
10  *      Copyright(C) 1998 John E. Bossom
11  *      Copyright(C) 1999,2005 Pthreads-win32 contributors
12  *
13  *      Contact Email: rpj@callisto.canberra.edu.au
14  *
15  *      The current list of contributors is contained
16  *      in the file CONTRIBUTORS included with the source
17  *      code distribution. The list can also be seen at the
18  *      following World Wide Web location:
19  *      http://sources.redhat.com/pthreads-win32/contributors.html
20  *
21  *      This library is free software; you can redistribute it and/or
22  *      modify it under the terms of the GNU Lesser General Public
23  *      License as published by the Free Software Foundation; either
24  *      version 2 of the License, or (at your option) any later version.
25  *
26  *      This library is distributed in the hope that it will be useful,
27  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
28  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
29  *      Lesser General Public License for more details.
30  *
31  *      You should have received a copy of the GNU Lesser General Public
32  *      License along with this library in the file COPYING.LIB;
33  *      if not, write to the Free Software Foundation, Inc.,
34  *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
35  */
36 
37 #include "pthread.h"
38 #include "implement.h"
39 
40 pthread_t
pthread_self(void)41 pthread_self (void)
42      /*
43       * ------------------------------------------------------
44       * DOCPUBLIC
45       *      This function returns a reference to the current running
46       *      thread.
47       *
48       * PARAMETERS
49       *      N/A
50       *
51       *
52       * DESCRIPTION
53       *      This function returns a reference to the current running
54       *      thread.
55       *
56       * RESULTS
57       *              pthread_t       reference to the current thread
58       *
59       * ------------------------------------------------------
60       */
61 {
62   pthread_t self;
63   pthread_t nil = {NULL, 0};
64   ptw32_thread_t * sp;
65 
66 #if defined(_UWIN)
67   if (!ptw32_selfThreadKey)
68     return nil;
69 #endif
70 
71   sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
72 
73   if (sp != NULL)
74     {
75       self = sp->ptHandle;
76     }
77   else
78     {
79       /*
80        * Need to create an implicit 'self' for the currently
81        * executing thread.
82        */
83       self = ptw32_new ();
84       sp = (ptw32_thread_t *) self.p;
85 
86       if (sp != NULL)
87 	{
88 	  /*
89 	   * This is a non-POSIX thread which has chosen to call
90 	   * a POSIX threads function for some reason. We assume that
91 	   * it isn't joinable, but we do assume that it's
92 	   * (deferred) cancelable.
93 	   */
94 	  sp->implicit = 1;
95 	  sp->detachState = PTHREAD_CREATE_DETACHED;
96 	  sp->thread = GetCurrentThreadId ();
97 
98 #if defined(NEED_DUPLICATEHANDLE)
99 	  /*
100 	   * DuplicateHandle does not exist on WinCE.
101 	   *
102 	   * NOTE:
103 	   * GetCurrentThread only returns a pseudo-handle
104 	   * which is only valid in the current thread context.
105 	   * Therefore, you should not pass the handle to
106 	   * other threads for whatever purpose.
107 	   */
108 	  sp->threadH = GetCurrentThread ();
109 #else
110 	  if (!DuplicateHandle (GetCurrentProcess (),
111 				GetCurrentThread (),
112 				GetCurrentProcess (),
113 				&sp->threadH,
114 				0, FALSE, DUPLICATE_SAME_ACCESS))
115 	    {
116 	      /*
117 	       * Should not do this, but we have no alternative if
118 	       * we can't get a Win32 thread handle.
119 	       * Thread structs are never freed.
120 	       */
121 	      ptw32_threadReusePush (self);
122 	      /*
123 	       * As this is a win32 thread calling us and we have failed,
124 	       * return a value that makes sense to win32.
125 	       */
126 	      return nil;
127 	    }
128 #endif
129 
130 	  /*
131 	   * No need to explicitly serialise access to sched_priority
132 	   * because the new handle is not yet public.
133 	   */
134 	  sp->sched_priority = GetThreadPriority (sp->threadH);
135 	  pthread_setspecific (ptw32_selfThreadKey, (void *) sp);
136 	}
137     }
138 
139   return (self);
140 
141 }				/* pthread_self */
142