|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.