~ubuntu-branches/ubuntu/saucy/nspr/saucy-updates

« back to all changes in this revision

Viewing changes to mozilla/nsprpub/pr/src/md/mac/mdcriticalregion.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2009-08-10 11:34:26 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090810113426-3uv4diflrkcbdimm
Tags: 4.8-0ubuntu1
* New upstream release: 4.8 (LP: #387812)
* adjust patches to changed upstreanm codebase
  - update debian/patches/99_configure.patch
* update shlibs symbols to include new API elements
  - update debian/libnspr4-0d.symbols

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: NULL; c-basic-offset: 2 -*- */
2
 
/* ***** BEGIN LICENSE BLOCK *****
3
 
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
 
 *
5
 
 * The contents of this file are subject to the Mozilla Public License Version
6
 
 * 1.1 (the "License"); you may not use this file except in compliance with
7
 
 * the License. You may obtain a copy of the License at
8
 
 * http://www.mozilla.org/MPL/
9
 
 *
10
 
 * Software distributed under the License is distributed on an "AS IS" basis,
11
 
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
 
 * for the specific language governing rights and limitations under the
13
 
 * License.
14
 
 *
15
 
 * The Original Code is the Netscape Portable Runtime (NSPR).
16
 
 *
17
 
 * The Initial Developer of the Original Code is
18
 
 * Netscape Communications Corporation.
19
 
 * Portions created by the Initial Developer are Copyright (C) 1998-2000
20
 
 * the Initial Developer. All Rights Reserved.
21
 
 *
22
 
 * Contributor(s):
23
 
 *   George Warner, Apple Computer Inc.
24
 
 *   Simon Fraser  <sfraser@netscape.com>
25
 
 *
26
 
 * Alternatively, the contents of this file may be used under the terms of
27
 
 * either the GNU General Public License Version 2 or later (the "GPL"), or
28
 
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
 
 * in which case the provisions of the GPL or the LGPL are applicable instead
30
 
 * of those above. If you wish to allow use of your version of this file only
31
 
 * under the terms of either the GPL or the LGPL, and not to allow others to
32
 
 * use your version of this file under the terms of the MPL, indicate your
33
 
 * decision by deleting the provisions above and replace them with the notice
34
 
 * and other provisions required by the GPL or the LGPL. If you do not delete
35
 
 * the provisions above, a recipient may use your version of this file under
36
 
 * the terms of any one of the MPL, the GPL or the LGPL.
37
 
 *
38
 
 * ***** END LICENSE BLOCK ***** */
39
 
 
40
 
#include "mdcriticalregion.h"
41
 
#include <MacErrors.h>
42
 
 
43
 
/*
44
 
  This code is a replacement for MPEnterCriticalRegion/MPLeaveCriticalRegion,
45
 
  which is broken on Mac OS 10.0.x builds, but fixed in 10.1. This code works
46
 
  everywhere.
47
 
*/
48
 
 
49
 
 
50
 
typedef struct MDCriticalRegionData_struct {
51
 
  MPTaskID        mMPTaskID;          /* Who's in the critical region? */
52
 
  UInt32          mDepthCount;        /* How deep? */
53
 
  MPSemaphoreID   mMPSemaphoreID;     /* ready semaphore */
54
 
} MDCriticalRegionData, *MDCriticalRegionDataPtr;
55
 
 
56
 
 
57
 
OSStatus
58
 
MD_CriticalRegionCreate(MDCriticalRegionID * outCriticalRegionID)
59
 
{
60
 
  MDCriticalRegionDataPtr newCriticalRegionPtr;
61
 
  MPSemaphoreID           mpSemaphoreID;
62
 
  OSStatus                err = noErr;
63
 
 
64
 
  if (outCriticalRegionID == NULL)
65
 
    return paramErr;
66
 
 
67
 
  *outCriticalRegionID = NULL;
68
 
 
69
 
  newCriticalRegionPtr = (MDCriticalRegionDataPtr)MPAllocateAligned(sizeof(MDCriticalRegionData),
70
 
                        kMPAllocateDefaultAligned, kMPAllocateClearMask);
71
 
  if (newCriticalRegionPtr == NULL)
72
 
    return memFullErr;
73
 
 
74
 
  // Note: this semaphore is pre-fired (ready!)
75
 
  err = MPCreateBinarySemaphore(&mpSemaphoreID);
76
 
  if (err == noErr)
77
 
  {
78
 
    newCriticalRegionPtr->mMPTaskID = kInvalidID;
79
 
    newCriticalRegionPtr->mDepthCount = 0;
80
 
    newCriticalRegionPtr->mMPSemaphoreID = mpSemaphoreID;
81
 
 
82
 
    *outCriticalRegionID = (MDCriticalRegionID)newCriticalRegionPtr;
83
 
  }
84
 
  else
85
 
  {
86
 
    MPFree((LogicalAddress)newCriticalRegionPtr);
87
 
  }
88
 
 
89
 
  return err;
90
 
}
91
 
 
92
 
OSStatus
93
 
MD_CriticalRegionDelete(MDCriticalRegionID inCriticalRegionID)
94
 
{
95
 
  MDCriticalRegionDataPtr criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
96
 
  OSStatus                err = noErr;
97
 
 
98
 
  if (criticalRegion == NULL)
99
 
    return paramErr;
100
 
 
101
 
  if ((criticalRegion->mMPTaskID != kInvalidID) && (criticalRegion->mDepthCount > 0))
102
 
    return kMPInsufficientResourcesErr;
103
 
 
104
 
  if (criticalRegion->mMPSemaphoreID != kInvalidID)
105
 
    err = MPDeleteSemaphore(criticalRegion->mMPSemaphoreID);
106
 
  if (noErr != err) return err;
107
 
 
108
 
  criticalRegion->mMPSemaphoreID = kInvalidID;
109
 
  MPFree((LogicalAddress) criticalRegion);
110
 
 
111
 
  return noErr;
112
 
}
113
 
 
114
 
OSStatus
115
 
MD_CriticalRegionEnter(MDCriticalRegionID inCriticalRegionID, Duration inTimeout)
116
 
{
117
 
  MDCriticalRegionDataPtr criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
118
 
  MPTaskID                currentTaskID = MPCurrentTaskID();
119
 
  OSStatus                err = noErr;
120
 
 
121
 
  if (criticalRegion == NULL)
122
 
    return paramErr;
123
 
 
124
 
  // if I'm inside the critical region...
125
 
  if (currentTaskID == criticalRegion->mMPTaskID)
126
 
  {
127
 
    // bump my depth
128
 
    criticalRegion->mDepthCount++;
129
 
    // and continue
130
 
    return noErr;
131
 
  }
132
 
 
133
 
  // wait for the ready semaphore
134
 
  err = MPWaitOnSemaphore(criticalRegion->mMPSemaphoreID, inTimeout);
135
 
  // we didn't get it. return the error
136
 
  if (noErr != err) return err;
137
 
 
138
 
  // we got it!
139
 
  criticalRegion->mMPTaskID = currentTaskID;
140
 
  criticalRegion->mDepthCount = 1;
141
 
 
142
 
  return noErr;
143
 
}
144
 
 
145
 
OSStatus
146
 
MD_CriticalRegionExit(MDCriticalRegionID inCriticalRegionID)
147
 
{
148
 
  MDCriticalRegionDataPtr   criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
149
 
  MPTaskID                  currentTaskID = MPCurrentTaskID();
150
 
  OSStatus                  err = noErr;
151
 
 
152
 
  // if we don't own the critical region...
153
 
  if (currentTaskID != criticalRegion->mMPTaskID)
154
 
    return kMPInsufficientResourcesErr;
155
 
 
156
 
  // if we aren't at a depth...
157
 
  if (criticalRegion->mDepthCount == 0)
158
 
    return kMPInsufficientResourcesErr;
159
 
 
160
 
  // un-bump my depth
161
 
  criticalRegion->mDepthCount--;
162
 
 
163
 
  // if we just bottomed out...
164
 
  if (criticalRegion->mDepthCount == 0)
165
 
  {
166
 
    // release ownership of the structure
167
 
    criticalRegion->mMPTaskID = kInvalidID;
168
 
    // and signal the ready semaphore
169
 
    err = MPSignalSemaphore(criticalRegion->mMPSemaphoreID);
170
 
  }
171
 
  return err;
172
 
}
173