Annotation of sbbs/src/xpdev/xpsem.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * $Id: xpsem.c,v 1.12 2005/10/21 21:44:23 deuce Exp $
        !             3:  *
        !             4:  * Copyright (C) 2000 Jason Evans <[email protected]>.
        !             5:  * All rights reserved.
        !             6:  * 
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice(s), this list of conditions and the following disclaimer as
        !            12:  *    the first lines of this file unmodified other than the possible
        !            13:  *    addition of one or more copyright notices.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice(s), this list of conditions and the following disclaimer in
        !            16:  *    the documentation and/or other materials provided with the
        !            17:  *    distribution.
        !            18:  * 
        !            19:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
        !            20:  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
        !            23:  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
        !            26:  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
        !            27:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
        !            28:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
        !            29:  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            30:  *
        !            31:  * $FreeBSD: src/lib/libc_r/uthread/uthread_sem.c,v 1.3.2.1 2000/07/18 02:05:57 jasone Exp $
        !            32:  */
        !            33: 
        !            34: #include <errno.h>
        !            35: #include "xpsem.h"
        !            36: #include <pthread.h>
        !            37: #include <sys/time.h>
        !            38: #include <stdlib.h>
        !            39: #include "gen_defs.h"
        !            40: #include "genwrap.h"
        !            41: 
        !            42: int
        !            43: xp_sem_init(xp_sem_t *sem, int pshared, unsigned int value)
        !            44: {
        !            45:        int     retval;
        !            46: 
        !            47:        /*
        !            48:         * Range check the arguments.
        !            49:         */
        !            50:        if (pshared != 0) {
        !            51:                /*
        !            52:                 * The user wants a semaphore that can be shared among
        !            53:                 * processes, which this implementation can't do.  Sounds like a
        !            54:                 * permissions problem to me (yeah right).
        !            55:                 */
        !            56:                errno = EPERM;
        !            57:                retval = -1;
        !            58:                goto RETURN;
        !            59:        }
        !            60: 
        !            61:        if (value > XP_SEM_VALUE_MAX) {
        !            62:                errno = EINVAL;
        !            63:                retval = -1;
        !            64:                goto RETURN;
        !            65:        }
        !            66: 
        !            67:        *sem = (xp_sem_t)malloc(sizeof(struct xp_sem));
        !            68:        if (*sem == NULL) {
        !            69:                errno = ENOSPC;
        !            70:                retval = -1;
        !            71:                goto RETURN;
        !            72:        }
        !            73: 
        !            74:        /*
        !            75:         * Initialize the semaphore.
        !            76:         */
        !            77:        if (pthread_mutex_init(&(*sem)->lock, NULL) != 0) {
        !            78:                free(*sem);
        !            79:                errno = ENOSPC;
        !            80:                retval = -1;
        !            81:                goto RETURN;
        !            82:        }
        !            83: 
        !            84:        if (pthread_cond_init(&(*sem)->gtzero, NULL) != 0) {
        !            85:                while(pthread_mutex_destroy(&(*sem)->lock)==EBUSY)
        !            86:                        SLEEP(1);
        !            87:                free(*sem);
        !            88:                errno = ENOSPC;
        !            89:                retval = -1;
        !            90:                goto RETURN;
        !            91:        }
        !            92:        
        !            93:        (*sem)->count = (u_int32_t)value;
        !            94:        (*sem)->nwaiters = 0;
        !            95:        (*sem)->magic = XP_SEM_MAGIC;
        !            96: 
        !            97:        retval = 0;
        !            98:   RETURN:
        !            99:        return retval;
        !           100: }
        !           101: 
        !           102: int
        !           103: xp_sem_destroy(xp_sem_t *sem)
        !           104: {
        !           105:        int     retval;
        !           106:        
        !           107:        _SEM_CHECK_VALIDITY(sem);
        !           108: 
        !           109:        /* Make sure there are no waiters. */
        !           110:        pthread_mutex_lock(&(*sem)->lock);
        !           111:        if ((*sem)->nwaiters > 0) {
        !           112:                pthread_mutex_unlock(&(*sem)->lock);
        !           113:                errno = EBUSY;
        !           114:                retval = -1;
        !           115:                goto RETURN;
        !           116:        }
        !           117:        pthread_mutex_unlock(&(*sem)->lock);
        !           118:        
        !           119:        while(pthread_mutex_destroy(&(*sem)->lock)==EBUSY)
        !           120:                SLEEP(1);
        !           121:        while(pthread_cond_destroy(&(*sem)->gtzero)==EBUSY)
        !           122:                SLEEP(1);
        !           123:        (*sem)->magic = 0;
        !           124: 
        !           125:        free(*sem);
        !           126: 
        !           127:        retval = 0;
        !           128:   RETURN:
        !           129:        return retval;
        !           130: }
        !           131: 
        !           132: xp_sem_t *
        !           133: xp_sem_open(const char *name, int oflag, ...)
        !           134: {
        !           135:        errno = ENOSYS;
        !           136:        return XP_SEM_FAILED;
        !           137: }
        !           138: 
        !           139: int
        !           140: xp_sem_close(xp_sem_t *sem)
        !           141: {
        !           142:        errno = ENOSYS;
        !           143:        return -1;
        !           144: }
        !           145: 
        !           146: int
        !           147: xp_sem_unlink(const char *name)
        !           148: {
        !           149:        errno = ENOSYS;
        !           150:        return -1;
        !           151: }
        !           152: 
        !           153: int
        !           154: xp_sem_wait(xp_sem_t *sem)
        !           155: {
        !           156:        int     retval;
        !           157: 
        !           158:        _SEM_CHECK_VALIDITY(sem);
        !           159: 
        !           160:        pthread_mutex_lock(&(*sem)->lock);
        !           161: 
        !           162:        while ((*sem)->count == 0) {
        !           163:                (*sem)->nwaiters++;
        !           164:                pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock);
        !           165:                (*sem)->nwaiters--;
        !           166:        }
        !           167:        (*sem)->count--;
        !           168: 
        !           169:        pthread_mutex_unlock(&(*sem)->lock);
        !           170: 
        !           171:        retval = 0;
        !           172:   RETURN:
        !           173: 
        !           174:        return retval;
        !           175: }
        !           176: 
        !           177: int
        !           178: xp_sem_trywait(xp_sem_t *sem)
        !           179: {
        !           180:        int     retval;
        !           181: 
        !           182:        _SEM_CHECK_VALIDITY(sem);
        !           183: 
        !           184:        pthread_mutex_lock(&(*sem)->lock);
        !           185: 
        !           186:        if ((*sem)->count > 0) {
        !           187:                (*sem)->count--;
        !           188:                retval = 0;
        !           189:        } else {
        !           190:                errno = EAGAIN;
        !           191:                retval = -1;
        !           192:        }
        !           193:        
        !           194:        pthread_mutex_unlock(&(*sem)->lock);
        !           195: 
        !           196:   RETURN:
        !           197:        return retval;
        !           198: }
        !           199: 
        !           200: int
        !           201: xp_sem_post(xp_sem_t *sem)
        !           202: {
        !           203:        int     retval;
        !           204: 
        !           205:        _SEM_CHECK_VALIDITY(sem);
        !           206: 
        !           207:        pthread_mutex_lock(&(*sem)->lock);
        !           208: 
        !           209:        (*sem)->count++;
        !           210:        if ((*sem)->nwaiters > 0) {
        !           211:                /*
        !           212:                 * We must use pthread_cond_broadcast() rather than
        !           213:                 * pthread_cond_signal() in order to assure that the highest
        !           214:                 * priority thread is run by the scheduler, since
        !           215:                 * pthread_cond_signal() signals waiting threads in FIFO order.
        !           216:                 */
        !           217:                pthread_cond_broadcast(&(*sem)->gtzero);
        !           218:        }
        !           219: 
        !           220:        pthread_mutex_unlock(&(*sem)->lock);
        !           221: 
        !           222:        retval = 0;
        !           223:   RETURN:
        !           224:        return retval;
        !           225: }
        !           226: 
        !           227: int
        !           228: xp_sem_getvalue(xp_sem_t *sem, int *sval)
        !           229: {
        !           230:        int     retval;
        !           231: 
        !           232:        _SEM_CHECK_VALIDITY(sem);
        !           233: 
        !           234:        pthread_mutex_lock(&(*sem)->lock);
        !           235:        *sval = (int)(*sem)->count;
        !           236:        pthread_mutex_unlock(&(*sem)->lock);
        !           237: 
        !           238:        retval = 0;
        !           239:   RETURN:
        !           240:        return retval;
        !           241: }
        !           242: 
        !           243: int
        !           244: xp_sem_setvalue(xp_sem_t *sem, int sval)
        !           245: {
        !           246:        int     retval;
        !           247: 
        !           248:        _SEM_CHECK_VALIDITY(sem);
        !           249: 
        !           250:        pthread_mutex_lock(&(*sem)->lock);
        !           251:        (*sem)->count=(u_int32_t)sval;
        !           252:        if (((*sem)->nwaiters > 0) && sval) {
        !           253:                /*
        !           254:                 * We must use pthread_cond_broadcast() rather than
        !           255:                 * pthread_cond_signal() in order to assure that the highest
        !           256:                 * priority thread is run by the scheduler, since
        !           257:                 * pthread_cond_signal() signals waiting threads in FIFO order.
        !           258:                 */
        !           259:                pthread_cond_broadcast(&(*sem)->gtzero);
        !           260:        }
        !           261:        pthread_mutex_unlock(&(*sem)->lock);
        !           262: 
        !           263:        retval = 0;
        !           264:   RETURN:
        !           265:        return retval;
        !           266: }
        !           267: 
        !           268: int
        !           269: xp_sem_timedwait(xp_sem_t *sem, const struct timespec *abs_timeout)
        !           270: {
        !           271:        int     retval=0;
        !           272: 
        !           273:        _SEM_CHECK_VALIDITY(sem);
        !           274: 
        !           275:        pthread_mutex_lock(&(*sem)->lock);
        !           276: 
        !           277:        while ((*sem)->count == 0) {
        !           278:                (*sem)->nwaiters++;
        !           279:                retval=pthread_cond_timedwait(&(*sem)->gtzero, &(*sem)->lock, abs_timeout);
        !           280:                (*sem)->nwaiters--;
        !           281:                if(retval)  {
        !           282:                        errno=retval;
        !           283:                        retval=-1;
        !           284:                        break;
        !           285:                }
        !           286:        }
        !           287:        if(retval==0)
        !           288:                (*sem)->count--;
        !           289: 
        !           290:        pthread_mutex_unlock(&(*sem)->lock);
        !           291: 
        !           292:   RETURN:
        !           293: 
        !           294:        return retval;
        !           295: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.