1 karl 1.9 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.1 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.9 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.1 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.9 //
|
21 mike 1.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
|
34 mike 1.10 #include "Network.h"
35
|
36 mike 1.8 #if defined(PEGASUS_OS_SOLARIS)
37 # include <sys/types.h>
38 # include <unistd.h>
39 #endif
40
|
41 mike 1.1 #include "SpinLock.h"
|
42 mike 1.2
|
43 gs.keenan 1.6 #if !defined(PEGASUS_OS_VMS) && !defined(PEGASUS_OS_TYPE_WINDOWS)
|
44 mike 1.3 # define PEGASUS_SPINLOCK_USE_PTHREADS
45 #endif
46
|
47 mike 1.2 #ifdef PEGASUS_SPINLOCK_USE_PTHREADS
48 # include <pthread.h>
49 #else
|
50 mike 1.11 # include "Mutex.h"
|
51 mike 1.2 #endif
|
52 mike 1.1
53 PEGASUS_NAMESPACE_BEGIN
54
|
55 kumpf 1.5 SpinLock spinLockPool[PEGASUS_NUM_SHARED_SPIN_LOCKS];
56 int spinLockPoolInitialized;
|
57 mike 1.1
|
58 mike 1.2 #ifdef PEGASUS_SPINLOCK_USE_PTHREADS
59 pthread_mutex_t _spinLockInitMutex = PTHREAD_MUTEX_INITIALIZER;
60 #else
|
61 mike 1.1 static Mutex _spinLockInitMutex;
|
62 mike 1.2 #endif
|
63 mike 1.1
|
64 kumpf 1.5 void SpinLockCreatePool()
|
65 mike 1.1 {
|
66 kumpf 1.5 // There's no need to check spinLockPoolInitialized before locking the
67 // mutex, because the caller can check the flag before calling this
68 // function.
|
69 mike 1.1
|
70 mike 1.2 #ifdef PEGASUS_SPINLOCK_USE_PTHREADS
|
71 kumpf 1.5 pthread_mutex_lock(&_spinLockInitMutex);
|
72 mike 1.2 #else
|
73 mike 1.11 _spinLockInitMutex.lock();
|
74 mike 1.2 #endif
|
75 mike 1.1
|
76 kumpf 1.5 if (spinLockPoolInitialized == 0)
77 {
78 for (size_t i = 0; i < PEGASUS_NUM_SHARED_SPIN_LOCKS; i++)
79 SpinLockCreate(spinLockPool[i]);
80
81 spinLockPoolInitialized = 1;
82 }
|
83 mike 1.1
|
84 mike 1.2 #ifdef PEGASUS_SPINLOCK_USE_PTHREADS
|
85 kumpf 1.5 pthread_mutex_unlock(&_spinLockInitMutex);
|
86 mike 1.2 #else
|
87 kumpf 1.5 _spinLockInitMutex.unlock();
|
88 mike 1.2 #endif
|
89 kumpf 1.5 }
90
91 #if defined(PEGASUS_SPINLOCK_USE_PTHREADS)
92
93 // This function is called prior to forking. We must obtain a lock
94 // on every mutex that the child will inherit. These will remain locked
95 // until they are unlocked (by _unlockSpinLockPool()). This prevents a
96 // child process from waiting indefinitely on a mutex that was locked by
97 // another thread in the parent process during the fork.
98
|
99 mike 1.8 extern "C" void _lockSpinLockPool()
|
100 kumpf 1.5 {
101 // Initialize the spinlock pool if not already done.
102
103 if (spinLockPoolInitialized == 0)
104 SpinLockCreatePool();
105
106 pthread_mutex_lock(&_spinLockInitMutex);
107
108 for (size_t i = 0; i < PEGASUS_NUM_SHARED_SPIN_LOCKS; i++)
109 SpinLockLock(spinLockPool[i]);
110 }
111
112 // This function is called after forking. It unlocks the mutexes that
113 // were locked by _lockSpinLockPool() before the fork.
114
|
115 mike 1.8 extern "C" void _unlockSpinLockPool()
|
116 kumpf 1.5 {
117 pthread_mutex_unlock(&_spinLockInitMutex);
118
119 for (size_t i = 0; i < PEGASUS_NUM_SHARED_SPIN_LOCKS; i++)
120 SpinLockUnlock(spinLockPool[i]);
121 }
122
123 class SpinLockInitializer
124 {
125 public:
126 SpinLockInitializer()
127 {
|
128 kumpf 1.7 // ATTN: Temporary workaround for Bug 4559
129 #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_SOLARIS)
|
130 kumpf 1.5 pthread_atfork(
131 _lockSpinLockPool,
132 _unlockSpinLockPool,
133 _unlockSpinLockPool);
|
134 kumpf 1.7 #endif
|
135 mike 1.1 }
|
136 kumpf 1.5 };
137
138 static SpinLockInitializer spinLockInitializer;
139
140 #endif /* PEGASUS_SPINLOCK_USE_PTHREADS */
|
141 mike 1.1
142 PEGASUS_NAMESPACE_END
|