~ubuntu-branches/ubuntu/feisty/clamav/feisty

« back to all changes in this revision

Viewing changes to win32/3rdparty/pthreads/create.c

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-02-20 10:33:44 UTC
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20070220103344-zgcu2psnx9d98fpa
Tags: upstream-0.90
ImportĀ upstreamĀ versionĀ 0.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * create.c
3
 
 *
4
 
 * Description:
5
 
 * This translation unit implements routines associated with spawning a new
6
 
 * thread.
7
 
 *
8
 
 * --------------------------------------------------------------------------
9
 
 *
10
 
 *      Pthreads-win32 - POSIX Threads Library for Win32
11
 
 *      Copyright(C) 1998 John E. Bossom
12
 
 *      Copyright(C) 1999,2005 Pthreads-win32 contributors
13
 
 * 
14
 
 *      Contact Email: rpj@callisto.canberra.edu.au
15
 
 * 
16
 
 *      The current list of contributors is contained
17
 
 *      in the file CONTRIBUTORS included with the source
18
 
 *      code distribution. The list can also be seen at the
19
 
 *      following World Wide Web location:
20
 
 *      http://sources.redhat.com/pthreads-win32/contributors.html
21
 
 * 
22
 
 *      This library is free software; you can redistribute it and/or
23
 
 *      modify it under the terms of the GNU Lesser General Public
24
 
 *      License as published by the Free Software Foundation; either
25
 
 *      version 2 of the License, or (at your option) any later version.
26
 
 * 
27
 
 *      This library is distributed in the hope that it will be useful,
28
 
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
29
 
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
30
 
 *      Lesser General Public License for more details.
31
 
 * 
32
 
 *      You should have received a copy of the GNU Lesser General Public
33
 
 *      License along with this library in the file COPYING.LIB;
34
 
 *      if not, write to the Free Software Foundation, Inc.,
35
 
 *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
36
 
 */
37
 
 
38
 
#include "pthread.h"
39
 
#include "implement.h"
40
 
#if ! defined(_UWIN) && ! defined(WINCE)
41
 
#include <process.h>
42
 
#endif
43
 
 
44
 
int
45
 
pthread_create (pthread_t * tid,
46
 
                const pthread_attr_t * attr,
47
 
                void *(*start) (void *), void *arg)
48
 
     /*
49
 
      * ------------------------------------------------------
50
 
      * DOCPUBLIC
51
 
      *      This function creates a thread running the start function,
52
 
      *      passing it the parameter value, 'arg'. The 'attr'
53
 
      *      argument specifies optional creation attributes.
54
 
      *      The identity of the new thread is returned
55
 
      *      via 'tid', which should not be NULL.
56
 
      *
57
 
      * PARAMETERS
58
 
      *      tid
59
 
      *              pointer to an instance of pthread_t
60
 
      *
61
 
      *      attr
62
 
      *              optional pointer to an instance of pthread_attr_t
63
 
      *
64
 
      *      start
65
 
      *              pointer to the starting routine for the new thread
66
 
      *
67
 
      *      arg
68
 
      *              optional parameter passed to 'start'
69
 
      *
70
 
      *
71
 
      * DESCRIPTION
72
 
      *      This function creates a thread running the start function,
73
 
      *      passing it the parameter value, 'arg'. The 'attr'
74
 
      *      argument specifies optional creation attributes.
75
 
      *      The identity of the new thread is returned
76
 
      *      via 'tid', which should not be the NULL pointer.
77
 
      *
78
 
      * RESULTS
79
 
      *              0               successfully created thread,
80
 
      *              EINVAL          attr invalid,
81
 
      *              EAGAIN          insufficient resources.
82
 
      *
83
 
      * ------------------------------------------------------
84
 
      */
85
 
{
86
 
  pthread_t thread;
87
 
  ptw32_thread_t * tp;
88
 
  register pthread_attr_t a;
89
 
  HANDLE threadH = 0;
90
 
  int result = EAGAIN;
91
 
  int run = PTW32_TRUE;
92
 
  ThreadParms *parms = NULL;
93
 
  long stackSize;
94
 
  int priority;
95
 
  pthread_t self;
96
 
 
97
 
  /*
98
 
   * Before doing anything, check that tid can be stored through
99
 
   * without invoking a memory protection error (segfault).
100
 
   * Make sure that the assignment below can't be optimised out by the compiler.
101
 
   * This is assured by conditionally assigning *tid again at the end.
102
 
   */
103
 
  tid->x = 0;
104
 
 
105
 
  if (attr != NULL)
106
 
    {
107
 
      a = *attr;
108
 
    }
109
 
  else
110
 
    {
111
 
      a = NULL;
112
 
    }
113
 
 
114
 
  if ((thread = ptw32_new ()).p == NULL)
115
 
    {
116
 
      goto FAIL0;
117
 
    }
118
 
 
119
 
  tp = (ptw32_thread_t *) thread.p;
120
 
 
121
 
  priority = tp->sched_priority;
122
 
 
123
 
  if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL)
124
 
    {
125
 
      goto FAIL0;
126
 
    }
127
 
 
128
 
  parms->tid = thread;
129
 
  parms->start = start;
130
 
  parms->arg = arg;
131
 
 
132
 
#if defined(HAVE_SIGSET_T)
133
 
 
134
 
  /*
135
 
   * Threads inherit their initial sigmask from their creator thread.
136
 
   */
137
 
  self = pthread_self();
138
 
  tp->sigmask = ((ptw32_thread_t *)self.p)->sigmask;
139
 
 
140
 
#endif /* HAVE_SIGSET_T */
141
 
 
142
 
 
143
 
  if (a != NULL)
