~ubuntu-branches/ubuntu/natty/xmlrpc-c/natty

« back to all changes in this revision

Viewing changes to lib/abyss/src/thread_pthread.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2011-01-06 18:56:02 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20110106185602-09og2x3suqlzbf6s
Tags: 1.16.32-0ubuntu1
* New upstream version (stable release). LP: #659591.
  - No unresolved symbols in the shared libraries. LP: #690779.
  - Builds with --no-add-needed and --as-needed.
* Rename shared library packages.
* Add symbols files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#include <unistd.h>
2
 
#include <pthread.h>
3
2
#include <string.h>
4
3
#include <errno.h>
5
4
#include <signal.h>
6
5
 
7
6
#include "xmlrpc_config.h"
8
7
 
 
8
#include "bool.h"
9
9
#include "mallocvar.h"
 
10
#include "xmlrpc-c/util_int.h"
10
11
#include "xmlrpc-c/string_int.h"
 
12
#include "pthreadx.h"
11
13
 
12
14
#include "xmlrpc-c/abyss.h"
13
15
 
22
24
    TThreadDoneFn * threadDone;
23
25
};
24
26
 
25
 
/* We used to have THREAD_STACK_SIZE = 16K, which was said to be the
 
27
/* We used to have MIN_STACK_SIZE = 16K, which was said to be the
26
28
   minimum stack size on Win32.  Scott Kolodzeski found in November
27
29
   2005 that this was insufficient for 64 bit Solaris -- we fail
28
30
   when creating the first thread.  So we changed to 128K.
29
31
*/
30
 
#define  THREAD_STACK_SIZE (128*1024L)
 
32
#define  MIN_STACK_SIZE (128*1024L)
31
33
 
32
34
 
33
35
typedef void * (pthreadStartRoutine)(void *);
40
42
pthreadStart(void * const arg) {
41
43
 
42
44
    struct abyss_thread * const threadP = arg;
43
 
    abyss_bool const executeTrue = true;
 
45
    bool const executeTrue = true;
44
46
 
45
47
    pthread_cleanup_push(threadP->threadDone, threadP->userHandle);
46
48
 
48
50
 
49
51
    pthread_cleanup_pop(executeTrue);
50
52
 
 
53
    /* Note that func() may not return; it may just exit the thread,
 
54
       by calling ThreadExit(), in which case code here doesn't run.
 
55
    */
 
56
    threadP->threadDone(threadP->userHandle);
 
57
 
51
58
    return NULL;
52
59
}
53
60
 
54
61
 
55
62
 
 
63
 
56
64
void
57
65
ThreadCreate(TThread **      const threadPP,
58
66
             void *          const userHandle,
59
67
             TThreadProc   * const func,
60
68
             TThreadDoneFn * const threadDone,
61
 
             abyss_bool      const useSigchld ATTR_UNUSED,
 
69
             bool            const useSigchld ATTR_UNUSED,
 
70
             size_t          const stackSize,
62
71
             const char **   const errorP) {
63
72
 
64
 
    TThread * threadP;
65
 
 
66
 
    MALLOCVAR(threadP);
67
 
    if (threadP == NULL)
68
 
        xmlrpc_asprintf(errorP,
69
 
                        "Can't allocate memory for thread descriptor.");
 
73
    if ((size_t)(int)stackSize != stackSize)
 
74
        xmlrpc_asprintf(errorP, "Stack size %lu is too big",
 
75
                        (unsigned long)stackSize);
70
76
    else {
71
 
        pthread_attr_t attr;
72
 
        int rc;
73
 
 
74
 
        pthread_attr_init(&attr);
75
 
 
76
 
        pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
77
 
        
78
 
        threadP->userHandle = userHandle;
79
 
        threadP->func       = func;
80
 
        threadP->threadDone = threadDone;
81
 
 
82
 
        rc = pthread_create(&threadP->thread, &attr,
83
 
                            pthreadStart, threadP);
84
 
        if (rc == 0) {
85
 
            *errorP = NULL;
86
 
            *threadPP = threadP;
87
 
        } else
88
 
            xmlrpc_asprintf(
89
 
                errorP, "pthread_create() failed, errno = %d (%s)",
90
 
                errno, strerror(errno));
91
 
        
92
 
        pthread_attr_destroy(&attr);
93
 
 
94
 
        if (*errorP)
95
 
            free(threadP);
 
77
        TThread * threadP;
 
78
 
 
79
        MALLOCVAR(threadP);
 
80
        if (threadP == NULL)
 
81
            xmlrpc_asprintf(errorP,
 
82
                            "Can't allocate memory for thread descriptor.");
 
83
        else {
 
84
            pthread_attr_t attr;
 
85
            int rc;
 
86
 
 
87
            pthread_attr_init(&attr);
 
88
 
 
89
            pthread_attr_setstacksize(&attr, MAX(MIN_STACK_SIZE, stackSize));
 
90
        
 
91
            threadP->userHandle = userHandle;
 
92
            threadP->func       = func;
 
93
            threadP->threadDone = threadDone;
 
94
 
 
95
            rc = pthread_create(&threadP->thread, &attr,
 
96
                                pthreadStart, threadP);
 
97
            if (rc == 0) {
 
98
                *errorP = NULL;
 
99
                *threadPP = threadP;
 
100
            } else
 
101
                xmlrpc_asprintf(
 
102
                    errorP, "pthread_create() failed, errno = %d (%s)",
 
103
                    errno, strerror(errno));
 
104
        
 
105
            pthread_attr_destroy(&attr);
 
106
 
 
107
            if (*errorP)
 
108
                free(threadP);
 
109
        }
96
110
    }
97
111
}
98
112
 
