/[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

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

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

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25