~ubuntu-branches/ubuntu/lucid/hdf-eos5/lucid

« back to all changes in this revision

Viewing changes to src/TSapi.c

  • Committer: Bazaar Package Importer
  • Author(s): Alastair McKinstry
  • Date: 2009-08-17 23:07:29 UTC
  • Revision ID: james.westby@ubuntu.com-20090817230729-gzbwp1ny01hv2nlk
Tags: upstream-5.1.12.dfsg.1
ImportĀ upstreamĀ versionĀ 5.1.12.dfsg.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 ----------------------------------------------------------------------------
 
3
 |    Copyright (C) 2001 Emergent IT Inc. and Raytheon Systems Company      |
 
4
 |                                                                          | 
 
5
 |  Permission to use, modify, and distribute this software and its         |
 
6
 |  documentation for any purpose without fee is hereby granted, provided   |
 
7
 |  that the above copyright notice appear in all copies and that both that |
 
8
 |  copyright notice and this permission notice appear in supporting        |
 
9
 |                          documentation.                                  |
 
10
 ----------------------------------------------------------------------------
 
11
 */
 
12
 
 
13
#include <HE5_HdfEosDef.h>
 
14
 
 
15
#ifdef  _HDFEOS5_THREADSAFE
 
16
 
 
17
/* Global Variable definition */
 
18
/* -------------------------- */
 
19
pthread_once_t    HE5_HDFE_TS_FirstInit = PTHREAD_ONCE_INIT;
 
20
 
 
21
#endif
 
22
 
 
23
/*----------------------------------------------------------------------------
 
24
|  BEGIN_PROLOG                                                              | 
 
25
|                                                                            |
 
26
|  FUNCTION: HE5_TSinitfirst                                                 | 
 
27
|                                                                            | 
 
28
|  DESCRIPTION : This function initializes the mutex, once per run.          |
 
29
|                                                                            |
 
30
|                                                                            |
 
31
|  Return Value    Type     Units     Description                            | 
 
32
|  ============   ======  =========   =====================================  | 
 
33
|                                                                            |
 
34
|  INPUTS:   None                                                            | 
 
35
|                                                                            |
 
36
|                                                                            |
 
37
|  OUTPUTS:                                                                  | 
 
38
|                                                                            |
 
39
|             None                                                           | 
 
40
|                                                                            |
 
41
|  NOTES:                                                                    | 
 
42
|                                                                            |
 
43
|   Date      Programmer    Description                                      | 
 
44
|  ========   ============  ===============================================  | 
 
45
|  08/21/01   A.Muslimov    Original development.                            |
 
46
|  08/27/01   A.Muslimov    Added appropriate error handlings.               |
 
47
|                                                                            |
 
48
|  END_PROLOG                                                                | 
 
49
----------------------------------------------------------------------------*/
 
50
void    
 
51
HE5_TSinitfirst(void)
 
52
{
 
53
#ifdef  _HDFEOS5_THREADSAFE
 
54
 
 
55
  herr_t   status = FAIL;
 
56
  char     errbuf[HE5_HDFE_ERRBUFSIZE];
 
57
 
 
58
  /* Initialize Global Mutex Variable */
 
59
  /* -------------------------------- */
 
60
  GlobalMutex.MasterThread = (pthread_t *)NULL;
 
61
 
 
62
  /* Initialize mutex with default value */
 
63
  /* ----------------------------------- */
 
64
  status = pthread_mutex_init(&GlobalMutex.Lock, NULL);
 
65
  if (status != SUCCEED)
 
66
        {
 
67
          status = FAIL;
 
68
          sprintf(errbuf, "Failed to initialize the mutex.\n");
 
69
          H5Epush(__FILE__, "HE5_TSinitfirst", __LINE__, H5E_FUNC, H5E_BADVALUE, errbuf);
 
70
        }
 
71
 
 
72
  /* Initialize condition variable with default attribute */
 
73
  /* ---------------------------------------------------- */
 
74
  status = pthread_cond_init(&GlobalMutex.CondVar, NULL);
 
75
  if (status != SUCCEED)
 
76
        {
 
77
          status = FAIL;
 
78
          sprintf(errbuf, "Failed to initialize the condition variable.\n");
 
79
          H5Epush(__FILE__, "HE5_TSinitfirst", __LINE__, H5E_FUNC, H5E_BADVALUE, errbuf);
 
80
        }
 
81
 
 
82
  GlobalMutex.LockCount = 0;
 
83
 
 
84
#endif
 
85
}
 
