/[pcsx2_0.9.7]/trunk/3rdparty/w32pthreads/sem_timedwait.c
ViewVC logotype

Annotation of /trunk/3rdparty/w32pthreads/sem_timedwait.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years ago) by william
File MIME type: text/plain
File size: 6347 byte(s)
committing r3113 initial commit again...
1 william 31 /*
2     * -------------------------------------------------------------
3     *
4     * Module: sem_timedwait.c
5     *
6     * Purpose:
7     * Semaphores aren't actually part of the PThreads standard.
8     * They are defined by the POSIX Standard:
9     *
10     * POSIX 1003.1b-1993 (POSIX.1b)
11     *
12     * -------------------------------------------------------------
13     *
14     * --------------------------------------------------------------------------
15     *
16     * Pthreads-win32 - POSIX Threads Library for Win32
17     * Copyright(C) 1998 John E. Bossom
18     * Copyright(C) 1999,2005 Pthreads-win32 contributors
19     *
20     * Contact Email: rpj@callisto.canberra.edu.au
21     *
22     * The current list of contributors is contained
23     * in the file CONTRIBUTORS included with the source
24     * code distribution. The list can also be seen at the
25     * following World Wide Web location:
26     * http://sources.redhat.com/pthreads-win32/contributors.html
27     *
28     * This library is free software; you can redistribute it and/or
29     * modify it under the terms of the GNU Lesser General Public
30     * License as published by the Free Software Foundation; either
31     * version 2 of the License, or (at your option) any later version.
32     *
33     * This library is distributed in the hope that it will be useful,
34     * but WITHOUT ANY WARRANTY; without even the implied warranty of
35     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
36     * Lesser General Public License for more details.
37     *
38     * You should have received a copy of the GNU Lesser General Public
39     * License along with this library in the file COPYING.LIB;
40     * if not, write to the Free Software Foundation, Inc.,
41     * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
42     */
43    
44     #include "ptw32pch.h"
45     #include "semaphore.h"
46    
47    
48     typedef struct {
49     sem_t sem;
50     int * resultPtr;
51     } sem_timedwait_cleanup_args_t;
52    
53    
54     static void PTW32_CDECL
55     ptw32_sem_timedwait_cleanup (void * args)
56     {
57     sem_timedwait_cleanup_args_t * a = (sem_timedwait_cleanup_args_t *)args;
58     sem_t s = a->sem;
59    
60     if (pthread_mutex_lock (&s->lock) == 0)
61     {
62     /*
63     * We either timed out or were cancelled.
64     * If someone has posted between then and now we try to take the semaphore.
65     * Otherwise the semaphore count may be wrong after we
66     * return. In the case of a cancellation, it is as if we
67     * were cancelled just before we return (after taking the semaphore)
68     * which is ok.
69     */
70     if (WaitForSingleObject(s->sem, 0) == WAIT_OBJECT_0)
71     {
72     /* We got the semaphore on the second attempt */
73     *(a->resultPtr) = 0;
74     }
75     else
76     {
77     /* Indicate we're no longer waiting */
78     s->value++;
79     #ifdef NEED_SEM
80     if (s->value > 0)
81     {
82     s->leftToUnblock = 0;
83     }
84     #else
85     /*
86     * Don't release the W32 sema, it doesn't need adjustment
87     * because it doesn't record the number of waiters.
88     */
89     #endif
90     }
91     (void) pthread_mutex_unlock (&s->lock);
92     }
93     }
94    
95    
96     int
97     sem_timedwait (sem_t * sem, const struct timespec *abstime)
98     /*
99     * ------------------------------------------------------
100     * DOCPUBLIC
101     * This function waits on a semaphore possibly until
102     * 'abstime' time.
103     *
104     * PARAMETERS
105     * sem
106     * pointer to an instance of sem_t
107     *
108     * abstime
109     * pointer to an instance of struct timespec
110     *
111     * DESCRIPTION
112     * This function waits on a semaphore. If the
113     * semaphore value is greater than zero, it decreases
114     * its value by one. If the semaphore value is zero, then
115     * the calling thread (or process) is blocked until it can
116     * successfully decrease the value or until interrupted by
117     * a signal.
118     *
119     * If 'abstime' is a NULL pointer then this function will
120     * block until it can successfully decrease the value or
121     * until interrupted by a signal.
122     *
123     * RESULTS
124     * 0 successfully decreased semaphore,
125     * -1 failed, error in errno
126     * ERRNO
127     * EINVAL 'sem' is not a valid semaphore,
128     * ENOSYS semaphores are not supported,
129     * EINTR the function was interrupted by a signal,
130     * EDEADLK a deadlock condition was detected.
131     * ETIMEDOUT abstime elapsed before success.
132     *
133     * ------------------------------------------------------
134     */
135     {
136     int result = 0;
137     sem_t s = *sem;
138    
139     pthread_testcancel();
140    
141     if (sem == NULL)
142     {
143     result = EINVAL;
144     }
145     else
146     {
147     DWORD milliseconds;
148    
149     if (abstime == NULL)
150     {
151     milliseconds = INFINITE;
152     }
153     else
154     {
155     /*
156     * Calculate timeout as milliseconds from current system time.
157     */
158     milliseconds = ptw32_relmillisecs (abstime);
159     }
160    
161     if ((result = pthread_mutex_lock (&s->lock)) == 0)
162     {
163     int v;
164    
165     /* See sem_destroy.c
166     */
167     if (*sem == NULL)
168     {
169     (void) pthread_mutex_unlock (&s->lock);
170     errno = EINVAL;
171     return -1;
172     }
173    
174     v = --s->value;
175     (void) pthread_mutex_unlock (&s->lock);
176    
177     if (v < 0)
178     {
179     #ifdef NEED_SEM
180     int timedout;
181     #endif
182     sem_timedwait_cleanup_args_t cleanup_args;
183    
184     cleanup_args.sem = s;
185     cleanup_args.resultPtr = &result;
186    
187     #ifdef _MSC_VER
188     #pragma inline_depth(0)
189     #endif
190     /* Must wait */
191     pthread_cleanup_push(ptw32_sem_timedwait_cleanup, (void *) &cleanup_args);
192     #ifdef NEED_SEM
193     timedout =
194     #endif
195     result = pthreadCancelableTimedWait (s->sem, milliseconds);
196     pthread_cleanup_pop(result);
197     #ifdef _MSC_VER
198     #pragma inline_depth()
199     #endif
200    
201     #ifdef NEED_SEM
202    
203     if (!timedout && pthread_mutex_lock (&s->lock) == 0)
204     {
205     if (*sem == NULL)
206     {
207     (void) pthread_mutex_unlock (&s->lock);
208     errno = EINVAL;
209     return -1;
210     }
211    
212     if (s->leftToUnblock > 0)
213     {
214     --s->leftToUnblock;
215     SetEvent(s->sem);
216     }
217     (void) pthread_mutex_unlock (&s->lock);
218     }
219    
220     #endif /* NEED_SEM */
221    
222     }
223     }
224    
225     }
226    
227     if (result != 0)
228     {
229    
230     errno = result;
231     return -1;
232    
233     }
234    
235     return 0;
236    
237     } /* sem_timedwait */

  ViewVC Help
Powered by ViewVC 1.1.22