root/branches/windows-client/src/common/gen-locks/gen-win-locks.c @ 8520

Revision 8520, 4.6 KB (checked in by sampson, 3 years ago)

Updated gen_locks

  • Property svn:executable set to *
Line 
1/*
2 * (C) 2001 Clemson University and The University of Chicago
3 *
4 * See COPYING in top-level directory.
5 */
6
7
8/* This code implements generic locking that can be turned on or off at
9 * compile time.
10 */
11
12#include <stdlib.h>
13#include <errno.h>
14
15#include "gen-locks.h"
16
17/***************************************************************
18 * visible functions
19 */
20
21#ifndef __GEN_NULL_LOCKING__
22
23/* Global variables */
24/* TODO: may need to init and delete in DLL enter/exit functions */
25LPCRITICAL_SECTION cond_list_lock = NULL;
26
27pgen_cond_t cond_list_head = NULL;
28pgen_cond_t cond_list_tail = NULL;
29
30/*
31 * gen_mutex_init()
32 *
33 * initializes a previously declared mutex
34 *
35 * returns 0 on success, -1 and sets errno on failure.
36 */
37int gen_win_mutex_init(
38    HANDLE *mut)
39{
40    *mut = CreateMutex(NULL, false, NULL);
41    return (*mut) ? 0 : -1;
42}
43
44/*
45 * gen_mutex_lock()
46 *
47 * blocks until it obtains a mutex lock on the given mutex
48 *
49 * returns 0 on success, -1 and sets errno on failure.
50 */
51int gen_win_mutex_lock(
52    HANDLE *mut)
53{
54    DWORD dwWaitResult;
55
56    dwWaitResult = WaitForSingleObject(*mut, INFINITE);
57
58    return (dwWaitResult == WAIT_OBJECT_0 || dwWaitResult == WAIT_ABANDONED) ? 0 : -1;
59}
60
61
62/*
63 * gen_mutex_unlock()
64 *
65 * releases a lock held on a mutex
66 *
67 * returns 0 on success, -1 and sets errno on failure
68 */
69int gen_win_mutex_unlock(
70    HANDLE *mut)
71{
72    BOOL rc = ReleaseMutex(*mut);
73
74    return (rc) ? 0 : -1;
75}
76
77
78/*
79 * pthread_mutex_trylock()
80 *
81 * nonblocking attempt to acquire a lock.
82 *
83 * returns 0 on success, -1 and sets errno on failure, sets errno to EBUSY
84 * if it cannot obtain the lock
85 */
86int gen_win_mutex_trylock(
87    HANDLE *mut)
88{
89    DWORD dwWaitResult;
90    int rc;
91     
92    dwWaitResult = WaitForSingleObject(*mut, 0);
93    if (dwWaitResult == WAIT_OBJECT_0 || dwWaitResult == WAIT_ABANDONED)
94    {
95        rc = 0;
96    }
97    else
98    {
99        rc = -1;
100        if (dwWaitResult == WAIT_TIMEOUT)
101        {
102            errno = EBUSY;
103        }
104        else
105        {
106            errno = GetLastError();
107        }
108    }
109
110    return rc;
111}
112
113/*
114 * gen_mutex_destroy()
115 *
116 * uninitializes the mutex and frees all memory associated with it.
117 *
118 * returns 0 on success, -errno on failure.
119 */
120int gen_win_mutex_destroy(
121    HANDLE *mut)
122{
123
124    if (!mut || *mut == INVALID_HANDLE_VALUE)
125    {
126        return (-EINVAL);
127    }
128   
129    CloseHandle(*mut);
130
131    return (0);
132}
133
134HANDLE gen_win_thread_self(void)
135{
136    return GetCurrentThread();
137}
138
139int gen_win_cond_destroy(HANDLE cond)
140{
141    if(!cond)
142    {
143        return -EINVAL;
144    }
145    pthread_cond_destroy(cond);
146    return 0;
147}
148
149int gen_win_cond_wait(HANDLE cond, HANDLE mut)
150{
151    return pthread_cond_wait(cond, mut);
152}
153
154int gen_win_cond_timedwait(HANDLE cond, HANDLE mut,
155                             const struct timespec *abstime)
156{
157    return pthread_cond_timedwait(cond, mut, abstime);
158}
159
160int gen_win_cond_signal(HANDLE cond)
161{
162    return pthread_cond_signal(cond);
163}
164
165int gen_win_cond_broadcast(HANDLE cond)
166{
167    return pthread_cond_broadcast(cond);
168}
169
170int gen_win_cond_init(pgen_cond_t *cond)
171{
172    int rc;
173    pgen_cond_t cv = NULL;
174
175    if (!cond)
176    {
177        return EINVAL;
178    }
179
180    /* Allocate condition variable */
181    cv = (pgen_cond_t) calloc(1, sizeof(*cv));
182    if (cv == NULL)
183    {
184        rc = ENOMEM;
185        goto DONE;
186    }
187
188    /* Create locking semaphore */
189    cv->semBlockLock = CreateSemaphore(NULL, 1, LONG_MAX, NULL);
190    if (cv->semBlockLock == NULL)
191    {
192        rc = (int) GetLastError();
193        goto FAIL0;
194    }
195
196    /* Create queue semaphore */
197    cv->semBlockQueue = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
198    if (cv->semBlockQueue == NULL)
199    {
200        rc = (int) GetLastError();
201        goto FAIL1;
202    }
203
204    /* Create unblock/lock mutex */
205    if ((rc = gen_mutex_init(&(cv->mtxUnblockLock))) != 0)
206    {
207        goto FAIL2;
208    }
209
210    rc = 0;
211
212    goto DONE;
213
214    /*
215     * Error conditions
216     */
217FAIL2:
218    CloseHandle(cv->semBlockQueue);
219
220FAIL1:
221    CloseHandle(cv->semBlockLock);
222
223FAIL0:
224    free(cv);
225    cv = NULL;
226
227DONE:
228    if (rc == 0)
229    {
230        if (cond_list_lock == NULL)
231        {
232            InitializeCriticalSection(cond_list_lock);
233        }
234
235        EnterCriticalSection(cond_list_lock);
236
237        cv->next = NULL;
238        cv->prev = cond_list_tail;
239
240        if (cond_list_tail != NULL)
241        {
242            cond_list_tail->next = cv;
243        }
244
245        cond_list_tail = cv;
246
247        if (cond_list_head == NULL)
248        {
249            cond_list_head = cv;
250        }
251
252        LeaveCriticalSection(cond_list_lock);
253
254    }
255
256    *cond = cv;
257
258    return rc;
259}
260
261#endif
262
263/*
264 * Local variables:
265 *  c-indent-level: 4
266 *  c-basic-offset: 4
267 * End:
268 *
269 * vim: ts=8 sts=4 sw=4 expandtab
270 */
Note: See TracBrowser for help on using the browser.