86
 
 
87
 
 
88
/*----------------------------------------------------------------------------
 
89
|  BEGIN_PROLOG                                                              | 
 
90
|                                                                            |
 
91
|  FUNCTION: HE5_TSmutexlock                                                 | 
 
92
|                                                                            | 
 
93
|  DESCRIPTION : This function locks the mutex.                              |
 
94
|                                                                            |
 
95
|                                                                            |
 
96
|  Return Value    Type     Units     Description                            | 
 
97
|  ============   ======  =========   =====================================  | 
 
98
|  status         herr_t  none        Return status variable                 |
 
99
|                                                                            |
 
100
|  INPUTS:                                                                   | 
 
101
|  Mutex          struct              Input data structure                   |
 
102
|                                                                            |
 
103
|                                                                            |
 
104
|  OUTPUTS:                                                                  | 
 
105
|                                                                            |
 
106
|             None                                                           | 
 
107
|                                                                            |
 
108
|  NOTES:                                                                    | 
 
109
|                                                                            |
 
110
|   Date      Programmer    Description                                      | 
 
111
|  ========   ============  ===============================================  | 
 
112
|  08/21/01   A.Muslimov    Original development.                            |
 
113
|  08/27/01   A.Muslimov    Added appropriate error handlings.               |
 
114
|                                                                            |
 
115
|  END_PROLOG                                                                | 
 
116
----------------------------------------------------------------------------*/
 
117
herr_t   
 
118
HE5_TSmutexlock(HE5_HDFE_MutexStruct *Mutex)
 
