/[dtapublic]/projs/trunk/shared_source/c_tcl_base_7_5_w_mods/tclthread.c
ViewVC logotype

Diff of /projs/trunk/shared_source/c_tcl_base_7_5_w_mods/tclthread.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 67 by dashley, Mon Oct 31 00:57:34 2016 UTC revision 71 by dashley, Sat Nov 5 11:07:06 2016 UTC
# Line 1  Line 1 
1  /* $Header$ */  /* $Header$ */
2  /*  /*
3   * tclThread.c --   * tclThread.c --
4   *   *
5   *      This file implements   Platform independent thread operations.   *      This file implements   Platform independent thread operations.
6   *      Most of the real work is done in the platform dependent files.   *      Most of the real work is done in the platform dependent files.
7   *   *
8   * Copyright (c) 1998 by Sun Microsystems, Inc.   * Copyright (c) 1998 by Sun Microsystems, Inc.
9   *   *
10   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
11   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12   *   *
13   * RCS: @(#) $Id: tclthread.c,v 1.1.1.1 2001/06/13 04:46:27 dtashley Exp $   * RCS: @(#) $Id: tclthread.c,v 1.1.1.1 2001/06/13 04:46:27 dtashley Exp $
14   */   */
15    
16  #include "tclInt.h"  #include "tclInt.h"
17    
18  /*  /*
19   * There are three classes of synchronization objects:   * There are three classes of synchronization objects:
20   * mutexes, thread data keys, and condition variables.   * mutexes, thread data keys, and condition variables.
21   * The following are used to record the memory used for these   * The following are used to record the memory used for these
22   * objects so they can be finalized.   * objects so they can be finalized.
23   *   *
24   * These statics are guarded by the mutex in the caller of   * These statics are guarded by the mutex in the caller of
25   * TclRememberThreadData, e.g., TclpThreadDataKeyInit   * TclRememberThreadData, e.g., TclpThreadDataKeyInit
26   */   */
27    
28  typedef struct {  typedef struct {
29      int num;            /* Number of objects remembered */      int num;            /* Number of objects remembered */
30      int max;            /* Max size of the array */      int max;            /* Max size of the array */
31      char **list;        /* List of pointers */      char **list;        /* List of pointers */
32  } SyncObjRecord;  } SyncObjRecord;
33    
34  static SyncObjRecord keyRecord;  static SyncObjRecord keyRecord;
35  static SyncObjRecord mutexRecord;  static SyncObjRecord mutexRecord;
36  static SyncObjRecord condRecord;  static SyncObjRecord condRecord;
37    
38  /*  /*
39   * Prototypes of functions used only in this file   * Prototypes of functions used only in this file
40   */   */
41    
42  static void             RememberSyncObject _ANSI_ARGS_((char *objPtr,  static void             RememberSyncObject _ANSI_ARGS_((char *objPtr,
43                              SyncObjRecord *recPtr));                              SyncObjRecord *recPtr));
44  static void             ForgetSyncObject _ANSI_ARGS_((char *objPtr,  static void             ForgetSyncObject _ANSI_ARGS_((char *objPtr,
45                              SyncObjRecord *recPtr));                              SyncObjRecord *recPtr));
46    
47  /*  /*
48   * Several functions are #defined to nothing in tcl.h if TCL_THREADS is not   * Several functions are #defined to nothing in tcl.h if TCL_THREADS is not
49   * specified.  Here we undo that so the procedures are defined in the   * specified.  Here we undo that so the procedures are defined in the
50   * stubs table.   * stubs table.
51   */   */
52  #ifndef TCL_THREADS  #ifndef TCL_THREADS
53  #undef Tcl_MutexLock  #undef Tcl_MutexLock
54  #undef Tcl_MutexUnlock  #undef Tcl_MutexUnlock
55  #undef Tcl_MutexFinalize  #undef Tcl_MutexFinalize
56  #undef Tcl_ConditionNotify  #undef Tcl_ConditionNotify
57  #undef Tcl_ConditionWait  #undef Tcl_ConditionWait
58  #undef Tcl_ConditionFinalize  #undef Tcl_ConditionFinalize
59  #endif  #endif
60    
61    
62  /*  /*
63   *----------------------------------------------------------------------   *----------------------------------------------------------------------
64   *   *
65   * Tcl_GetThreadData --   * Tcl_GetThreadData --
66   *   *
67   *      This procedure allocates and initializes a chunk of thread   *      This procedure allocates and initializes a chunk of thread
68   *      local storage.   *      local storage.
69   *   *
70   * Results:   * Results:
71   *      A thread-specific pointer to the data structure.   *      A thread-specific pointer to the data structure.
72   *   *
73   * Side effects:   * Side effects:
74   *      Will allocate memory the first time this thread calls for   *      Will allocate memory the first time this thread calls for
75   *      this chunk of storage.   *      this chunk of storage.
76   *   *
77   *----------------------------------------------------------------------   *----------------------------------------------------------------------
78   */   */
79    
80  VOID *  VOID *
81  Tcl_GetThreadData(keyPtr, size)  Tcl_GetThreadData(keyPtr, size)
82      Tcl_ThreadDataKey *keyPtr;  /* Identifier for the data chunk */      Tcl_ThreadDataKey *keyPtr;  /* Identifier for the data chunk */
83      int size;                   /* Size of storage block */      int size;                   /* Size of storage block */
84  {  {
85      VOID *result;      VOID *result;
86  #ifdef TCL_THREADS  #ifdef TCL_THREADS
87    
88      /*      /*
89       * See if this is the first thread to init this key.       * See if this is the first thread to init this key.
90       */       */
91    
92      if (*keyPtr == NULL) {      if (*keyPtr == NULL) {
93          TclpThreadDataKeyInit(keyPtr);          TclpThreadDataKeyInit(keyPtr);
94      }      }
95    
96      /*      /*
97       * Initialize the key for this thread.       * Initialize the key for this thread.
98       */       */
99    
100      result = TclpThreadDataKeyGet(keyPtr);      result = TclpThreadDataKeyGet(keyPtr);
101      if (result == NULL) {      if (result == NULL) {
102          result  = (VOID *)ckalloc((size_t)size);          result  = (VOID *)ckalloc((size_t)size);
103          memset(result, 0, (size_t)size);          memset(result, 0, (size_t)size);
104          TclpThreadDataKeySet(keyPtr, result);          TclpThreadDataKeySet(keyPtr, result);
105      }      }
106  #else  #else
107      if (*keyPtr == NULL) {      if (*keyPtr == NULL) {
108          result = (VOID *)ckalloc((size_t)size);          result = (VOID *)ckalloc((size_t)size);
109          memset((char *)result, 0, (size_t)size);          memset((char *)result, 0, (size_t)size);
110          *keyPtr = (Tcl_ThreadDataKey)result;          *keyPtr = (Tcl_ThreadDataKey)result;
111          TclRememberDataKey(keyPtr);          TclRememberDataKey(keyPtr);
112      }      }
113      result = *(VOID **)keyPtr;      result = *(VOID **)keyPtr;
114  #endif  #endif
115      return result;      return result;
116  }  }
117    
118  /*  /*
119   *----------------------------------------------------------------------   *----------------------------------------------------------------------
120   *   *
121   * TclThreadDataKeyGet --   * TclThreadDataKeyGet --
122   *   *
123   *      This procedure returns a pointer to a block of thread local storage.   *      This procedure returns a pointer to a block of thread local storage.
124   *   *
125   * Results:   * Results:
126   *      A thread-specific pointer to the data structure, or NULL   *      A thread-specific pointer to the data structure, or NULL
127   *      if the memory has not been assigned to this key for this thread.   *      if the memory has not been assigned to this key for this thread.
128   *   *
129   * Side effects:   * Side effects:
130   *      None.   *      None.
131   *   *
132   *----------------------------------------------------------------------   *----------------------------------------------------------------------
133   */   */
134    
135  VOID *  VOID *
136  TclThreadDataKeyGet(keyPtr)  TclThreadDataKeyGet(keyPtr)
137      Tcl_ThreadDataKey *keyPtr;  /* Identifier for the data chunk,      Tcl_ThreadDataKey *keyPtr;  /* Identifier for the data chunk,
138                                   * really (pthread_key_t **) */                                   * really (pthread_key_t **) */
139  {  {
140  #ifdef TCL_THREADS  #ifdef TCL_THREADS
141      return (VOID *)TclpThreadDataKeyGet(keyPtr);      return (VOID *)TclpThreadDataKeyGet(keyPtr);
142  #else  #else
143      char *result = *(char **)keyPtr;      char *result = *(char **)keyPtr;
144      return (VOID *)result;      return (VOID *)result;
145  #endif /* TCL_THREADS */  #endif /* TCL_THREADS */
146  }  }
147    
148    
149  /*  /*
150   *----------------------------------------------------------------------   *----------------------------------------------------------------------
151   *   *
152   * TclThreadDataKeySet --   * TclThreadDataKeySet --
153   *   *
154   *      This procedure sets a thread local storage pointer.   *      This procedure sets a thread local storage pointer.
155   *   *
156   * Results:   * Results:
157   *      None.   *      None.
158   *   *
159   * Side effects:   * Side effects:
160   *      The assigned value will be returned by TclpThreadDataKeyGet.   *      The assigned value will be returned by TclpThreadDataKeyGet.
161   *   *
162   *----------------------------------------------------------------------   *----------------------------------------------------------------------
163   */   */
164    
165  void  void
166  TclThreadDataKeySet(keyPtr, data)  TclThreadDataKeySet(keyPtr, data)
167      Tcl_ThreadDataKey *keyPtr;  /* Identifier for the data chunk,      Tcl_ThreadDataKey *keyPtr;  /* Identifier for the data chunk,
168                                   * really (pthread_key_t **) */                                   * really (pthread_key_t **) */
169      VOID *data;                 /* Thread local storage */      VOID *data;                 /* Thread local storage */
170  {  {
171  #ifdef TCL_THREADS  #ifdef TCL_THREADS
172      if (*keyPtr == NULL) {      if (*keyPtr == NULL) {
173          TclpThreadDataKeyInit(keyPtr);          TclpThreadDataKeyInit(keyPtr);
174      }      }
175      TclpThreadDataKeySet(keyPtr, data);      TclpThreadDataKeySet(keyPtr, data);
176  #else  #else
177      *keyPtr = (Tcl_ThreadDataKey)data;      *keyPtr = (Tcl_ThreadDataKey)data;
178  #endif /* TCL_THREADS */  #endif /* TCL_THREADS */
179  }  }
180    
181    
182    
183  /*  /*
184   *----------------------------------------------------------------------   *----------------------------------------------------------------------
185   *   *
186   * RememberSyncObject   * RememberSyncObject
187   *   *
188   *      Keep a list of (mutexes/condition variable/data key)   *      Keep a list of (mutexes/condition variable/data key)
189   *      used during finalization.   *      used during finalization.
190   *   *
191   * Results:   * Results:
192   *      None.   *      None.
193   *   *
194   * Side effects:   * Side effects:
195   *      Add to the appropriate list.   *      Add to the appropriate list.
196   *   *
197   *----------------------------------------------------------------------   *----------------------------------------------------------------------
198   */   */
199    
200  static void  static void
201  RememberSyncObject(objPtr, recPtr)  RememberSyncObject(objPtr, recPtr)
202      char *objPtr;               /* Pointer to sync object */      char *objPtr;               /* Pointer to sync object */
203      SyncObjRecord *recPtr;      /* Record of sync objects */      SyncObjRecord *recPtr;      /* Record of sync objects */
204  {  {
205      char **newList;      char **newList;
206      int i, j;      int i, j;
207    
208      /*      /*
209       * Save the pointer to the allocated object so it can be finalized.       * Save the pointer to the allocated object so it can be finalized.
210       * Grow the list of pointers if necessary, copying only non-NULL       * Grow the list of pointers if necessary, copying only non-NULL
211       * pointers to the new list.       * pointers to the new list.
212       */       */
213    
214      if (recPtr->num >= recPtr->max) {      if (recPtr->num >= recPtr->max) {
215          recPtr->max += 8;          recPtr->max += 8;
216          newList = (char **)ckalloc(recPtr->max * sizeof(char *));          newList = (char **)ckalloc(recPtr->max * sizeof(char *));
217          for (i=0,j=0 ; i<recPtr->num ; i++) {          for (i=0,j=0 ; i<recPtr->num ; i++) {
218              if (recPtr->list[i] != NULL) {              if (recPtr->list[i] != NULL) {
219                  newList[j++] = recPtr->list[i];                  newList[j++] = recPtr->list[i];
220              }              }
221          }          }
222          if (recPtr->list != NULL) {          if (recPtr->list != NULL) {
223              ckfree((char *)recPtr->list);              ckfree((char *)recPtr->list);
224          }          }
225          recPtr->list = newList;          recPtr->list = newList;
226          recPtr->num = j;          recPtr->num = j;
227      }      }
228      recPtr->list[recPtr->num] = objPtr;      recPtr->list[recPtr->num] = objPtr;
229      recPtr->num++;      recPtr->num++;
230  }  }
231    
232  /*  /*
233   *----------------------------------------------------------------------   *----------------------------------------------------------------------
234   *   *
235   * ForgetSyncObject   * ForgetSyncObject
236   *   *
237   *      Remove a single object from the list.   *      Remove a single object from the list.
238   *   *
239   * Results:   * Results:
240   *      None.   *      None.
241   *   *
242   * Side effects:   * Side effects:
243   *      Remove from the appropriate list.   *      Remove from the appropriate list.
244   *   *
245   *----------------------------------------------------------------------   *----------------------------------------------------------------------
246   */   */
247    
248  static void  static void
249  ForgetSyncObject(objPtr, recPtr)  ForgetSyncObject(objPtr, recPtr)
250      char *objPtr;               /* Pointer to sync object */      char *objPtr;               /* Pointer to sync object */
251      SyncObjRecord *recPtr;      /* Record of sync objects */      SyncObjRecord *recPtr;      /* Record of sync objects */
252  {  {
253      int i;      int i;
254    
255      for (i=0 ; i<recPtr->num ; i++) {      for (i=0 ; i<recPtr->num ; i++) {
256          if (objPtr == recPtr->list[i]) {          if (objPtr == recPtr->list[i]) {
257              recPtr->list[i] = NULL;              recPtr->list[i] = NULL;
258              return;              return;
259          }          }
260      }      }
261  }  }
262    
263  /*  /*
264   *----------------------------------------------------------------------   *----------------------------------------------------------------------
265   *   *
266   * TclRememberMutex   * TclRememberMutex
267   *   *
268   *      Keep a list of mutexes used during finalization.   *      Keep a list of mutexes used during finalization.
269   *   *
270   * Results:   * Results:
271   *      None.   *      None.
272   *   *
273   * Side effects:   * Side effects:
274   *      Add to the mutex list.   *      Add to the mutex list.
275   *   *
276   *----------------------------------------------------------------------   *----------------------------------------------------------------------
277   */   */
278    
279  void  void
280  TclRememberMutex(mutexPtr)  TclRememberMutex(mutexPtr)
281      Tcl_Mutex *mutexPtr;      Tcl_Mutex *mutexPtr;
282  {  {
283      RememberSyncObject((char *)mutexPtr, &mutexRecord);      RememberSyncObject((char *)mutexPtr, &mutexRecord);
284  }  }
285    
286  /*  /*
287   *----------------------------------------------------------------------   *----------------------------------------------------------------------
288   *   *
289   * Tcl_MutexFinalize   * Tcl_MutexFinalize
290   *   *
291   *      Finalize a single mutex and remove it from the   *      Finalize a single mutex and remove it from the
292   *      list of remembered objects.   *      list of remembered objects.
293   *   *
294   * Results:   * Results:
295   *      None.   *      None.
296   *   *
297   * Side effects:   * Side effects:
298   *      Remove the mutex from the list.   *      Remove the mutex from the list.
299   *   *
300   *----------------------------------------------------------------------   *----------------------------------------------------------------------
301   */   */
302    
303  void  void
304  Tcl_MutexFinalize(mutexPtr)  Tcl_MutexFinalize(mutexPtr)
305      Tcl_Mutex *mutexPtr;      Tcl_Mutex *mutexPtr;
306  {  {
307  #ifdef TCL_THREADS  #ifdef TCL_THREADS
308      TclpFinalizeMutex(mutexPtr);      TclpFinalizeMutex(mutexPtr);
309  #endif  #endif
310      ForgetSyncObject((char *)mutexPtr, &mutexRecord);      ForgetSyncObject((char *)mutexPtr, &mutexRecord);
311  }  }
312    
313  /*  /*
314   *----------------------------------------------------------------------   *----------------------------------------------------------------------
315   *   *
316   * TclRememberDataKey   * TclRememberDataKey
317   *   *
318   *      Keep a list of thread data keys used during finalization.   *      Keep a list of thread data keys used during finalization.
319   *   *
320   * Results:   * Results:
321   *      None.   *      None.
322   *   *
323   * Side effects:   * Side effects:
324   *      Add to the key list.   *      Add to the key list.
325   *   *
326   *----------------------------------------------------------------------   *----------------------------------------------------------------------
327   */   */
328    
329  void  void
330  TclRememberDataKey(keyPtr)  TclRememberDataKey(keyPtr)
331      Tcl_ThreadDataKey *keyPtr;      Tcl_ThreadDataKey *keyPtr;
332  {  {
333      RememberSyncObject((char *)keyPtr, &keyRecord);      RememberSyncObject((char *)keyPtr, &keyRecord);
334  }  }
335    
336  /*  /*
337   *----------------------------------------------------------------------   *----------------------------------------------------------------------
338   *   *
339   * TclRememberCondition   * TclRememberCondition
340   *   *
341   *      Keep a list of condition variables used during finalization.   *      Keep a list of condition variables used during finalization.
342   *   *
343   * Results:   * Results:
344   *      None.   *      None.
345   *   *
346   * Side effects:   * Side effects:
347   *      Add to the condition variable list.   *      Add to the condition variable list.
348   *   *
349   *----------------------------------------------------------------------   *----------------------------------------------------------------------
350   */   */
351    
352  void  void
353  TclRememberCondition(condPtr)  TclRememberCondition(condPtr)
354      Tcl_Condition *condPtr;      Tcl_Condition *condPtr;
355  {  {
356      RememberSyncObject((char *)condPtr, &condRecord);      RememberSyncObject((char *)condPtr, &condRecord);
357  }  }
358    
359  /*  /*
360   *----------------------------------------------------------------------   *----------------------------------------------------------------------
361   *   *
362   * Tcl_ConditionFinalize   * Tcl_ConditionFinalize
363   *   *
364   *      Finalize a single condition variable and remove it from the   *      Finalize a single condition variable and remove it from the
365   *      list of remembered objects.   *      list of remembered objects.
366   *   *
367   * Results:   * Results:
368   *      None.   *      None.
369   *   *
370   * Side effects:   * Side effects:
371   *      Remove the condition variable from the list.   *      Remove the condition variable from the list.
372   *   *
373   *----------------------------------------------------------------------   *----------------------------------------------------------------------
374   */   */
375    
376  void  void
377  Tcl_ConditionFinalize(condPtr)  Tcl_ConditionFinalize(condPtr)
378      Tcl_Condition *condPtr;      Tcl_Condition *condPtr;
379  {  {
380  #ifdef TCL_THREADS  #ifdef TCL_THREADS
381      TclpFinalizeCondition(condPtr);      TclpFinalizeCondition(condPtr);
382  #endif  #endif
383      ForgetSyncObject((char *)condPtr, &condRecord);      ForgetSyncObject((char *)condPtr, &condRecord);
384  }  }
385    
386  /*  /*
387   *----------------------------------------------------------------------   *----------------------------------------------------------------------
388   *   *
389   * TclFinalizeThreadData --   * TclFinalizeThreadData --
390   *   *
391   *      This procedure cleans up the thread-local storage.  This is   *      This procedure cleans up the thread-local storage.  This is
392   *      called once for each thread.   *      called once for each thread.
393   *   *
394   * Results:   * Results:
395   *      None.   *      None.
396   *   *
397   * Side effects:   * Side effects:
398   *      Frees up all thread local storage.   *      Frees up all thread local storage.
399   *   *
400   *----------------------------------------------------------------------   *----------------------------------------------------------------------
401   */   */
402    
403  void  void
404  TclFinalizeThreadData()  TclFinalizeThreadData()
405  {  {
406      int i;      int i;
407      Tcl_ThreadDataKey *keyPtr;      Tcl_ThreadDataKey *keyPtr;
408    
409      TclpMasterLock();      TclpMasterLock();
410      for (i=0 ; i<keyRecord.num ; i++) {      for (i=0 ; i<keyRecord.num ; i++) {
411          keyPtr = (Tcl_ThreadDataKey *) keyRecord.list[i];          keyPtr = (Tcl_ThreadDataKey *) keyRecord.list[i];
412  #ifdef TCL_THREADS  #ifdef TCL_THREADS
413          TclpFinalizeThreadData(keyPtr);          TclpFinalizeThreadData(keyPtr);
414  #else  #else
415          if (*keyPtr != NULL) {          if (*keyPtr != NULL) {
416              ckfree((char *)*keyPtr);              ckfree((char *)*keyPtr);
417              *keyPtr = NULL;              *keyPtr = NULL;
418          }          }
419  #endif  #endif
420      }      }
421  #ifdef TCL_THREADS  #ifdef TCL_THREADS
422      TclpMasterUnlock();      TclpMasterUnlock();
423  #endif  #endif
424  }  }
425    
426  /*  /*
427   *----------------------------------------------------------------------   *----------------------------------------------------------------------
428   *   *
429   * TclFinalizeSynchronization --   * TclFinalizeSynchronization --
430   *   *
431   *      This procedure cleans up all synchronization objects:   *      This procedure cleans up all synchronization objects:
432   *      mutexes, condition variables, and thread-local storage.   *      mutexes, condition variables, and thread-local storage.
433   *   *
434   * Results:   * Results:
435   *      None.   *      None.
436   *   *
437   * Side effects:   * Side effects:
438   *      Frees up the memory.   *      Frees up the memory.
439   *   *
440   *----------------------------------------------------------------------   *----------------------------------------------------------------------
441   */   */
442    
443  void  void
444  TclFinalizeSynchronization()  TclFinalizeSynchronization()
445  {  {
446  #ifdef TCL_THREADS  #ifdef TCL_THREADS
447      Tcl_ThreadDataKey *keyPtr;      Tcl_ThreadDataKey *keyPtr;
448      Tcl_Mutex *mutexPtr;      Tcl_Mutex *mutexPtr;
449      Tcl_Condition *condPtr;      Tcl_Condition *condPtr;
450      int i;      int i;
451    
452      TclpMasterLock();      TclpMasterLock();
453      for (i=0 ; i<keyRecord.num ; i++) {      for (i=0 ; i<keyRecord.num ; i++) {
454          keyPtr = (Tcl_ThreadDataKey *)keyRecord.list[i];          keyPtr = (Tcl_ThreadDataKey *)keyRecord.list[i];
455          TclpFinalizeThreadDataKey(keyPtr);          TclpFinalizeThreadDataKey(keyPtr);
456      }      }
457      if (keyRecord.list != NULL) {      if (keyRecord.list != NULL) {
458          ckfree((char *)keyRecord.list);          ckfree((char *)keyRecord.list);
459          keyRecord.list = NULL;          keyRecord.list = NULL;
460      }      }
461      keyRecord.max = 0;      keyRecord.max = 0;
462      keyRecord.num = 0;      keyRecord.num = 0;
463    
464      for (i=0 ; i<mutexRecord.num ; i++) {      for (i=0 ; i<mutexRecord.num ; i++) {
465          mutexPtr = (Tcl_Mutex *)mutexRecord.list[i];          mutexPtr = (Tcl_Mutex *)mutexRecord.list[i];
466          if (mutexPtr != NULL) {          if (mutexPtr != NULL) {
467              TclpFinalizeMutex(mutexPtr);              TclpFinalizeMutex(mutexPtr);
468          }          }
469      }      }
470      if (mutexRecord.list != NULL) {      if (mutexRecord.list != NULL) {
471          ckfree((char *)mutexRecord.list);          ckfree((char *)mutexRecord.list);
472          mutexRecord.list = NULL;          mutexRecord.list = NULL;
473      }      }
474      mutexRecord.max = 0;      mutexRecord.max = 0;
475      mutexRecord.num = 0;      mutexRecord.num = 0;
476    
477      for (i=0 ; i<condRecord.num ; i++) {      for (i=0 ; i<condRecord.num ; i++) {
478          condPtr = (Tcl_Condition *)condRecord.list[i];          condPtr = (Tcl_Condition *)condRecord.list[i];
479          if (condPtr != NULL) {          if (condPtr != NULL) {
480              TclpFinalizeCondition(condPtr);              TclpFinalizeCondition(condPtr);
481          }          }
482      }      }
483      if (condRecord.list != NULL) {      if (condRecord.list != NULL) {
484          ckfree((char *)condRecord.list);          ckfree((char *)condRecord.list);
485          condRecord.list = NULL;          condRecord.list = NULL;
486      }      }
487      condRecord.max = 0;      condRecord.max = 0;
488      condRecord.num = 0;      condRecord.num = 0;
489    
490      TclpMasterUnlock();      TclpMasterUnlock();
491  #else  #else
492      if (keyRecord.list != NULL) {      if (keyRecord.list != NULL) {
493          ckfree((char *)keyRecord.list);          ckfree((char *)keyRecord.list);
494          keyRecord.list = NULL;          keyRecord.list = NULL;
495      }      }
496      keyRecord.max = 0;      keyRecord.max = 0;
497      keyRecord.num = 0;      keyRecord.num = 0;
498  #endif  #endif
499  }  }
500    
501    
502  /*  /*
503   *----------------------------------------------------------------------   *----------------------------------------------------------------------
504   *   *
505   * Tcl_ExitThread --   * Tcl_ExitThread --
506   *   *
507   *      This procedure is called to terminate the current thread.   *      This procedure is called to terminate the current thread.
508   *      This should be used by extensions that create threads with   *      This should be used by extensions that create threads with
509   *      additional interpreters in them.   *      additional interpreters in them.
510   *   *
511   * Results:   * Results:
512   *      None.   *      None.
513   *   *
514   * Side effects:   * Side effects:
515   *      All thread exit handlers are invoked, then the thread dies.   *      All thread exit handlers are invoked, then the thread dies.
516   *   *
517   *----------------------------------------------------------------------   *----------------------------------------------------------------------
518   */   */
519    
520  void  void
521  Tcl_ExitThread(status)  Tcl_ExitThread(status)
522      int status;      int status;
523  {  {
524      Tcl_FinalizeThread();      Tcl_FinalizeThread();
525  #ifdef TCL_THREADS  #ifdef TCL_THREADS
526      TclpThreadExit(status);      TclpThreadExit(status);
527  #endif  #endif
528  }  }
529    
530  #ifndef TCL_THREADS  #ifndef TCL_THREADS
531    
532  /*  /*
533   *----------------------------------------------------------------------   *----------------------------------------------------------------------
534   *   *
535   * Tcl_ConditionWait, et al. --   * Tcl_ConditionWait, et al. --
536   *   *
537   *      These noop procedures are provided so the stub table does   *      These noop procedures are provided so the stub table does
538   *      not have to be conditionalized for threads.  The real   *      not have to be conditionalized for threads.  The real
539   *      implementations of these functions live in the platform   *      implementations of these functions live in the platform
540   *      specific files.   *      specific files.
541   *   *
542   * Results:   * Results:
543   *      None.   *      None.
544   *   *
545   * Side effects:   * Side effects:
546   *      None.   *      None.
547   *   *
548   *----------------------------------------------------------------------   *----------------------------------------------------------------------
549   */   */
550    
551  #undef Tcl_ConditionWait  #undef Tcl_ConditionWait
552  void  void
553  Tcl_ConditionWait(condPtr, mutexPtr, timePtr)  Tcl_ConditionWait(condPtr, mutexPtr, timePtr)
554      Tcl_Condition *condPtr;     /* Really (pthread_cond_t **) */      Tcl_Condition *condPtr;     /* Really (pthread_cond_t **) */
555      Tcl_Mutex *mutexPtr;        /* Really (pthread_mutex_t **) */      Tcl_Mutex *mutexPtr;        /* Really (pthread_mutex_t **) */
556      Tcl_Time *timePtr;          /* Timeout on waiting period */      Tcl_Time *timePtr;          /* Timeout on waiting period */
557  {  {
558  }  }
559    
560  #undef Tcl_ConditionNotify  #undef Tcl_ConditionNotify
561  void  void
562  Tcl_ConditionNotify(condPtr)  Tcl_ConditionNotify(condPtr)
563      Tcl_Condition *condPtr;      Tcl_Condition *condPtr;
564  {  {
565  }  }
566    
567  #undef Tcl_MutexLock  #undef Tcl_MutexLock
568  void  void
569  Tcl_MutexLock(mutexPtr)  Tcl_MutexLock(mutexPtr)
570      Tcl_Mutex *mutexPtr;      Tcl_Mutex *mutexPtr;
571  {  {
572  }  }
573    
574  #undef Tcl_MutexUnlock  #undef Tcl_MutexUnlock
575  void  void
576  Tcl_MutexUnlock(mutexPtr)  Tcl_MutexUnlock(mutexPtr)
577      Tcl_Mutex *mutexPtr;      Tcl_Mutex *mutexPtr;
578  {  {
579  }  }
580  #endif  #endif
581    
582  /* End of tclthread.c */  /* End of tclthread.c */

Legend:
Removed from v.67  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25