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

1.1       root        1: /* xpevent.c */
                      2: 
                      3: /* *nix emulation of Win32 *Event API */
                      4: 
1.1.1.2 ! root        5: /* $Id: xpevent.c,v 1.15 2010/03/11 01:14:17 deuce Exp $ */
1.1       root        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:        }
1.1.1.2 ! root       53:        memset(event,0,sizeof(struct xpevent));
1.1       root       54: 
                     55:        /*
                     56:         * Initialize
                     57:         */
                     58:        if (pthread_mutex_init(&event->lock, NULL) != 0) {
                     59:                free(event);
                     60:                errno = ENOSPC;
                     61:                return(NULL);
                     62:        }
                     63: 
                     64:        if (pthread_cond_init(&event->gtzero, NULL) != 0) {
                     65:                while(pthread_mutex_destroy(&event->lock)==EBUSY)
                     66:                        SLEEP(1);
                     67:                free(event);
                     68:                errno = ENOSPC;
                     69:                return(NULL);
                     70:        }
                     71: 
                     72:        event->mreset=bManualReset;
                     73:        event->value=bInitialState;
                     74:        event->nwaiters = 0;
                     75:        event->magic=EVENT_MAGIC;
                     76: 
                     77:        return(event);
                     78: }
                     79: 
                     80: BOOL
                     81: SetEvent(xpevent_t event)
                     82: {
                     83:        if (event==NULL || (event->magic != EVENT_MAGIC)) {
                     84:                errno = EINVAL;
                     85:                return(FALSE);
                     86:        }
                     87: 
                     88:        pthread_mutex_lock(&event->lock);
                     89: 
                     90:        event->value=TRUE;
                     91:        if (event->nwaiters > 0) {
                     92:                /*
                     93:                 * We must use pthread_cond_broadcast() rather than
                     94:                 * pthread_cond_signal() in order to assure that the highest
                     95:                 * priority thread is run by the scheduler, since
                     96:                 * pthread_cond_signal() signals waiting threads in FIFO order.
                     97:                 */
                     98:                pthread_cond_broadcast(&event->gtzero);
                     99:        }
                    100: 
                    101:        pthread_mutex_unlock(&event->lock);
                    102: 
                    103:        return(TRUE);
                    104: }
                    105: 
                    106: BOOL
                    107: ResetEvent(xpevent_t event)
                    108: {
                    109:        if (event==NULL || (event->magic != EVENT_MAGIC)) {
                    110:                errno = EINVAL;
                    111:                return(FALSE);
                    112:        }
                    113: 
                    114:        pthread_mutex_lock(&event->lock);
                    115: 
                    116:        event->value=FALSE;
                    117: 
                    118:        pthread_mutex_unlock(&event->lock);
                    119: 
                    120:        return(TRUE);
                    121: }
                    122: 
                    123: BOOL
                    124: CloseEvent(xpevent_t event)
                    125: {
                    126:        if (event==NULL || (event->magic != EVENT_MAGIC)) {
                    127:                errno = EINVAL;
                    128:                return(FALSE);
                    129:        }
                    130: 
                    131:        /* Make sure there are no waiters. */
                    132:        pthread_mutex_lock(&event->lock);
                    133:        if (event->nwaiters > 0) {
                    134:                pthread_mutex_unlock(&event->lock);
                    135:                errno = EBUSY;
                    136:                return(FALSE);
                    137:        }
                    138: 
                    139:        pthread_mutex_unlock(&event->lock);
                    140: 
                    141:        while(pthread_mutex_destroy(&event->lock)==EBUSY)
                    142:                SLEEP(1);
                    143:        while(pthread_cond_destroy(&event->gtzero)==EBUSY)
                    144:                SLEEP(1);
                    145:        event->magic = 0;
                    146: 
                    147:        free(event);
                    148: 
                    149:        return(TRUE);
                    150: }
                    151: 
                    152: DWORD
                    153: WaitForEvent(xpevent_t event, DWORD ms)
                    154: {
                    155:        DWORD   retval=WAIT_FAILED;
                    156:        struct timespec abstime;
                    157:        struct timeval currtime;
                    158: 
                    159:        if (event==NULL || (event->magic != EVENT_MAGIC)) {
                    160:                errno = EINVAL;
                    161:                return(WAIT_FAILED);
                    162:        }
                    163: 
                    164:        if(ms && ms!=INFINITE) {
                    165:                gettimeofday(&currtime,NULL);
1.1.1.2 ! root      166:                abstime.tv_sec=currtime.tv_sec + ((currtime.tv_usec/1000 + ms)/1000);
1.1       root      167:                abstime.tv_nsec=(currtime.tv_usec*1000 + ms*1000000)%1000000000;
                    168:        }
1.1.1.2 ! root      169: 
1.1       root      170:        pthread_mutex_lock(&event->lock);
                    171: 
1.1.1.2 ! root      172:        if(event->value)
        !           173:                retval=WAIT_OBJECT_0;
        !           174: 
        !           175:        while ((!(event->value)) || (event->verify!=NULL && !event->verify(event->cbdata))) {
        !           176:                retval=WAIT_FAILED;
1.1       root      177:                event->nwaiters++;
                    178:                switch(ms) {
                    179:                        case 0:
                    180:                                if(event->value)
1.1.1.2 ! root      181:                                        retval=WAIT_OBJECT_0;
1.1       root      182:                                else
                    183:                                        retval=WAIT_TIMEOUT;
1.1.1.2 ! root      184:                                event->nwaiters--;
1.1       root      185:                                goto DONE;
                    186:                                break;
                    187:                        case INFINITE:
                    188:                                retval=pthread_cond_wait(&event->gtzero, &event->lock);
1.1.1.2 ! root      189:                                if(retval) {
        !           190:                                        errno=retval;
        !           191:                                        retval=WAIT_FAILED;
        !           192:                                        event->nwaiters--;
        !           193:                                        goto DONE;
        !           194:                                }
1.1       root      195:                                break;
                    196:                        default:
                    197:                                retval=pthread_cond_timedwait(&event->gtzero, &event->lock, &abstime);
                    198:                                if(retval)  {
                    199:                                        if(retval==ETIMEDOUT)
                    200:                                                retval=WAIT_TIMEOUT;
                    201:                                        else {
                    202:                                                errno=retval;
                    203:                                                retval=WAIT_FAILED;
                    204:                                        }
1.1.1.2 ! root      205:                                        event->nwaiters--;
1.1       root      206:                                        goto DONE;
                    207:                                }
                    208:                }
                    209:                event->nwaiters--;
                    210:        }
                    211: 
                    212:   DONE:
                    213: 
1.1.1.2 ! root      214:        if(retval==WAIT_OBJECT_0) {
1.1       root      215:                if(!event->mreset)
                    216:                        event->value=FALSE;
                    217:        }
                    218: 
                    219:        pthread_mutex_unlock(&event->lock);
                    220: 
                    221:        return retval;
                    222: }

unix.superglobalmegacorp.com

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