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