119
{
 
120
  herr_t   status = SUCCEED;
 
121
#ifdef  _HDFEOS5_THREADSAFE
 
122
  char     errbuf[HE5_HDFE_ERRBUFSIZE];
 
123
#ifdef  _HDFEOS5_THREADSAFE_DEBUG
 
124
  time_t   lockTime;
 
125
#endif
 
126
 
 
127
  status = FAIL;
 
128
 
 
129
  /* Initialize the mutex */
 
130
  /* -------------------- */
 
131
  HE5_FIRST_THREAD_INIT
 
132
 
 
133
  /* Check the initialization */
 
134
  /* ------------------------ */
 
135
  if (status != SUCCEED)
 
136
        {
 
137
          status = FAIL;
 
138
          sprintf(errbuf, "Failed to initialize the mutex.\n");
 
139
          H5Epush(__FILE__, "HE5_TSmutexlock", __LINE__, H5E_FUNC, H5E_BADVALUE, errbuf);
 
140
          return(status);
 
141
        }       
 
142
 
 
143
#ifdef  _HDFEOS5_THREADSAFE_DEBUG
 
144
  time(&lockTime);
 
145
  printf("Attempt to lock mutex ... Time = %lf \n", (double)lockTime);
 
146
#endif
 
147
 
 
148
  /* Lock the mutex */
 
149
  /* -------------- */
 
150
  status = pthread_mutex_lock(&Mutex->Lock);
 
151
  if (status != SUCCEED)
 
152
        {
 
153
          status = FAIL;
 
154
          sprintf(errbuf, "Failed to lock the mutex.\n");
 
155
          H5Epush(__FILE__, "HE5_TSmutexlock", __LINE__, H5E_FUNC, H5E_BADVALUE, errbuf);
 
156
          return(status);
 
157
        }
 
158
  
 
159
  /* Find out if the mutex is locked and who owns the lock */
 
160
  /* ----------------------------------------------------- */
 
161
  if (Mutex->MasterThread && pthread_equal(pthread_self(), *Mutex->MasterThread)){
 
162
        /* already owned by self -- increment count */
 
163
        /* ---------------------------------------- */
 
164
        Mutex->LockCount++;
 
165
  } else if (!Mutex->MasterThread) {
 
166
        /* No one else has locked it -- set owner and get lock */
 
167
        /* --------------------------------------------------- */
 
168
        Mutex->MasterThread = (pthread_t *)malloc(sizeof(pthread_t));
 
169
        if (Mutex->MasterThread == (pthread_t *)NULL)
 
170
          {
 
171
                status = FAIL;
 
172
                sprintf(errbuf, "Cannot allocate memory for master thread ID.\n");
 
173
                H5Epush(__FILE__, "HE5_TSmutexlock", __LINE__, H5E_RESOURCE, H5E_BADRANGE, errbuf);
 
174
                return(status);
 
175
          }
 
176
 
 
177
        *Mutex->MasterThread = pthread_self();
 
178
        Mutex->LockCount = 1;
 
179
  } else {
 
180
        /* if already locked by someone else */
 
181
        /* --------------------------------- */
 
182
        for (;;) {
 
183
          status = pthread_cond_wait(&Mutex->CondVar, &Mutex->Lock);
 
184
          if (status != SUCCEED)
 
185
                {
 
186
                  status = FAIL;
 
187
                  sprintf(errbuf, "Failed to block the thread on condition variable.\n");
 
188
                  H5Epush(__FILE__, "HE5_TSmutexlock", __LINE__, H5E_FUNC, H5E_BADVALUE, errbuf);
 
189
                  return(status);
 
190
                }
 
191
 
 
192
          if (!Mutex->MasterThread) {
 
193
                Mutex->MasterThread = (pthread_t *)malloc(sizeof(pthread_t));
 
194
                if (Mutex->MasterThread == (pthread_t *)NULL)
 
195
                  {
 
196
                        status = FAIL;
 
197
                        sprintf(errbuf, "Cannot allocate memory for master thread ID.\n");
 
198
                        H5Epush(__FILE__, "HE5_TSmutexlock", __LINE__, H5E_RESOURCE, H5E_BADRANGE, errbuf);
 
199
                        return(status);
 
200
                  }             
 
201
#ifdef  _HDFEOS5_THREADSAFE_DEBUG
 
202
                time(&lockTime);
 
203
                printf("Locking mutex ... Time = %lf \n", (double)lockTime);
 
204
#endif
 
205
                *Mutex->MasterThread = pthread_self();
 
206
                Mutex->LockCount = 1;
 
207
                break;
 
208
          }
 
209
        }
 
210
  }
 
211
  
 
212
 
 
213
  /* Unlock the mutex */
 
214
  /* ---------------- */
 
215
  status = pthread_mutex_unlock(&Mutex->Lock);
 
216
  if (status != SUCCEED)
 
217
        {
 
218
          status = FAIL;
 
219
          sprintf(errbuf, "Failed to unlock the mutex.\n");
 
220
          H5Epush(__FILE__, "HE5_TSmutexlock", __LINE__, H5E_FUNC, H5E_BADVALUE, errbuf);
 
221
        }
 
222
#ifdef  _HDFEOS5_THREADSAFE_DEBUG
 
223
  time(&lockTime);
 
224
  printf("Locking mutex ... Time = %lf \n", (double)lockTime);
 
225
#endif
 
226
#endif
 
227
  return(status);
 
228
}
 
