Annotation of sbbs/src/xpdev/xpevent.c, revision 1.1.1.1

1.1       root        1: /* xpevent.c */
                      2: 
                      3: /* *nix emulation of Win32 *Event API */
                      4: 
                      5: /* $Id: xpevent.c,v 1.9 2005/10/21 21:49:48 deuce Exp $ */
                      6: 
                      7: /****************************************************************************
                      8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                     10:  *                                                                                                                                                     *
                     11:  * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html         *
                     12:  *                                                                                                                                                     *
                     13:  * This library is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU Lesser General Public License          *
                     15:  * as published by the Free Software Foundation; either version 2                      *
                     16:  * of the License, or (at your option) any later version.                                      *
                     17:  * See the GNU Lesser General Public License for more details: lgpl.txt or     *
                     18:  * http://www.fsf.org/copyleft/lesser.html                                                                     *
                     19:  *                                                                                                                                                     *
                     20:  * Anonymous FTP access to the most recent released source is available at     *
                     21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     22:  *                                                                                                                                                     *
                     23:  * Anonymous CVS access to the development source and modification history     *
                     24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     26:  *     (just hit return, no password is necessary)                                                     *
                     27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     28:  *                                                                                                                                                     *
                     29:  * For Synchronet coding style and modification guidelines, see                                *
                     30:  * http://www.synchro.net/source.html                                                                          *
                     31:  *                                                                                                                                                     *
                     32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     33:  * format) via e-mail to [email protected]                                                                      *
                     34:  *                                                                                                                                                     *
                     35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     36:  ****************************************************************************/
                     37: 
                     38: #include <stdio.h>             /* NULL */
                     39: #include <stdlib.h>            /* malloc() */
                     40: #include "xpevent.h"
                     41: #include "genwrap.h"
                     42: 
                     43: xpevent_t
                     44: CreateEvent(void *sec, BOOL bManualReset, BOOL bInitialState, void *name)
                     45: {
                     46:        xpevent_t       event;
                     47: 
                     48:        event = (xpevent_t)malloc(sizeof(struct xpevent));
                     49:        if (event == NULL) {
                     50:                errno = ENOSPC;
                     51:                return(NULL);
                     52:        }
                     53: 
                     54:        /*
                     55:         * Initialize
                     56:         */
                     57:        if (pthread_mutex_init(&event->lock, NULL) != 0) {
                     58:                free(event);
                     59:                errno = ENOSPC;
                     60:                return(NULL);
                     61:        }
                     62: 
                     63:        if (pthread_cond_init(&event->gtzero, NULL) != 0) {
                     64:                while(pthread_mutex_destroy(&event->lock)==EBUSY)
                     65:                        SLEEP(1);
                     66:                free(event);
                     67:                errno = ENOSPC;
                     68:                return(NULL);
                     69:        }
                     70: 
                     71:        event->mreset=bManualReset;
                     72:        event->value=bInitialState;
                     73:        event->nwaiters = 0;
                     74:        event->magic=EVENT_MAGIC;
                     75: 
                     76:        return(event);
                     77: }
                     78: 
                     79: BOOL
                     80: SetEvent(xpevent_t event)
                     81: {
                     82:        if (event==NULL || (event->magic != EVENT_MAGIC)) {
                     83:                errno = EINVAL;
                     84:                return(FALSE);
                     85:        }
                     86: 
                     87:        pthread_mutex_lock(&event->lock);
                     88: 
                     89:        event->value=TRUE;
                     90:        if (event->nwaiters > 0) {
                     91:                /*
                     92:                 * We must use pthread_cond_broadcast() rather than
                     93:                 * pthread_cond_signal() in order to assure that the highest
                     94:                 * priority thread is run by the scheduler, since
                     95:                 * pthread_cond_signal() signals waiting threads in FIFO order.
                     96:                 */
                     97:                pthread_cond_broadcast(&event->gtzero);
                     98:        }
                     99: 
                    100:        pthread_mutex_unlock(&event->lock);
                    101: 
                    102:        return(TRUE);
                    103: }
                    104: 
                    105: BOOL
                    106: ResetEvent(xpevent_t event)
                    107: {
                    108:        if (event==NULL || (event->magic != EVENT_MAGIC)) {
                    109:                errno = EINVAL;
                    110:                return(FALSE);
                    111:        }
                    112: 
                    113:        pthread_mutex_lock(&event->lock);
                    114: 
                    115:        event->value=FALSE;
                    116: 
                    117:        pthread_mutex_unlock(&event->lock);
                    118: 
                    119:        return(TRUE);
                    120: }
                    121: 
                    122: BOOL
                    123: CloseEvent(xpevent_t event)
                    124: {
                    125:        if (event==NULL || (event->magic != EVENT_MAGIC)) {
                    126:                errno = EINVAL;
                    127:                return(FALSE);
                    128:        }
                    129: 
                    130:        /* Make sure there are no waiters. */
                    131:        pthread_mutex_lock(&event->lock);
                    132:        if (event->nwaiters > 0) {
                    133:                pthread_mutex_unlock(&event->lock);
                    134:                errno = EBUSY;
                    135:                return(FALSE);
                    136:        }
                    137: 
                    138:        pthread_mutex_unlock(&event->lock);
                    139: 
                    140:        while(pthread_mutex_destroy(&event->lock)==EBUSY)
                    141:                SLEEP(1);
                    142:        while(pthread_cond_destroy(&event->gtzero)==EBUSY)
                    143:                SLEEP(1);
                    144:        event->magic = 0;
                    145: 
                    146:        free(event);
                    147: 
                    148:        return(TRUE);
                    149: }
                    150: 
                    151: DWORD
                    152: WaitForEvent(xpevent_t event, DWORD ms)
                    153: {
                    154:        DWORD   retval=WAIT_FAILED;
                    155:        struct timespec abstime;
                    156:        struct timeval currtime;
                    157: 
                    158:        if (event==NULL || (event->magic != EVENT_MAGIC)) {
                    159:                errno = EINVAL;
                    160:                return(WAIT_FAILED);
                    161:        }
                    162: 
                    163:        if(ms && ms!=INFINITE) {
                    164:                gettimeofday(&currtime,NULL);
                    165:                abstime.tv_sec=currtime.tv_sec + (currtime.tv_usec/1000 + ms)/1000;
                    166:                abstime.tv_nsec=(currtime.tv_usec*1000 + ms*1000000)%1000000000;
                    167:        }
                    168:        
                    169:        pthread_mutex_lock(&event->lock);
                    170: 
                    171:        while (!(event->value)) {
                    172:                event->nwaiters++;
                    173:                switch(ms) {
                    174:                        case 0:
                    175:                                if(event->value)
                    176:                                        retval=0;
                    177:                                else
                    178:                                        retval=WAIT_TIMEOUT;
                    179:                                goto DONE;
                    180:                                break;
                    181:                        case INFINITE:
                    182:                                retval=pthread_cond_wait(&event->gtzero, &event->lock);
                    183:                                break;
                    184:                        default:
                    185:                                retval=pthread_cond_timedwait(&event->gtzero, &event->lock, &abstime);
                    186:                                if(retval)  {
                    187:                                        if(retval==ETIMEDOUT)
                    188:                                                retval=WAIT_TIMEOUT;
                    189:                                        else {
                    190:                                                errno=retval;
                    191:                                                retval=WAIT_FAILED;
                    192:                                        }
                    193:                                        goto DONE;
                    194:                                }
                    195:                }
                    196:                event->nwaiters--;
                    197:        }
                    198: 
                    199:   DONE:
                    200: 
                    201:        if(retval==0) {
                    202:                retval=WAIT_OBJECT_0;
                    203:                if(!event->mreset)
                    204:                        event->value=FALSE;
                    205:        }
                    206: 
                    207:        pthread_mutex_unlock(&event->lock);
                    208: 
                    209:        return retval;
                    210: }

unix.superglobalmegacorp.com

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