diff options
Diffstat (limited to 'source4/lib/appweb/ejs-2.0/mpr/mprLock.c')
-rw-r--r-- | source4/lib/appweb/ejs-2.0/mpr/mprLock.c | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprLock.c b/source4/lib/appweb/ejs-2.0/mpr/mprLock.c new file mode 100644 index 0000000000..df9ce276d4 --- /dev/null +++ b/source4/lib/appweb/ejs-2.0/mpr/mprLock.c @@ -0,0 +1,266 @@ +/** + * @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 + */ |