229
 
 
230
 
 
231
 
 
232
/*----------------------------------------------------------------------------
 
233
|  BEGIN_PROLOG                                                              | 
 
234
|                                                                            |
 
235
|  FUNCTION: HE5_TSmutexunlock                                               | 
 
236
|                                                                            | 
 
237
|  DESCRIPTION : This function unlocks the mutex.                            |
 
238
|                                                                            |
 
239
|                                                                            |
 
240
|  Return Value    Type     Units     Description                            | 
 
241
|  ============   ======  =========   =====================================  |
 
242
|  status         herr_t              Return status variable                 |
 
243
|                                                                            |
 
244
|  INPUTS:                                                                   | 
 
245
|  Mutex          struct              data structure                         |
 
246
|                                                                            |
 
247
|                                                                            |
 
248
|  OUTPUTS:                                                                  | 
 
249
|                                                                            |
 
250
|             None                                                           | 
 
251
|                                                                            |
 
252
|  NOTES:                                                                    | 
 
253
|                                                                            |
 
254
|   Date      Programmer    Description                                      | 
 
255
|  ========   ============  ===============================================  | 
 
256
|  08/21/01   A.Muslimov    Original development.                            |
 
257
|  08/27/01   A.Muslimov    Added appropriate error handlings.               |
 
258
|                                                                            |
 
259
|  END_PROLOG                                                                | 
 
260
----------------------------------------------------------------------------*/
 
261
herr_t   
 
262
HE5_TSmutexunlock(HE5_HDFE_MutexStruct *Mutex)
 
263
{
 
264
  herr_t   status = SUCCEED;
 
265
#ifdef  _HDFEOS5_THREADSAFE
 
266
  char     errbuf[HE5_HDFE_ERRBUFSIZE];
 
267
#ifdef  _HDFEOS5_THREADSAFE_DEBUG
 
268
  time_t   unlockTime;
 
269
#endif  
 
270
 
 
271
  status = FAIL;
 
272
 
 
273
  /* Lock the mutex */
 
274
  /* -------------- */
 
275
  status = pthread_mutex_lock(&Mutex->Lock);
 
276
  if (status != SUCCEED)
 
277
        {
 
278
          status = FAIL;
 
279
          sprintf(errbuf, "Failed to unlock the mutex.\n");
 
280
          H5Epush(__FILE__, "HE5_TSmutexunlock", __LINE__, H5E_FUNC, H5E_BADVALUE, errbuf);
 
281
          return(status);
 
282
        }
 
283
  Mutex->LockCount--;
 
284
  
 
285
  if (Mutex->LockCount == 0)
 
286
        {
 
287
          free(Mutex->MasterThread);
 
288
          Mutex->MasterThread = NULL;
 
289
          status = pthread_cond_signal(&Mutex->CondVar);
 
290
          if (status != SUCCEED)
 
291
                {
 
292
                  status = FAIL;
 
293
                  sprintf(errbuf, "Failed to unblock the thread blocked on a condition variable.\n");
 
294
                  H5Epush(__FILE__, "HE5_TSmutexunlock", __LINE__, H5E_FUNC, H5E_BADVALUE, errbuf);
 
295
                  return(status);
 
296
                }
 
297
        }
 
298
 
 
299
  /* Unlock the mutex */
 
300
  /* ---------------- */
 
301
  status = pthread_mutex_unlock(&Mutex->Lock);
 
302
  if (status != SUCCEED)
 
303
        {
 
304
          status = FAIL;
 
305
          sprintf(errbuf, "Failed to unlock the mutex.\n");
 
306
          H5Epush(__FILE__, "HE5_TSmutexunlock", __LINE__, H5E_FUNC, H5E_BADVALUE, errbuf);
 
307
        }
 
308
#ifdef  _HDFEOS5_THREADSAFE_DEBUG
 
309
  time(&unlockTime);
 
310
  printf("Unlocking mutex ... Time = %lf \n", (double)unlockTime);
 
311
#endif
 
312
#endif
 
313
  return(status);
 
314
}
 
315
 
 
316
 
 
317
 
 
318
 
 
319
 
 
320
 
 
321
 
 
322
 
 
323
 
 
324
 
 
325
 
 
326
 
 
327
 
 
328
 
 
329
 
 
330
 
 
331
 
 
332
 
 
333
 
 
334
 
 
335
 
 
336
 
 
337
 
 
338
 
 
339
 
 
340