|
|
1.1 root 1: /* threadwrap.c */
2:
3: /* Thread-related cross-platform development wrappers */
4:
5: /* $Id: threadwrap.c,v 1.22 2005/10/21 00:04:19 rswindell 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: #if defined(__unix__)
39: #include <unistd.h> /* _POSIX_THREADS */
40: #include <sys/param.h> /* BSD */
41: #endif
42:
43: #if defined(_WIN32) && !defined(_WIN32_WINNT)
44: #define _WIN32_WINNT 0x0400 /* Needed for TryEnterCriticalSection */
45: #endif
46:
47: #include "threadwrap.h" /* DLLCALL */
48:
49: /****************************************************************************/
50: /* Wrapper for Win32 create/begin thread function */
51: /* Uses POSIX threads */
52: /****************************************************************************/
53: #if defined(__unix__)
54: #if defined(_POSIX_THREADS)
55: #if defined(__BORLANDC__)
56: #pragma argsused
57: #endif
58: ulong _beginthread(void( *start_address )( void * )
59: ,unsigned stack_size, void *arglist)
60: {
61: pthread_t thread;
62: pthread_attr_t attr;
63: size_t default_stack;
64:
65: pthread_attr_init(&attr); /* initialize attribute structure */
66:
67: /* set thread attributes to PTHREAD_CREATE_DETACHED which will ensure
68: that thread resources are freed on exit() */
69: pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
70:
71: /* Default stack size in BSD is too small for JS stuff */
72: /* Force to at least 256k */
73: #define XPDEV_MIN_THREAD_STACK_SIZE (256*1024)
74: if(stack_size==0 && pthread_attr_getstacksize(&attr, &default_stack)==0
75: && default_stack < XPDEV_MIN_THREAD_STACK_SIZE)
76: stack_size=XPDEV_MIN_THREAD_STACK_SIZE;
77:
78: if(stack_size!=0)
79: pthread_attr_setstacksize(&attr, stack_size);
80:
81: if(pthread_create(&thread
82: #if defined(__BORLANDC__) /* a (hopefully temporary) work-around */
83: ,NULL
84: #else
85: ,&attr /* default attributes */
86: #endif
87: /* POSIX defines this arg as "void *(*start_address)" */
88: ,(void * (*)(void *)) start_address
89: ,arglist)==0)
90: return((int) thread /* thread handle */);
91:
92: return(-1); /* error */
93: }
94: #else
95:
96: #error "Need _beginthread implementation for non-POSIX thread library."
97:
98: #endif
99:
100: #endif /* __unix__ */
101:
102: /****************************************************************************/
103: /* Wrappers for POSIX thread (pthread) mutexes */
104: /****************************************************************************/
105: pthread_mutex_t pthread_mutex_initializer(void)
106: {
107: pthread_mutex_t mutex;
108:
109: pthread_mutex_init(&mutex,NULL);
110:
111: return(mutex);
112: }
113:
114: #if !defined(_POSIX_THREADS)
115:
116: #if defined(__BORLANDC__)
117: #pragma argsused /* attr arg not used */
118: #endif
119: int pthread_mutex_init(pthread_mutex_t* mutex, void* attr)
120: {
121: #if defined(PTHREAD_MUTEX_AS_WIN32_MUTEX)
122: return ((((*mutex)=CreateMutex(/* security */NULL, /* owned */FALSE, /* name */NULL))==NULL) ? -1 : 0);
123: #elif defined(_WIN32) /* Win32 Critical Section */
124: InitializeCriticalSection(mutex);
125: return 0; /* No error */
126: #elif defined(__OS2__)
127: return DosCreateMutexSem(/* name */NULL, mutex, /* attr */0, /* owned */0);
128: #endif
129: }
130:
131: int pthread_mutex_lock(pthread_mutex_t* mutex)
132: {
133: #if defined(PTHREAD_MUTEX_AS_WIN32_MUTEX)
134: return (WaitForSingleObject(*mutex, INFINITE)==WAIT_OBJECT_0 ? 0 : EBUSY);
135: #elif defined(_WIN32) /* Win32 Critical Section */
136: EnterCriticalSection(mutex);
137: return 0; /* No error */
138: #elif defined(__OS2__)
139: return DosRequestMutexSem(*mutex, -1 /* SEM_INDEFINITE_WAIT */);
140: #endif
141: }
142:
143: int pthread_mutex_trylock(pthread_mutex_t* mutex)
144: {
145: #if defined(PTHREAD_MUTEX_AS_WIN32_MUTEX)
146: return (WaitForSingleObject(*mutex, 0)==WAIT_OBJECT_0 ? 0 : EBUSY);
147: #elif defined(_WIN32) /* Win32 Critical Section */
148: /* TryEnterCriticalSection only available on NT4+ :-( */
149: return (TryEnterCriticalSection(mutex) ? 0 : EBUSY);
150: #elif defined(__OS2__)
151: return DosRequestMutexSem(*mutex, 0 /* SEM_IMMEDIATE_RETURN */);
152: #endif
153: }
154:
155: int pthread_mutex_unlock(pthread_mutex_t* mutex)
156: {
157: #if defined(PTHREAD_MUTEX_AS_WIN32_MUTEX)
158: return (ReleaseMutex(*mutex) ? 0 : GetLastError());
159: #elif defined(_WIN32) /* Win32 Critical Section */
160: LeaveCriticalSection(mutex);
161: return 0; /* No error */
162: #elif defined(__OS2__)
163: return DosReleaseMutexSem(*mutex);
164: #endif
165: }
166:
167: int pthread_mutex_destroy(pthread_mutex_t* mutex)
168: {
169: #if defined(PTHREAD_MUTEX_AS_WIN32_MUTEX)
170: return (CloseHandle(*mutex) ? 0 : GetLastError());
171: #elif defined(_WIN32) /* Win32 Critical Section */
172: DeleteCriticalSection(mutex);
173: return 0; /* No error */
174: #elif defined(__OS2__)
175: return DosCloseMutexSem(*mutex);
176: #endif
177: }
178:
179: #endif /* POSIX thread mutexes */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.