99
113
 
100
114
 
101
 
abyss_bool
 
115
bool
102
116
ThreadRun(TThread * const threadP ATTR_UNUSED) {
103
117
    return TRUE;    
104
118
}
105
119
 
106
120
 
107
121
 
108
 
abyss_bool
 
122
bool
109
123
ThreadStop(TThread * const threadP ATTR_UNUSED) {
110
124
    return TRUE;
111
125
}
112
126
 
113
127
 
114
128
 
115
 
abyss_bool
 
129
bool
116
130
ThreadKill(TThread * const threadP ATTR_UNUSED) {
117
131
 
118
132
    return (pthread_kill(threadP->thread, SIGTERM) == 0);
133
147
 
134
148
 
135
149
void
136
 
ThreadExit(int const retValue) {
 
150
ThreadExit(TThread * const threadP ATTR_UNUSED,
 
151
           int       const retValue) {
137
152
 
138
153
    pthread_exit((void*)&retValue);
139
154
 
154
169
 
155
170
 
156
171
 
157
 
abyss_bool
 
172
bool
158
173
ThreadForks(void) {
159
174
 
160
175
    return FALSE;
184
199
** Mutex
185
200
*********************************************************************/
186
201
 
187
 
 
188
 
 
189
 
abyss_bool
190
 
MutexCreate(TMutex * const mutexP) {
191
 
 
192
 
    return (pthread_mutex_init(mutexP, NULL) == 0);
 
202
struct abyss_mutex {
 
203
    pthread_mutex_t pthreadMutex;
 
204
};
 
205
 
 
206
 
 
207
bool
 
208
MutexCreate(TMutex ** const mutexPP) {
 
209
 
 
210
    TMutex * mutexP;
 
211
    bool succeeded;
 
212
 
 
213
    MALLOCVAR(mutexP);
 
214
 
 
215
    if (mutexP) {
 
216
        int rc;
 
217
        rc = pthread_mutex_init(&mutexP->pthreadMutex, NULL);
 
218
 
 
219
        succeeded = (rc == 0);
 
220
    } else
 
221
        succeeded = FALSE;
 
222
 
 
223
    if (!succeeded)
 
224
        free(mutexP);
 
225
 
 
226
    *mutexPP = mutexP;
 
227
 
 
228
    return succeeded;
193
229
}
194
230
 
195
231
 
196
232
 
197
 
abyss_bool
 
233
bool
198
234
MutexLock(TMutex * const mutexP) {
199
 
    return (pthread_mutex_lock(mutexP) == 0);
 
235
    return (pthread_mutex_lock(&mutexP->pthreadMutex) == 0);
200
236
}
201
237
 
202
238
 
203
239
 
204
 
abyss_bool
 
240
bool
205
241
MutexUnlock(TMutex * const mutexP) {
206
 
    return (pthread_mutex_unlock(mutexP) == 0);
 
242
    return (pthread_mutex_unlock(&mutexP->pthreadMutex) == 0);
207
243
}
208
244
 
209
245
 
210
246
 
211
 
abyss_bool
 
247
bool
212
248
MutexTryLock(TMutex * const mutexP) {
213
 
    return (pthread_mutex_trylock(mutexP) == 0);
 
249
    return (pthread_mutex_trylock(&mutexP->pthreadMutex) == 0);
214
250
}
215
251
 
216
252
 
217
253
 
218
254
void
219
 
MutexFree(TMutex * const mutexP) {
220
 
    pthread_mutex_destroy(mutexP);
 
255
MutexDestroy(TMutex * const mutexP) {
 
256
    pthread_mutex_destroy(&mutexP->pthreadMutex);
 
257
 
 
258
    free(mutexP);
221
259
}