1
0
mirror of https://github.com/samba-team/samba.git synced 2025-11-16 20:23:50 +03:00
Files
samba-mirror/source/lib/appweb/ejs-2.0/mpr/mprLock.c

267 lines
5.5 KiB
C

/**
* @file mprThread.c
* @brief Mbedthis Portable Runtime Base Thread Locking Support
*/
/*
* @copy default
*
* Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
*
* This software is distributed under commercial and open source licenses.
* You may use the GPL open source license described below or you may acquire
* a commercial license from Mbedthis Software. You agree to be fully bound
* by the terms of either license. Consult the LICENSE.TXT distributed with
* this software for full details.
*
* This software is open source; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See the GNU General Public License for more
* details at: http://www.mbedthis.com/downloads/gplLicense.html
*
* This program is distributed WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* This GPL license does NOT permit incorporating this software into
* proprietary programs. If you are unable to comply with the GPL, you must
* acquire a commercial license to use this software. Commercial licenses
* for this software and support services are available from Mbedthis
* Software at http://www.mbedthis.com
*
* @end
*/
#include "mpr.h"
#if BLD_FEATURE_MULTITHREAD
/************************************ Code ************************************/
void mprInitThreads(MprApp *app)
{
mprAssert(app);
if (app->globalLock == 0) {
app->globalLock = mprCreateLock(app);
app->allocLock = mprCreateLock(app);
}
}
/******************************************************************************/
void mprTermThreads(MprApp *app)
{
mprAssert(app);
if (app->globalLock) {
mprDestroyLock(app->globalLock);
app->globalLock = 0;
}
if (app->allocLock) {
MprLock *lock = app->allocLock;
app->allocLock = 0;
mprDestroyLock(lock);
}
}
/******************************************************************************/
MprLock *mprCreateLock(MprCtx ctx)
{
MprLock *lock;
mprAssert(ctx);
lock = mprAllocType(ctx, MprLock);
#if BLD_HOST_UNIX
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutex_init(&lock->cs, &attr);
pthread_mutexattr_destroy(&attr);
#elif WIN
InitializeCriticalSectionAndSpinCount(&lock->cs, 5000);
#elif VXWORKS
lock->cs = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE |
SEM_INVERSION_SAFE);
if (lock->cs == 0) {
mprAssert(0);
mprFree(lock);
return 0;
}
#endif
return lock;
}
/******************************************************************************/
/*
* Destroy a lock. Must be locked on entrance.
*/
void mprDestroyLock(MprLock *lock)
{
mprAssert(lock);
if (lock == 0) {
return;
}
#if BLD_HOST_UNIX
pthread_mutex_unlock(&lock->cs);
pthread_mutex_destroy(&lock->cs);
#elif WIN
DeleteCriticalSection(&lock->cs);
#elif VXWORKS
semDelete(lock->cs);
#endif
mprFree(lock);
}
/******************************************************************************/
/*
* Lock a mutex
*/
void mprLock(MprLock *lock)
{
/*
* OPT -- Do this just so we can allocate MprApp before we have created its
* lock. Should remove this test here and in mprUnlock.
*/
if (lock == 0) {
return;
}
#if BLD_HOST_UNIX
pthread_mutex_lock(&lock->cs);
#elif WIN
EnterCriticalSection(&lock->cs);
#elif VXWORKS
semTake(lock->cs, WAIT_FOREVER);
#endif
}
/******************************************************************************/
/*
* Try to attain a lock. Do not block!
*/
int mprTryLock(MprLock *lock)
{
mprAssert(lock);
#if BLD_HOST_UNIX
{
int err;
if ((err = pthread_mutex_trylock(&lock->cs)) != 0) {
if (err == EBUSY) {
return MPR_ERR_BUSY;
} else {
return MPR_ERR_CANT_ACCESS;
}
}
return 0;
}
#elif WIN
if (TryEnterCriticalSection(&lock->cs) == 0) {
return MPR_ERR_BUSY;
}
#elif VXWORKS
{
int rc;
rc = semTake(cs, NO_WAIT);
if (rc == -1) {
mprAssert(0);
}
if (rc == S_objLib_OBJ_UNAVAILABLE) {
return MPR_ERR_BUSY;
} else {
return MPR_ERR_CANT_ACCESS;
}
/* Success */
return 0;
}
#endif
return 0;
}
/******************************************************************************/
/*
* Unlock.
*/
void mprUnlock(MprLock *lock)
{
if (lock == 0) {
return;
}
#if BLD_HOST_UNIX
pthread_mutex_unlock(&lock->cs);
#elif WIN
LeaveCriticalSection(&lock->cs);
#elif VXWORKS
semGive(lock->cs);
#endif
}
/******************************************************************************/
/*
* Big global lock. Avoid using this.
*/
void mprGlobalLock(MprCtx ctx)
{
MprApp *app;
app = mprGetApp(ctx);
mprAssert(app);
if (app && app->globalLock) {
mprLock(app->globalLock);
}
}
/******************************************************************************/
void mprGlobalUnlock(MprCtx ctx)
{
MprApp *app;
app = mprGetApp(ctx);
mprAssert(app);
if (app && app->globalLock) {
mprUnlock(app->globalLock);
}
}
/******************************************************************************/
int mprGetCurrentThreadID()
{
#if BLD_HOST_UNIX
return (int) pthread_self();
#elif WIN
return GetCurrentThreadId();
#elif VXWORKS
return (int) pthread_self();
#endif
}
/******************************************************************************/
#endif /* BLD_FEATURE_MULTITHREAD */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim:tw=78
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/