⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ptsynch.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* tuck these away 'till later */    saved_entries = mon->entryCount;     mon->entryCount = 0;    _PT_PTHREAD_COPY_THR_HANDLE(mon->owner, saved_owner);    _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner);        rv = PR_WaitCondVar(mon->cvar, timeout);    /* reinstate the intresting information */    mon->entryCount = saved_entries;    _PT_PTHREAD_COPY_THR_HANDLE(saved_owner, mon->owner);    return rv;}  /* PR_Wait */PR_IMPLEMENT(PRStatus) PR_Notify(PRMonitor *mon){    PR_ASSERT(NULL != mon);    /* we'd better be locked */    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex));    /* and the entries better be positive */    PR_ASSERT(mon->entryCount > 0);    /* and it better be by us */    PR_ASSERT(pthread_equal(mon->owner, pthread_self()));    pt_PostNotifyToCvar(mon->cvar, PR_FALSE);    return PR_SUCCESS;}  /* PR_Notify */PR_IMPLEMENT(PRStatus) PR_NotifyAll(PRMonitor *mon){    PR_ASSERT(mon != NULL);    /* we'd better be locked */    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex));    /* and the entries better be positive */    PR_ASSERT(mon->entryCount > 0);    /* and it better be by us */    PR_ASSERT(pthread_equal(mon->owner, pthread_self()));    pt_PostNotifyToCvar(mon->cvar, PR_TRUE);    return PR_SUCCESS;}  /* PR_NotifyAll *//**************************************************************//**************************************************************//**************************SEMAPHORES**************************//**************************************************************//**************************************************************/PR_IMPLEMENT(void) PR_PostSem(PRSemaphore *semaphore){    static PRBool unwarned = PR_TRUE;    if (unwarned) unwarned = _PR_Obsolete(        "PR_PostSem", "locks & condition variables");	PR_Lock(semaphore->cvar->lock);	PR_NotifyCondVar(semaphore->cvar);	semaphore->count += 1;	PR_Unlock(semaphore->cvar->lock);}  /* PR_PostSem */PR_IMPLEMENT(PRStatus) PR_WaitSem(PRSemaphore *semaphore){	PRStatus status = PR_SUCCESS;    static PRBool unwarned = PR_TRUE;    if (unwarned) unwarned = _PR_Obsolete(        "PR_WaitSem", "locks & condition variables");	PR_Lock(semaphore->cvar->lock);	while ((semaphore->count == 0) && (PR_SUCCESS == status))		status = PR_WaitCondVar(semaphore->cvar, PR_INTERVAL_NO_TIMEOUT);	if (PR_SUCCESS == status) semaphore->count -= 1;	PR_Unlock(semaphore->cvar->lock);	return status;}  /* PR_WaitSem */PR_IMPLEMENT(void) PR_DestroySem(PRSemaphore *semaphore){    static PRBool unwarned = PR_TRUE;    if (unwarned) unwarned = _PR_Obsolete(        "PR_DestroySem", "locks & condition variables");    PR_DestroyLock(semaphore->cvar->lock);    PR_DestroyCondVar(semaphore->cvar);    PR_DELETE(semaphore);}  /* PR_DestroySem */PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value){    PRSemaphore *semaphore;    static PRBool unwarned = PR_TRUE;    if (!_pr_initialized) _PR_ImplicitInitialization();    if (unwarned) unwarned = _PR_Obsolete(        "PR_NewSem", "locks & condition variables");    semaphore = PR_NEWZAP(PRSemaphore);    if (NULL != semaphore)    {        PRLock *lock = PR_NewLock();        if (NULL != lock)        {            semaphore->cvar = PR_NewCondVar(lock);            if (NULL != semaphore->cvar)            {                semaphore->count = value;                return semaphore;            }            PR_DestroyLock(lock);        }        PR_DELETE(semaphore);    }    return NULL;}/* * Define the interprocess named semaphore functions. * There are three implementations: * 1. POSIX semaphore based; * 2. System V semaphore based; * 3. unsupported (fails with PR_NOT_IMPLEMENTED_ERROR). */#ifdef _PR_HAVE_POSIX_SEMAPHORES#include <fcntl.h>PR_IMPLEMENT(PRSem *) PR_OpenSemaphore(    const char *name,    PRIntn flags,    PRIntn mode,    PRUintn value){    PRSem *sem;    char osname[PR_IPC_NAME_SIZE];    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)        == PR_FAILURE)    {        return NULL;    }    sem = PR_NEW(PRSem);    if (NULL == sem)    {        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);        return NULL;    }    if (flags & PR_SEM_CREATE)    {        int oflag = O_CREAT;        if (flags & PR_SEM_EXCL) oflag |= O_EXCL;        sem->sem = sem_open(osname, oflag, mode, value);    }    else    {        sem->sem = sem_open(osname, 0);    }    if ((sem_t *) -1 == sem->sem)    {        _PR_MD_MAP_DEFAULT_ERROR(errno);        PR_DELETE(sem);        return NULL;    }    return sem;}PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem){    int rv;    rv = sem_wait(sem->sem);    if (0 != rv)    {        _PR_MD_MAP_DEFAULT_ERROR(errno);        return PR_FAILURE;    }    return PR_SUCCESS;}PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem){    int rv;    rv = sem_post(sem->sem);    if (0 != rv)    {        _PR_MD_MAP_DEFAULT_ERROR(errno);        return PR_FAILURE;    }    return PR_SUCCESS;}PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem){    int rv;    rv = sem_close(sem->sem);    if (0 != rv)    {        _PR_MD_MAP_DEFAULT_ERROR(errno);        return PR_FAILURE;    }    PR_DELETE(sem);    return PR_SUCCESS;}PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name){    int rv;    char osname[PR_IPC_NAME_SIZE];    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)        == PR_FAILURE)    {        return PR_FAILURE;    }    rv = sem_unlink(osname);    if (0 != rv)    {        _PR_MD_MAP_DEFAULT_ERROR(errno);        return PR_FAILURE;    }    return PR_SUCCESS;}    #elif defined(_PR_HAVE_SYSV_SEMAPHORES)#include <fcntl.h>#include <sys/sem.h>/* * From the semctl(2) man page in glibc 2.0 */#if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) \    || defined(FREEBSD) || defined(OPENBSD) || defined(BSDI)/* union semun is defined by including <sys/sem.h> */#else/* according to X/OPEN we have to define it ourselves */union semun {    int val;    struct semid_ds *buf;    unsigned short  *array;};#endif/* * 'a' (97) is the final closing price of NSCP stock. */#define NSPR_IPC_KEY_ID 'a'  /* the id argument for ftok() */#define NSPR_SEM_MODE 0666PR_IMPLEMENT(PRSem *) PR_OpenSemaphore(    const char *name,    PRIntn flags,    PRIntn mode,    PRUintn value){    PRSem *sem;    key_t key;    union semun arg;    struct sembuf sop;    struct semid_ds seminfo;#define MAX_TRIES 60    PRIntn i;    char osname[PR_IPC_NAME_SIZE];    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)        == PR_FAILURE)    {        return NULL;    }    /* Make sure the file exists before calling ftok. */    if (flags & PR_SEM_CREATE)    {        int osfd = open(osname, O_RDWR|O_CREAT, mode);        if (-1 == osfd)        {            _PR_MD_MAP_OPEN_ERROR(errno);            return NULL;        }        if (close(osfd) == -1)        {            _PR_MD_MAP_CLOSE_ERROR(errno);            return NULL;        }    }    key = ftok(osname, NSPR_IPC_KEY_ID);    if ((key_t)-1 == key)    {        _PR_MD_MAP_DEFAULT_ERROR(errno);        return NULL;    }    sem = PR_NEW(PRSem);    if (NULL == sem)    {        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);        return NULL;    }    if (flags & PR_SEM_CREATE)    {        sem->semid = semget(key, 1, mode|IPC_CREAT|IPC_EXCL);        if (sem->semid >= 0)        {            /* creator of a semaphore is responsible for initializing it */            arg.val = 0;            if (semctl(sem->semid, 0, SETVAL, arg) == -1)            {                _PR_MD_MAP_DEFAULT_ERROR(errno);                PR_DELETE(sem);                return NULL;            }            /* call semop to set sem_otime to nonzero */            sop.sem_num = 0;            sop.sem_op = value;            sop.sem_flg = 0;            if (semop(sem->semid, &sop, 1) == -1)            {                _PR_MD_MAP_DEFAULT_ERROR(errno);                PR_DELETE(sem);                return NULL;            }            return sem;        }        if (errno != EEXIST || flags & PR_SEM_EXCL)        {            _PR_MD_MAP_DEFAULT_ERROR(errno);            PR_DELETE(sem);            return NULL;        }    }    sem->semid = semget(key, 1, NSPR_SEM_MODE);    if (sem->semid == -1)    {        _PR_MD_MAP_DEFAULT_ERROR(errno);        PR_DELETE(sem);        return NULL;    }    for (i = 0; i < MAX_TRIES; i++)    {        arg.buf = &seminfo;        semctl(sem->semid, 0, IPC_STAT, arg);        if (seminfo.sem_otime != 0) break;        sleep(1);    }    if (i == MAX_TRIES)    {        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);        PR_DELETE(sem);        return NULL;    }    return sem;}PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem){    struct sembuf sop;    sop.sem_num = 0;    sop.sem_op = -1;    sop.sem_flg = 0;    if (semop(sem->semid, &sop, 1) == -1)    {        _PR_MD_MAP_DEFAULT_ERROR(errno);        return PR_FAILURE;    }    return PR_SUCCESS;}PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem){    struct sembuf sop;    sop.sem_num = 0;    sop.sem_op = 1;    sop.sem_flg = 0;    if (semop(sem->semid, &sop, 1) == -1)    {        _PR_MD_MAP_DEFAULT_ERROR(errno);        return PR_FAILURE;    }    return PR_SUCCESS;}PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem){    PR_DELETE(sem);    return PR_SUCCESS;}PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name){    key_t key;    int semid;    /* On some systems (e.g., glibc 2.0) semctl requires a fourth argument */    union semun unused;    char osname[PR_IPC_NAME_SIZE];    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)        == PR_FAILURE)    {        return PR_FAILURE;    }    key = ftok(osname, NSPR_IPC_KEY_ID);    if ((key_t) -1 == key)    {        _PR_MD_MAP_DEFAULT_ERROR(errno);        return PR_FAILURE;    }    if (unlink(osname) == -1)    {        _PR_MD_MAP_UNLINK_ERROR(errno);        return PR_FAILURE;    }    semid = semget(key, 1, NSPR_SEM_MODE);    if (-1 == semid)    {        _PR_MD_MAP_DEFAULT_ERROR(errno);        return PR_FAILURE;    }    unused.val = 0;    if (semctl(semid, 0, IPC_RMID, unused) == -1)    {         _PR_MD_MAP_DEFAULT_ERROR(errno);        return PR_FAILURE;    }    return PR_SUCCESS;}#else /* neither POSIX nor System V semaphores are available */PR_IMPLEMENT(PRSem *) PR_OpenSemaphore(    const char *name,    PRIntn flags,    PRIntn mode,    PRUintn value){    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);    return NULL;}PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem){    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);    return PR_FAILURE;}PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem){    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);    return PR_FAILURE;}PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem){    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);    return PR_FAILURE;}PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name){    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);    return PR_FAILURE;}#endif /* end of interprocess named semaphore functions *//**************************************************************//**************************************************************//******************ROUTINES FOR DCE EMULATION******************//**************************************************************//**************************************************************/#include "prpdce.h"PR_IMPLEMENT(PRStatus) PRP_TryLock(PRLock *lock){    PRIntn rv = pthread_mutex_trylock(&lock->mutex);    if (rv == PT_TRYLOCK_SUCCESS)    {        PR_ASSERT(PR_FALSE == lock->locked);        lock->locked = PR_TRUE;        lock->owner = pthread_self();    }    /* XXX set error code? */    return (PT_TRYLOCK_SUCCESS == rv) ? PR_SUCCESS : PR_FAILURE;}  /* PRP_TryLock */PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void){    PRCondVar *cv;    if (!_pr_initialized) _PR_ImplicitInitialization();    cv = PR_NEW(PRCondVar);    if (cv != NULL)    {        int rv;        rv = _PT_PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr);         PR_ASSERT(0 == rv);        cv->lock = _PR_NAKED_CV_LOCK;    }    return cv;}  /* PRP_NewNakedCondVar */PR_IMPLEMENT(void) PRP_DestroyNakedCondVar(PRCondVar *cvar){    int rv;    rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv);#if defined(DEBUG)        memset(cvar, 0xaf, sizeof(PRCondVar));#endif    PR_DELETE(cvar);}  /* PRP_DestroyNakedCondVar */PR_IMPLEMENT(PRStatus) PRP_NakedWait(    PRCondVar *cvar, PRLock *ml, PRIntervalTime timeout){    PRIntn rv;    PR_ASSERT(cvar != NULL);    /* XXX do we really want to assert this in a naked wait? */    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(ml->mutex));    if (timeout == PR_INTERVAL_NO_TIMEOUT)        rv = pthread_cond_wait(&cvar->cv, &ml->mutex);    else        rv = pt_TimedWait(&cvar->cv, &ml->mutex, timeout);    if (rv != 0)    {        _PR_MD_MAP_DEFAULT_ERROR(rv);        return PR_FAILURE;    }    return PR_SUCCESS;}  /* PRP_NakedWait */PR_IMPLEMENT(PRStatus) PRP_NakedNotify(PRCondVar *cvar){    int rv;    PR_ASSERT(cvar != NULL);    rv = pthread_cond_signal(&cvar->cv);    PR_ASSERT(0 == rv);    return PR_SUCCESS;}  /* PRP_NakedNotify */PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar){    int rv;    PR_ASSERT(cvar != NULL);    rv = pthread_cond_broadcast(&cvar->cv);    PR_ASSERT(0 == rv);    return PR_SUCCESS;}  /* PRP_NakedBroadcast */#endif  /* defined(_PR_PTHREADS) *//* ptsynch.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -