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 *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
35 */
36
37#include "pthread.h"
38#include "implement.h"
39
40pthread_t
41pthread_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