144
 
    {
145
 
      stackSize = a->stacksize;
146
 
      tp->detachState = a->detachstate;
147
 
      priority = a->param.sched_priority;
148
 
 
149
 
#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
150
 
      /* WinCE */
151
 
#else
152
 
      /* Everything else */
153
 
 
154
 
      /*
155
 
       * Thread priority must be set to a valid system level
156
 
       * without altering the value set by pthread_attr_setschedparam().
157
 
       */
158
 
 
159
 
      /*
160
 
       * PTHREAD_EXPLICIT_SCHED is the default because Win32 threads
161
 
       * don't inherit their creator's priority. They are started with
162
 
       * THREAD_PRIORITY_NORMAL (win32 value). The result of not supplying
163
 
       * an 'attr' arg to pthread_create() is equivalent to defaulting to
164
 
       * PTHREAD_EXPLICIT_SCHED and priority THREAD_PRIORITY_NORMAL.
165
 
       */
166
 
      if (PTHREAD_INHERIT_SCHED == a->inheritsched)
167
 
        {
168
 
          /*
169
 
           * If the thread that called pthread_create() is a Win32 thread
170
 
           * then the inherited priority could be the result of a temporary
171
 
           * system adjustment. This is not the case for POSIX threads.
172
 
           */
173
 
#if ! defined(HAVE_SIGSET_T)
174
 
          self = pthread_self ();
175
 
#endif
176
 
          priority = ((ptw32_thread_t *) self.p)->sched_priority;
177
 
        }
178
 
 
179
 
#endif
180
 
 
181
 
    }
182
 
  else
183
 
    {
184
 
      /*
185
 
       * Default stackSize
186
 
       */
187
 
      stackSize = PTHREAD_STACK_MIN;
188
 
    }
189
 
 
190
 
  tp->state = run ? PThreadStateInitial : PThreadStateSuspended;
191
 
 
192
 
  tp->keys = NULL;
193
 
 
194
 
  /*
195
 
   * Threads must be started in suspended mode and resumed if necessary
196
 
   * after _beginthreadex returns us the handle. Otherwise we set up a
197
 
   * race condition between the creating and the created threads.
198
 
   * Note that we also retain a local copy of the handle for use
199
 
   * by us in case thread.p->threadH gets NULLed later but before we've
200
 
   * finished with it here.
201
 
   */
202
 
 
203
 
#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) 
204
 
 
205
 
  tp->threadH =
206
 
    threadH =
207
 
    (HANDLE) _beginthreadex ((void *) NULL,     /* No security info             */
208
 
                             (unsigned) stackSize,      /* default stack size   */
209
 
                             ptw32_threadStart,
210
 
                             parms,
211
 
                             (unsigned)
212
 
                             CREATE_SUSPENDED,
213
 
                             (unsigned *) &(tp->thread));
214
 
 
215
 
  if (threadH != 0)
216
 
    {
217
 
      if (a != NULL)
218
 
        {
219
 
          (void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority);
220
 
        }
221
 
 
222
 
      if (run)
223
 
        {
224
 
          ResumeThread (threadH);
225
 
        }
226
 
    }
227
 
 
228
 
#else /* __MINGW32__ && ! __MSVCRT__ */
229
 
 
230
 
  /*
231
 
   * This lock will force pthread_threadStart() to wait until we have
232
 
   * the thread handle and have set the priority.
233
 
   */
234
 
  (void) pthread_mutex_lock (&tp->cancelLock);
235
 
 
236
 
  tp->threadH =
237
 
    threadH =
238
 
    (HANDLE) _beginthread (ptw32_threadStart, (unsigned) stackSize,     /* default stack size   */
239
 
                           parms);
240
 
 
241
 
  /*
242
 
   * Make the return code match _beginthreadex's.
243
 
   */
244
 
  if (threadH == (HANDLE) - 1L)
245
 
    {
246
 
      tp->threadH = threadH = 0;
247
 
    }
248
 
  else
249
 
    {
250
 
      if (!run)
251
 
        {
252
 
          /* 
253
 
           * beginthread does not allow for create flags, so we do it now.
254
 
           * Note that beginthread itself creates the thread in SUSPENDED
255
 
           * mode, and then calls ResumeThread to start it.
256
 
           */
257
 
          SuspendThread (threadH);
258
 
        }
259
 
 
260
 
      if (a != NULL)
261
 
        {
262
 
          (void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority);
263
 
        }
264
 
    }
265
 
 
266
 
  (void) pthread_mutex_unlock (&tp->cancelLock);
267
 
 
268
 
#endif /* __MINGW32__ && ! __MSVCRT__ */
269
 
 
270
 
  result = (threadH != 0) ? 0 : EAGAIN;
271
 
 
272
 
  /*
273
 
   * Fall Through Intentionally
274
 
   */
275
 
 
276
 
  /*
277
 
   * ------------
278
 
   * Failure Code
279
 
   * ------------
280
 
   */
281
 
 
282
 
FAIL0:
283
 
  if (result != 0)
284
 
    {
285
 
 
286
 
      ptw32_threadDestroy (thread);
287
 
      tp = NULL;
288
 
 
289
 
      if (parms != NULL)
290
 
        {
291
 
          free (parms);
292
 
        }
293
 
    }
294
 
  else
295
 
    {
296
 
      *tid = thread;
297
 
    }
298
 
 
299
 
#ifdef _UWIN
300
 
  if (result == 0)
301
 
    pthread_count++;
302
 
#endif
303
 
  return (result);
304
 
 
305
 
}                               /* pthread_create */