~ubuntu-branches/ubuntu/lucid/seamonkey/lucid-security

« back to all changes in this revision

Viewing changes to security/nss-fips/lib/util/nssilock.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabien Tassin
  • Date: 2008-07-29 21:29:02 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080729212902-spm9kpvchp9udwbw
Tags: 1.1.11+nobinonly-0ubuntu1
* New security upstream release: 1.1.11 (LP: #218534)
  Fixes USN-602-1, USN-619-1, USN-623-1 and USN-629-1
* Refresh diverged patch:
  - update debian/patches/80_security_build.patch
* Fix FTBFS with missing -lfontconfig
  - add debian/patches/11_fix_ftbfs_with_fontconfig.patch
  - update debian/patches/series
* Build with default gcc (hardy: 4.2, intrepid: 4.3)
  - update debian/rules
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
3
 *
 
4
 * The contents of this file are subject to the Mozilla Public License Version
 
5
 * 1.1 (the "License"); you may not use this file except in compliance with
 
6
 * the License. You may obtain a copy of the License at
 
7
 * http://www.mozilla.org/MPL/
 
8
 *
 
9
 * Software distributed under the License is distributed on an "AS IS" basis,
 
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
11
 * for the specific language governing rights and limitations under the
 
12
 * License.
 
13
 *
 
14
 * The Original Code is the Netscape security libraries.
 
15
 *
 
16
 * The Initial Developer of the Original Code is
 
17
 * Netscape Communications Corporation.
 
18
 * Portions created by the Initial Developer are Copyright (C) 1994-2000
 
19
 * the Initial Developer. All Rights Reserved.
 
20
 *
 
21
 * Contributor(s):
 
22
 *
 
23
 * Alternatively, the contents of this file may be used under the terms of
 
24
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
25
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
26
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
27
 * of those above. If you wish to allow use of your version of this file only
 
28
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
29
 * use your version of this file under the terms of the MPL, indicate your
 
30
 * decision by deleting the provisions above and replace them with the notice
 
31
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
32
 * the provisions above, a recipient may use your version of this file under
 
33
 * the terms of any one of the MPL, the GPL or the LGPL.
 
34
 *
 
35
 * ***** END LICENSE BLOCK ***** */
 
36
 
 
37
/*
 
38
 * nssilock.c - NSS lock instrumentation wrapper functions
 
39
 *
 
40
 * NOTE - These are not public interfaces
 
41
 *
 
42
 * Implementation Notes:
 
43
 * I've tried to make the instrumentation relatively non-intrusive.
 
44
 * To do this, I have used a single PR_LOG() call in each
 
45
 * instrumented function. There's room for improvement.
 
46
 *
 
47
 *
 
48
 */
 
49
 
 
50
#include "prinit.h"
 
51
#include "prerror.h"
 
52
#include "prlock.h"
 
53
#include "prmem.h"
 
54
#include "prenv.h"
 
55
#include "prcvar.h"
 
56
#include "prio.h"
 
57
 
 
58
#if defined(NEED_NSS_ILOCK)
 
59
#include "prlog.h"
 
60
#include "nssilock.h"
 
61
 
 
62
/*
 
63
** Declare the instrumented PZLock 
 
64
*/
 
65
struct pzlock_s {
 
66
    PRLock *lock;  /* the PZLock to be instrumented */
 
67
    PRIntervalTime time; /* timestamp when the lock was aquired */
 
68
    nssILockType ltype;
 
69
};
 
70
 
 
71
/*
 
72
** Declare the instrumented PZMonitor 
 
73
*/
 
74
struct pzmonitor_s {
 
75
    PRMonitor *mon;   /* the PZMonitor to be instrumented */
 
76
    PRIntervalTime time; /* timestamp when the monitor was aquired */
 
77
    nssILockType ltype;
 
78
};
 
79
 
 
80
/*
 
81
** Declare the instrumented PZCondVar
 
82
*/
 
83
struct pzcondvar_s  {
 
84
    PRCondVar   *cvar;  /* the PZCondVar to be instrumented */
 
85
    nssILockType ltype;
 
86
};
 
87
 
 
88
 
 
89
/*
 
90
** Define a CallOnce type to ensure serialized self-initialization
 
91
*/
 
92
static PRCallOnceType coNssILock;     /* CallOnce type */
 
93
static PRIntn  nssILockInitialized;   /* initialization done when 1 */
 
94
static PRLogModuleInfo *nssILog;      /* Log instrumentation to this handle */
 
95
 
 
96
 
 
97
#define NUM_TT_ENTRIES 6000000
 
98
static PRInt32  traceIndex = -1;      /* index into trace table */
 
99
static struct pzTrace_s *tt;          /* pointer to trace table */
 
100
static PRInt32  ttBufSize = (NUM_TT_ENTRIES * sizeof(struct pzTrace_s ));
 
101
static PRCondVar *ttCVar;
 
102
static PRLock    *ttLock;
 
103
static PRFileDesc *ttfd;              /* trace table file */
 
104
 
 
105
/*
 
106
** Vtrace() -- Trace events, write events to external media
 
107
**
 
108
** Vtrace() records traced events in an in-memory trace table
 
109
** when the trace table fills, Vtrace writes the entire table
 
110
** to a file.
 
111
**
 
112
** data can be lost!
 
113
**
 
114
*/
 
115
static void Vtrace(
 
116
    nssILockOp      op,
 
117
    nssILockType    ltype,
 
118
    PRIntervalTime  callTime,
 
119
    PRIntervalTime  heldTime,
 
120
    void            *lock,
 
121
    PRIntn          line,
 
122
    char            *file
 
123
)  {
 
124
    PRInt32 idx;
 
125
    struct pzTrace_s *tp;
 
126
 
 
127
RetryTrace:
 
128
    idx = PR_AtomicIncrement( &traceIndex );
 
129
    while( NUM_TT_ENTRIES <= idx || op == FlushTT ) {
 
130
        if( NUM_TT_ENTRIES == idx  || op == FlushTT )  {
 
131
            int writeSize = idx * sizeof(struct pzTrace_s);
 
132
            PR_Lock(ttLock);
 
133
            PR_Write( ttfd, tt, writeSize );
 
134
            traceIndex = -1;
 
135
            PR_NotifyAllCondVar( ttCVar );
 
136
            PR_Unlock(ttLock);
 
137
            goto RetryTrace;
 
138
        } else {
 
139
            PR_Lock(ttLock);
 
140
            while( NUM_TT_ENTRIES < idx )
 
141
                PR_WaitCondVar(ttCVar, PR_INTERVAL_NO_WAIT);
 
142
            PR_Unlock(ttLock);
 
143
            goto RetryTrace;
 
144
        }
 
145
    } /* end while() */
 
146
 
 
147
    /* create the trace entry */
 
148
    tp = tt + idx;
 
149
    tp->threadID = PR_GetThreadID(PR_GetCurrentThread());
 
150
    tp->op = op;
 
151
    tp->ltype = ltype;
 
152
    tp->callTime = callTime;
 
153
    tp->heldTime = heldTime;
 
154
    tp->lock = lock;
 
155
    tp ->line = line;
 
156
    strcpy(tp->file, file );
 
157
    return;
 
158
} /* --- end Vtrace() --- */
 
159
 
 
160
/*
 
161
** pz_TraceFlush() -- Force trace table write to file
 
162
**
 
163
*/
 
164
extern void pz_TraceFlush( void )
 
165
{
 
166
    Vtrace( FlushTT, nssILockSelfServ, 0, 0, NULL, 0, "" );
 
167
    return;
 
168
} /* --- end pz_TraceFlush() --- */
 
169
 
 
170
/*
 
171
** nssILockInit() -- Initialization for nssilock
 
172
**
 
173
** This function is called from the CallOnce mechanism.
 
174
*/
 
175
static PRStatus
 
176
    nssILockInit( void ) 
 
177
{   
 
178
    int i;
 
179
    nssILockInitialized = 1;
 
180
 
 
181
    /* new log module */
 
182
    nssILog = PR_NewLogModule("nssilock");
 
183
    if ( NULL == nssILog )  {
 
184
        return(PR_FAILURE);
 
185
    }
 
186
 
 
187
    tt = PR_Calloc( NUM_TT_ENTRIES, sizeof(struct pzTrace_s));
 
188
    if (NULL == tt ) {
 
189
        fprintf(stderr, "nssilock: can't allocate trace table\n");
 
190
        exit(1);
 
191
    }
 
192
 
 
193
    ttfd = PR_Open( "xxxTTLog", PR_CREATE_FILE | PR_WRONLY, 0666 );
 
194
    if ( NULL == ttfd )  {
 
195
        fprintf( stderr, "Oh Drat! Can't open 'xxxTTLog'\n");
 
196
        exit(1);
 
197
    }
 
198
 
 
199
    ttLock = PR_NewLock();
 
200
    ttCVar = PR_NewCondVar(ttLock);
 
201
 
 
202
    return(PR_SUCCESS);
 
203
} /* --- end nssILockInit() --- */
 
204
 
 
205
extern PZLock * pz_NewLock( 
 
206
    nssILockType ltype,
 
207
    char *file,  
 
208
    PRIntn line )
 
209
{
 
210
    PRStatus rc;
 
211
    PZLock  *lock;
 
212
    
 
213
    /* Self Initialize the nssILock feature */
 
214
    if (!nssILockInitialized)  {
 
215
        rc = PR_CallOnce( &coNssILock, nssILockInit );
 
216
        if ( PR_FAILURE == rc ) {
 
217
            PR_SetError( PR_UNKNOWN_ERROR, 0 );
 
218
            return( NULL );
 
219
        }
 
220
    }
 
221
 
 
222
    lock = PR_NEWZAP( PZLock );
 
223
    if ( NULL != lock )  {
 
224
        lock->lock = PR_NewLock();
 
225
        if ( NULL == lock->lock )  {
 
226
            PR_DELETE( lock );
 
227
            lock = NULL;
 
228
        }
 
229
    }
 
230
    lock->ltype = ltype;
 
231
 
 
232
    Vtrace( NewLock, ltype, 0, 0, lock, line, file );
 
233
    return(lock);
 
234
} /* --- end pz_NewLock() --- */
 
235
 
 
236
extern void
 
237
    pz_Lock(
 
238
        PZLock *lock,
 
239
        char *file,
 
240
        PRIntn line
 
241
    )
 
242
{            
 
243
    PRIntervalTime callTime;
 
244
 
 
245
    callTime = PR_IntervalNow();
 
246
    PR_Lock( lock->lock );
 
247
    lock->time = PR_IntervalNow();
 
248
    callTime = lock->time - callTime;
 
249
 
 
250
    Vtrace( Lock, lock->ltype, callTime, 0, lock, line, file );
 
251
    return;
 
252
} /* --- end  pz_Lock() --- */
 
253
 
 
254
extern PRStatus
 
255
    pz_Unlock(
 
256
        PZLock *lock,
 
257
        char *file,
 
258
        PRIntn line
 
259
    ) 
 
260
{
 
261
    PRStatus rc;
 
262
    PRIntervalTime callTime, now, heldTime;
 
263
 
 
264
    callTime = PR_IntervalNow();
 
265
    rc = PR_Unlock( lock->lock );
 
266
    now = PR_IntervalNow(); 
 
267
    callTime = now - callTime;
 
268
    heldTime = now - lock->time;
 
269
    Vtrace( Unlock, lock->ltype, callTime, heldTime, lock, line, file );
 
270
    return( rc );
 
271
} /* --- end  pz_Unlock() --- */
 
272
 
 
273
extern void
 
274
    pz_DestroyLock(
 
275
        PZLock *lock,
 
276
        char *file,
 
277
        PRIntn line
 
278
    )
 
279
{
 
280
    Vtrace( DestroyLock, lock->ltype, 0, 0, lock, line, file );
 
281
    PR_DestroyLock( lock->lock );
 
282
    PR_DELETE( lock );
 
283
    return;
 
284
} /* --- end  pz_DestroyLock() --- */
 
285
 
 
286
 
 
287
 
 
288
extern PZCondVar *
 
289
    pz_NewCondVar(
 
290
        PZLock *lock,
 
291
        char *file,
 
292
        PRIntn line
 
293
    )
 
294
{
 
295
    PZCondVar *cvar;
 
296
 
 
297
    cvar = PR_NEWZAP( PZCondVar );
 
298
    if ( NULL == cvar ) return(NULL);
 
299
   
 
300
    cvar->ltype = lock->ltype; 
 
301
    cvar->cvar = PR_NewCondVar( lock->lock );
 
302
    if ( NULL == cvar->cvar )  {
 
303
        PR_DELETE( cvar );
 
304
    }
 
305
    Vtrace( NewCondVar, cvar->ltype, 0, 0, cvar, line, file );
 
306
    return( cvar );
 
307
} /* --- end  pz_NewCondVar() --- */
 
308
 
 
309
extern void
 
310
    pz_DestroyCondVar(
 
311
        PZCondVar *cvar,
 
312
        char *file,
 
313
        PRIntn line
 
314
    )
 
315
{
 
316
    Vtrace( DestroyCondVar, cvar->ltype, 0, 0, cvar, line, file );
 
317
    PR_DestroyCondVar( cvar->cvar );
 
318
    PR_DELETE( cvar );
 
319
} /* --- end  pz_DestroyCondVar() --- */
 
320
 
 
321
extern PRStatus
 
322
    pz_WaitCondVar(
 
323
        PZCondVar *cvar,
 
324
        PRIntervalTime timeout,
 
325
        char *file,
 
326
        PRIntn line
 
327
    )
 
328
{
 
329
    PRStatus    rc;
 
330
    PRIntervalTime callTime;
 
331
 
 
332
    callTime = PR_IntervalNow();
 
333
    rc = PR_WaitCondVar( cvar->cvar, timeout );
 
334
    callTime = PR_IntervalNow() - callTime;
 
335
    
 
336
    Vtrace( WaitCondVar, cvar->ltype, callTime, 0, cvar, line, file );
 
337
    return(rc);
 
338
} /* --- end  pz_WaitCondVar() --- */
 
339
 
 
340
extern PRStatus
 
341
    pz_NotifyCondVar(
 
342
        PZCondVar *cvar,
 
343
        char *file,
 
344
        PRIntn line
 
345
    )
 
346
{
 
347
    PRStatus    rc;
 
348
    
 
349
    rc = PR_NotifyCondVar( cvar->cvar );
 
350
    
 
351
    Vtrace( NotifyCondVar, cvar->ltype, 0, 0, cvar, line, file );
 
352
    return(rc);
 
353
} /* --- end  pz_NotifyCondVar() --- */
 
354
 
 
355
extern PRStatus
 
356
    pz_NotifyAllCondVar(
 
357
        PZCondVar *cvar,
 
358
        char *file,
 
359
        PRIntn line
 
360
    )
 
361
{
 
362
    PRStatus    rc;
 
363
    
 
364
    rc = PR_NotifyAllCondVar( cvar->cvar );
 
365
    
 
366
    Vtrace( NotifyAllCondVar, cvar->ltype, 0, 0, cvar, line, file );
 
367
    return(rc);
 
368
} /* --- end  pz_NotifyAllCondVar() --- */
 
369
 
 
370
extern PZMonitor *
 
371
    pz_NewMonitor( 
 
372
        nssILockType ltype,
 
373
        char *file,
 
374
        PRIntn line
 
375
    )
 
376
{
 
377
    PRStatus rc;
 
378
    PZMonitor   *mon;
 
379
 
 
380
    /* Self Initialize the nssILock feature */
 
381
    if (!nssILockInitialized)  {
 
382
        rc = PR_CallOnce( &coNssILock, nssILockInit );
 
383
        if ( PR_FAILURE == rc ) {
 
384
            PR_SetError( PR_UNKNOWN_ERROR, 0 );
 
385
            return( NULL );
 
386
        }
 
387
    }
 
388
 
 
389
    mon = PR_NEWZAP( PZMonitor );
 
390
    if ( NULL != mon )  {
 
391
        mon->mon = PR_NewMonitor();
 
392
        if ( NULL == mon->mon )  {
 
393
            PR_DELETE( mon );
 
394
            return NULL;
 
395
        }
 
396
    }
 
397
    mon->ltype = ltype;
 
398
 
 
399
    Vtrace( NewMonitor, mon->ltype, 0, 0, mon, line, file );
 
400
    return(mon);
 
401
} /* --- end  pz_NewMonitor() --- */
 
402
 
 
403
extern void
 
404
    pz_DestroyMonitor(
 
405
        PZMonitor *mon,
 
406
        char *file,
 
407
        PRIntn line
 
408
    )
 
409
{
 
410
    Vtrace( DestroyMonitor, mon->ltype, 0, 0, mon, line, file );
 
411
    PR_DestroyMonitor( mon->mon );
 
412
    PR_DELETE( mon );
 
413
    return;                
 
414
} /* --- end  pz_DestroyMonitor() --- */
 
415
 
 
416
extern void
 
417
    pz_EnterMonitor(
 
418
        PZMonitor *mon,
 
419
        char *file,
 
420
        PRIntn line
 
421
    )
 
422
{
 
423
    PRIntervalTime callTime, now;
 
424
 
 
425
    callTime = PR_IntervalNow();
 
426
    PR_EnterMonitor( mon->mon );
 
427
    now = PR_IntervalNow();
 
428
    callTime = now - callTime;
 
429
    if ( PR_GetMonitorEntryCount(mon->mon) == 1 )  {
 
430
        mon->time = now;
 
431
    }
 
432
    Vtrace( EnterMonitor, mon->ltype, callTime, 0, mon, line, file );
 
433
    return;
 
434
} /* --- end  pz_EnterMonitor() --- */
 
435
 
 
436
extern PRStatus
 
437
    pz_ExitMonitor(
 
438
        PZMonitor *mon,
 
439
        char *file,
 
440
        PRIntn line
 
441
    )
 
442
{
 
443
    PRStatus rc;
 
444
    PRIntervalTime callTime, now, heldTime;
 
445
    PRIntn  mec = PR_GetMonitorEntryCount( mon->mon );
 
446
   
 
447
    heldTime = (PRIntervalTime)-1; 
 
448
    callTime = PR_IntervalNow();
 
449
    rc = PR_ExitMonitor( mon->mon );
 
450
    now = PR_IntervalNow();
 
451
    callTime = now - callTime;
 
452
    if ( mec == 1 )
 
453
        heldTime = now - mon->time;
 
454
    Vtrace( ExitMonitor, mon->ltype, callTime, heldTime, mon, line, file );
 
455
    return( rc );
 
456
} /* --- end  pz_ExitMonitor() --- */
 
457
 
 
458
extern PRIntn
 
459
    pz_GetMonitorEntryCount(
 
460
        PZMonitor *mon,
 
461
        char *file,
 
462
        PRIntn line
 
463
    )
 
464
{
 
465
    return( PR_GetMonitorEntryCount(mon->mon));
 
466
} /* --- end pz_GetMonitorEntryCount() --- */
 
467
 
 
468
 
 
469
extern PRStatus
 
470
    pz_Wait(
 
471
        PZMonitor *mon,
 
472
        PRIntervalTime ticks,
 
473
        char *file,
 
474
        PRIntn line
 
475
    )
 
476
{
 
477
    PRStatus rc;
 
478
    PRIntervalTime callTime;
 
479
 
 
480
    callTime = PR_IntervalNow();
 
481
    rc = PR_Wait( mon->mon, ticks );
 
482
    callTime = PR_IntervalNow() - callTime;
 
483
    Vtrace( Wait, mon->ltype, callTime, 0, mon, line, file );
 
484
    return( rc );
 
485
} /* --- end  pz_Wait() --- */
 
486
 
 
487
extern PRStatus
 
488
    pz_Notify(
 
489
        PZMonitor *mon,
 
490
        char *file,
 
491
        PRIntn line
 
492
    )
 
493
{
 
494
    PRStatus rc;
 
495
    PRIntervalTime callTime;
 
496
 
 
497
    callTime = PR_IntervalNow();
 
498
    rc = PR_Notify( mon->mon );
 
499
    callTime = PR_IntervalNow() - callTime;
 
500
    Vtrace( Notify, mon->ltype, callTime, 0, mon, line, file );
 
501
    return( rc );
 
502
} /* --- end  pz_Notify() --- */
 
503
 
 
504
extern PRStatus
 
505
    pz_NotifyAll(
 
506
        PZMonitor *mon,
 
507
        char *file,
 
508
        PRIntn line
 
509
    )
 
510
{
 
511
    PRStatus rc;
 
512
    PRIntervalTime callTime;
 
513
 
 
514
    callTime = PR_IntervalNow();
 
515
    rc = PR_NotifyAll( mon->mon );
 
516
    callTime = PR_IntervalNow() - callTime;
 
517
    Vtrace( NotifyAll, mon->ltype, callTime, 0, mon, line, file );
 
518
    return( rc );
 
519
} /* --- end  pz_NotifyAll() --- */
 
520
 
 
521
#endif /* NEED_NSS_ILOCK */
 
522
/* --- end nssilock.c --------------------------------- */