26
26
uint thd_lib_detected= 0;
28
#ifndef my_pthread_getprio
29
int my_pthread_getprio(pthread_t thread_id)
31
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
32
struct sched_param tmp_sched_param;
34
if (!pthread_getschedparam(thread_id,&policy,&tmp_sched_param))
36
return tmp_sched_param.sched_priority;
43
#ifndef my_pthread_attr_setprio
44
void my_pthread_attr_setprio(pthread_attr_t *attr, int priority)
46
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
47
struct sched_param tmp_sched_param;
48
bzero((char*) &tmp_sched_param,sizeof(tmp_sched_param));
49
tmp_sched_param.sched_priority=priority;
50
VOID(pthread_attr_setschedparam(attr,&tmp_sched_param));
56
Some functions for RTS threads, AIX, Siemens Unix and UnixWare 7
57
(and DEC OSF/1 3.2 too)
60
28
int my_pthread_create_detached=1;
62
#if defined(HAVE_NONPOSIX_SIGWAIT)
64
int my_sigwait(const sigset_t *set,int *sig)
66
int signal=sigwait((sigset_t*) set);
74
/* localtime_r for SCO 3.2V4.2 */
76
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
78
extern pthread_mutex_t LOCK_localtime_r;
82
#if !defined(HAVE_LOCALTIME_R)
83
struct tm *localtime_r(const time_t *clock, struct tm *res)
86
pthread_mutex_lock(&LOCK_localtime_r);
89
pthread_mutex_unlock(&LOCK_localtime_r);
94
#if !defined(HAVE_GMTIME_R)
96
Reentrant version of standard gmtime() function.
97
Needed on some systems which don't implement it.
100
struct tm *gmtime_r(const time_t *clock, struct tm *res)
103
pthread_mutex_lock(&LOCK_localtime_r);
106
pthread_mutex_unlock(&LOCK_localtime_r);
111
/****************************************************************************
112
** Replacement of sigwait if the system doesn't have one (like BSDI 3.0)
115
** This version of sigwait() is assumed to called in a loop so the signalmask
116
** is permanently modified to reflect the signal set. This is done to get
117
** a much faster implementation.
119
** This implementation isn't thread safe: It assumes that only one
120
** thread is using sigwait.
122
** If one later supplies a different signal mask, all old signals that
123
** was used before are unblocked and set to SIGDFL.
125
** Author: Gary Wisniewski <garyw@spidereye.com.au>, much modified by Monty
126
****************************************************************************/
128
#if !defined(HAVE_SIGWAIT) && !defined(sigwait) && !defined(HAVE_rts_threads) && !defined(HAVE_NONPOSIX_SIGWAIT)
130
#if !defined(DONT_USE_SIGSUSPEND)
132
static sigset_t sigwait_set,rev_sigwait_set,px_recd;
134
void px_handle_sig(int sig)
136
sigaddset(&px_recd, sig);
140
void sigwait_setup(sigset_t *set)
143
struct sigaction sact,sact1;
144
sigset_t unblock_mask;
147
sact.sa_handler = px_handle_sig;
148
memcpy_fixed(&sact.sa_mask,set,sizeof(*set)); /* handler isn't thread_safe */
149
sigemptyset(&unblock_mask);
150
pthread_sigmask(SIG_UNBLOCK,(sigset_t*) 0,&rev_sigwait_set);
152
for (i = 1; i <= sizeof(sigwait_set)*8; i++)
154
if (sigismember(set,i))
156
sigdelset(&rev_sigwait_set,i);
157
if (!sigismember(&sigwait_set,i))
158
sigaction(i, &sact, (struct sigaction*) 0);
162
sigdelset(&px_recd,i); /* Don't handle this */
163
if (sigismember(&sigwait_set,i))
164
{ /* Remove the old handler */
165
sigaddset(&unblock_mask,i);
166
sigdelset(&rev_sigwait_set,i);
168
sact1.sa_handler = SIG_DFL;
169
sigemptyset(&sact1.sa_mask);
170
sigaction(i, &sact1, 0);
174
memcpy_fixed(&sigwait_set,set,sizeof(*set));
175
pthread_sigmask(SIG_BLOCK,(sigset_t*) set,(sigset_t*) 0);
176
pthread_sigmask(SIG_UNBLOCK,&unblock_mask,(sigset_t*) 0);
180
int sigwait(sigset_t *setp, int *sigp)
182
if (memcmp(setp,&sigwait_set,sizeof(sigwait_set)))
183
sigwait_setup(setp); /* Init or change of set */
188
This is a fast, not 100% portable implementation to find the signal.
189
Because the handler is blocked there should be at most 1 bit set, but
190
the specification on this is somewhat shady so we use a set instead a
194
ulong *ptr= (ulong*) &px_recd;
195
ulong *end=ptr+sizeof(px_recd)/sizeof(ulong);
197
for ( ; ptr != end ; ptr++)
202
int found= (int) ((char*) ptr - (char*) &px_recd)*8+1;
209
sigdelset(&px_recd,found);
213
sigsuspend(&rev_sigwait_set);
217
#else /* !DONT_USE_SIGSUSPEND */
219
/****************************************************************************
220
** Replacement of sigwait if the system doesn't have one (like BSDI 3.0)
223
** This version of sigwait() is assumed to called in a loop so the signalmask
224
** is permanently modified to reflect the signal set. This is done to get
225
** a much faster implementation.
227
** This implementation uses a extra thread to handle the signals and one
228
** must always call sigwait() with the same signal mask!
232
** pthread_kill() doesn't work on a thread in a select() or sleep() loop?
233
** After adding the sleep to sigwait_thread, all signals are checked and
234
** delivered every second. This isn't that terrible performance vice, but
235
** someone should report this to BSDI and ask for a fix!
236
** Another problem is that when the sleep() ends, every select() in other
237
** threads are interrupted!
238
****************************************************************************/
240
static sigset_t pending_set;
241
static bool inited=0;
242
static pthread_cond_t COND_sigwait;
243
static pthread_mutex_t LOCK_sigwait;
246
void sigwait_handle_sig(int sig)
248
pthread_mutex_lock(&LOCK_sigwait);
249
sigaddset(&pending_set, sig);
250
VOID(pthread_cond_signal(&COND_sigwait)); /* inform sigwait() about signal */
251
pthread_mutex_unlock(&LOCK_sigwait);
254
void *sigwait_thread(void *set_arg)
256
sigset_t *set=(sigset_t*) set_arg;
259
struct sigaction sact;
261
sact.sa_handler = sigwait_handle_sig;
262
memcpy_fixed(&sact.sa_mask,set,sizeof(*set)); /* handler isn't thread_safe */
263
sigemptyset(&pending_set);
265
for (i = 1; i <= sizeof(pending_set)*8; i++)
267
if (sigismember(set,i))
269
sigaction(i, &sact, (struct sigaction*) 0);
272
/* Ensure that init_thr_alarm() is called */
273
DBUG_ASSERT(thr_client_alarm);
274
sigaddset(set, thr_client_alarm);
275
pthread_sigmask(SIG_UNBLOCK,(sigset_t*) set,(sigset_t*) 0);
276
alarm_thread=pthread_self(); /* For thr_alarm */
279
{ /* Wait for signals */
280
#ifdef HAVE_NOT_BROKEN_SELECT
285
sleep(1); /* Because of broken BSDI */
291
int sigwait(sigset_t *setp, int *sigp)
295
pthread_attr_t thr_attr;
296
pthread_t sigwait_thread_id;
298
sigemptyset(&pending_set);
299
pthread_mutex_init(&LOCK_sigwait,MY_MUTEX_INIT_FAST);
300
pthread_cond_init(&COND_sigwait,NULL);
302
pthread_attr_init(&thr_attr);
303
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
304
pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
305
pthread_attr_setstacksize(&thr_attr,8196);
306
my_pthread_attr_setprio(&thr_attr,100); /* Very high priority */
307
VOID(pthread_create(&sigwait_thread_id,&thr_attr,sigwait_thread,setp));
308
VOID(pthread_attr_destroy(&thr_attr));
311
pthread_mutex_lock(&LOCK_sigwait);
314
ulong *ptr= (ulong*) &pending_set;
315
ulong *end=ptr+sizeof(pending_set)/sizeof(ulong);
317
for ( ; ptr != end ; ptr++)
322
int found= (int) ((char*) ptr - (char*) &pending_set)*8+1;
329
sigdelset(&pending_set,found);
330
pthread_mutex_unlock(&LOCK_sigwait);
334
VOID(pthread_cond_wait(&COND_sigwait,&LOCK_sigwait));
339
#endif /* DONT_USE_SIGSUSPEND */
340
#endif /* HAVE_SIGWAIT */
343
30
/****************************************************************************
344
31
The following functions fixes that all pthread functions should work
345
32
according to latest posix standard