version 1.2, 2005/11/03 02:26:06
|
version 1.10.4.3, 2006/07/29 01:18:27
|
|
|
//%2005//////////////////////////////////////////////////////////////////////// |
//%2006//////////////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development | // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development |
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. | // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. |
|
|
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. | // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. |
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; | // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
// EMC Corporation; VERITAS Software Corporation; The Open Group. | // EMC Corporation; VERITAS Software Corporation; The Open Group. |
|
// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
|
// EMC Corporation; Symantec Corporation; The Open Group. |
// | // |
// Permission is hereby granted, free of charge, to any person obtaining a copy | // Permission is hereby granted, free of charge, to any person obtaining a copy |
// of this software and associated documentation files (the "Software"), to | // of this software and associated documentation files (the "Software"), to |
|
|
// | // |
// Author: Mike Brasher, Inova Europe (mike-brasher@austin.rr.com) | // Author: Mike Brasher, Inova Europe (mike-brasher@austin.rr.com) |
// | // |
|
// Modified By: David Dillard, Symantec Corp. (david_dillard@symantec.com) |
|
// |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
|
#include "Network.h" |
|
|
|
#if defined(PEGASUS_OS_SOLARIS) |
|
# include <sys/types.h> |
|
# include <unistd.h> |
|
#endif |
|
|
#include "SpinLock.h" | #include "SpinLock.h" |
| |
|
#if !defined(PEGASUS_OS_VMS) && !defined(PEGASUS_OS_TYPE_WINDOWS) |
|
# define PEGASUS_SPINLOCK_USE_PTHREADS |
|
#endif |
|
|
#ifdef PEGASUS_SPINLOCK_USE_PTHREADS | #ifdef PEGASUS_SPINLOCK_USE_PTHREADS |
# include <pthread.h> | # include <pthread.h> |
#else | #else |
# include "IPC.h" |
# include "Mutex.h" |
#endif | #endif |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
SpinLock sharedSpinLocks[PEGASUS_NUM_SHARED_SPIN_LOCKS]; |
SpinLock spinLockPool[PEGASUS_NUM_SHARED_SPIN_LOCKS]; |
|
int spinLockPoolInitialized; |
| |
#ifdef PEGASUS_SPINLOCK_USE_PTHREADS | #ifdef PEGASUS_SPINLOCK_USE_PTHREADS |
pthread_mutex_t _spinLockInitMutex = PTHREAD_MUTEX_INITIALIZER; | pthread_mutex_t _spinLockInitMutex = PTHREAD_MUTEX_INITIALIZER; |
|
|
static Mutex _spinLockInitMutex; | static Mutex _spinLockInitMutex; |
#endif | #endif |
| |
void SpinLockConditionalCreate(SpinLock& lock) |
void SpinLockCreatePool() |
{ | { |
// Use double-checked locking pattern to avoid mutex lock when possible. |
// There's no need to check spinLockPoolInitialized before locking the |
|
// mutex, because the caller can check the flag before calling this |
|
// function. |
| |
if (lock.initialized == 0) |
|
{ |
|
#ifdef PEGASUS_SPINLOCK_USE_PTHREADS | #ifdef PEGASUS_SPINLOCK_USE_PTHREADS |
pthread_mutex_lock(&_spinLockInitMutex); | pthread_mutex_lock(&_spinLockInitMutex); |
#else | #else |
_spinLockInitMutex.lock(pegasus_thread_self()); |
_spinLockInitMutex.lock(); |
#endif | #endif |
| |
if (lock.initialized == 0) |
if (spinLockPoolInitialized == 0) |
SpinLockCreate(lock); |
{ |
|
for (size_t i = 0; i < PEGASUS_NUM_SHARED_SPIN_LOCKS; i++) |
|
SpinLockCreate(spinLockPool[i]); |
|
|
|
spinLockPoolInitialized = 1; |
|
} |
| |
#ifdef PEGASUS_SPINLOCK_USE_PTHREADS | #ifdef PEGASUS_SPINLOCK_USE_PTHREADS |
pthread_mutex_unlock(&_spinLockInitMutex); | pthread_mutex_unlock(&_spinLockInitMutex); |
|
|
_spinLockInitMutex.unlock(); | _spinLockInitMutex.unlock(); |
#endif | #endif |
} | } |
|
|
|
#if defined(PEGASUS_SPINLOCK_USE_PTHREADS) |
|
|
|
// This function is called prior to forking. We must obtain a lock |
|
// on every mutex that the child will inherit. These will remain locked |
|
// until they are unlocked (by _unlockSpinLockPool()). This prevents a |
|
// child process from waiting indefinitely on a mutex that was locked by |
|
// another thread in the parent process during the fork. |
|
|
|
extern "C" void _lockSpinLockPool() |
|
{ |
|
// Initialize the spinlock pool if not already done. |
|
|
|
if (spinLockPoolInitialized == 0) |
|
SpinLockCreatePool(); |
|
|
|
pthread_mutex_lock(&_spinLockInitMutex); |
|
|
|
for (size_t i = 0; i < PEGASUS_NUM_SHARED_SPIN_LOCKS; i++) |
|
SpinLockLock(spinLockPool[i]); |
|
} |
|
|
|
// This function is called after forking. It unlocks the mutexes that |
|
// were locked by _lockSpinLockPool() before the fork. |
|
|
|
extern "C" void _unlockSpinLockPool() |
|
{ |
|
pthread_mutex_unlock(&_spinLockInitMutex); |
|
|
|
for (size_t i = 0; i < PEGASUS_NUM_SHARED_SPIN_LOCKS; i++) |
|
SpinLockUnlock(spinLockPool[i]); |
} | } |
| |
|
class SpinLockInitializer |
|
{ |
|
public: |
|
SpinLockInitializer() |
|
{ |
|
// ATTN: Temporary workaround for Bug 4559 |
|
#if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_SOLARIS) |
|
pthread_atfork( |
|
_lockSpinLockPool, |
|
_unlockSpinLockPool, |
|
_unlockSpinLockPool); |
|
#endif |
|
} |
|
}; |
|
|
|
static SpinLockInitializer spinLockInitializer; |
|
|
|
#endif /* PEGASUS_SPINLOCK_USE_PTHREADS */ |
|
|
PEGASUS_NAMESPACE_END | PEGASUS_NAMESPACE_END |