⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 my_pthread.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
字号:
/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB This file is public domain and comes with NO WARRANTY of any kind *//* Functions to get threads more portable */#include "mysys_priv.h"#ifdef THREAD#include <signal.h>#include <m_string.h>#include <thr_alarm.h>#include <assert.h>#if !defined(MSDOS) && !defined(__WIN__)#include <netdb.h>#endif#if (defined(__BSD__) || defined(_BSDI_VERSION)) && !defined(HAVE_mit_thread)#define SCHED_POLICY SCHED_RR#else#define SCHED_POLICY SCHED_OTHER#endif#ifndef my_pthread_setpriovoid my_pthread_setprio(pthread_t thread_id,int prior){#ifdef HAVE_PTHREAD_SETSCHEDPARAM  struct sched_param tmp_sched_param;  bzero((char*) &tmp_sched_param,sizeof(tmp_sched_param));  tmp_sched_param.sched_priority=prior;  VOID(pthread_setschedparam(thread_id,SCHED_POLICY,&tmp_sched_param));#endif}#endif#ifndef my_pthread_getprioint my_pthread_getprio(pthread_t thread_id){#ifdef HAVE_PTHREAD_SETSCHEDPARAM  struct sched_param tmp_sched_param;  int policy;  if (!pthread_getschedparam(thread_id,&policy,&tmp_sched_param))  {    DBUG_PRINT("thread",("policy: %d  priority: %d",			 policy,tmp_sched_param.sched_priority));    return tmp_sched_param.sched_priority;  }#endif  return -1;}#endif#ifndef my_pthread_attr_setpriovoid my_pthread_attr_setprio(pthread_attr_t *attr, int priority){#ifdef HAVE_PTHREAD_SETSCHEDPARAM  struct sched_param tmp_sched_param;  bzero((char*) &tmp_sched_param,sizeof(tmp_sched_param));  tmp_sched_param.sched_priority=priority;  VOID(pthread_attr_setschedparam(attr,&tmp_sched_param));#endif}#endif/* To allow use of pthread_getspecific with two arguments */#ifdef HAVE_NONPOSIX_PTHREAD_GETSPECIFIC#undef pthread_getspecific#ifdef HAVE_UNIXWARE7_THREADS#define pthread_getspecific thr_getspecific#endifvoid *my_pthread_getspecific_imp(pthread_key_t key){  void *value;  if (pthread_getspecific(key,(void *) &value))    return 0;  return value;}#endif/* Some functions for RTS threads, AIX, Siemens Unix and UnixWare 7   (and DEC OSF/1 3.2 too) */int my_pthread_create_detached=1;#if defined(HAVE_NONPOSIX_SIGWAIT) || defined(HAVE_DEC_3_2_THREADS)int my_sigwait(const sigset_t *set,int *sig){  int signal=sigwait((sigset_t*) set);  if (signal < 0)    return errno;  *sig=signal;  return 0;}#endif/* localtime_r for SCO 3.2V4.2 */#ifndef HAVE_LOCALTIME_Rextern pthread_mutex_t LOCK_localtime_r;struct tm *localtime_r(const time_t *clock, struct tm *res){  struct tm *tmp;  pthread_mutex_lock(&LOCK_localtime_r);  tmp=localtime(clock);  *res= *tmp;  pthread_mutex_unlock(&LOCK_localtime_r);  return res;}#endif/****************************************************************************** Replacement of sigwait if the system doesn't have one (like BSDI 3.0)**** Note:** This version of sigwait() is assumed to called in a loop so the signalmask** is permanently modified to reflect the signal set. This is done to get** a much faster implementation.**** This implementation isn't thread safe: It assumes that only one** thread is using sigwait.**** If one later supplies a different signal mask, all old signals that** was used before are unblocked and set to SIGDFL.**** Author: Gary Wisniewski <garyw@spidereye.com.au>, much modified by Monty****************************************************************************/#if !defined(HAVE_SIGWAIT) && !defined(HAVE_mit_thread) && !defined(sigwait) && !defined(__WIN__) && !defined(HAVE_rts_threads) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(OS2)#if !defined(DONT_USE_SIGSUSPEND)static sigset_t sigwait_set,rev_sigwait_set,px_recd;void px_handle_sig(int sig){  sigaddset(&px_recd, sig);}void sigwait_setup(sigset_t *set){  int i;  struct sigaction sact,sact1;  sigset_t unblock_mask;  sact.sa_flags = 0;  sact.sa_handler = px_handle_sig;  memcpy_fixed(&sact.sa_mask,set,sizeof(*set));	/* handler isn't thread_safe */  sigemptyset(&unblock_mask);  pthread_sigmask(SIG_UNBLOCK,(sigset_t*) 0,&rev_sigwait_set);  for (i = 1; i <= sizeof(sigwait_set)*8; i++)  {    if (sigismember(set,i))    {      sigdelset(&rev_sigwait_set,i);      if (!sigismember(&sigwait_set,i))	sigaction(i, &sact, (struct sigaction*) 0);    }    else    {      sigdelset(&px_recd,i);			/* Don't handle this */      if (sigismember(&sigwait_set,i))      {						/* Remove the old handler */	sigaddset(&unblock_mask,i);	sigdelset(&rev_sigwait_set,i);	sact1.sa_flags = 0;	sact1.sa_handler = SIG_DFL;	sigemptyset(&sact1.sa_mask);	sigaction(i, &sact1, 0);      }    }  }  memcpy_fixed(&sigwait_set,set,sizeof(*set));  pthread_sigmask(SIG_BLOCK,(sigset_t*) set,(sigset_t*) 0);  pthread_sigmask(SIG_UNBLOCK,&unblock_mask,(sigset_t*) 0);}int sigwait(sigset_t *setp, int *sigp){  if (memcmp(setp,&sigwait_set,sizeof(sigwait_set)))    sigwait_setup(setp);			/* Init or change of set */  for (;;)  {    /*      This is a fast, not 100% portable implementation to find the signal.      Because the handler is blocked there should be at most 1 bit set, but      the specification on this is somewhat shady so we use a set instead a      single variable.      */    ulong *ptr= (ulong*) &px_recd;    ulong *end=ptr+sizeof(px_recd)/sizeof(ulong);    for ( ; ptr != end ; ptr++)    {      if (*ptr)      {	ulong set= *ptr;	int found= (int) ((char*) ptr - (char*) &px_recd)*8+1;	while (!(set & 1))	{	  found++;	  set>>=1;	}	*sigp=found;	sigdelset(&px_recd,found);	return 0;      }    }    sigsuspend(&rev_sigwait_set);  }  return 0;}#else  /* !DONT_USE_SIGSUSPEND *//****************************************************************************** Replacement of sigwait if the system doesn't have one (like BSDI 3.0)**** Note:** This version of sigwait() is assumed to called in a loop so the signalmask** is permanently modified to reflect the signal set. This is done to get** a much faster implementation.**** This implementation uses a extra thread to handle the signals and one** must always call sigwait() with the same signal mask!**** BSDI 3.0 NOTE:**** pthread_kill() doesn't work on a thread in a select() or sleep() loop?** After adding the sleep to sigwait_thread, all signals are checked and** delivered every second. This isn't that terrible performance vice, but** someone should report this to BSDI and ask for a fix!** Another problem is that when the sleep() ends, every select() in other** threads are interrupted!****************************************************************************/static sigset_t pending_set;static bool inited=0;static pthread_cond_t  COND_sigwait;static pthread_mutex_t LOCK_sigwait;void sigwait_handle_sig(int sig){  pthread_mutex_lock(&LOCK_sigwait);  sigaddset(&pending_set, sig);  VOID(pthread_cond_signal(&COND_sigwait)); /* inform sigwait() about signal */  pthread_mutex_unlock(&LOCK_sigwait);}extern pthread_t alarm_thread;void *sigwait_thread(void *set_arg){  sigset_t *set=(sigset_t*) set_arg;  int i;  struct sigaction sact;  sact.sa_flags = 0;  sact.sa_handler = sigwait_handle_sig;  memcpy_fixed(&sact.sa_mask,set,sizeof(*set));	/* handler isn't thread_safe */  sigemptyset(&pending_set);  for (i = 1; i <= sizeof(pending_set)*8; i++)  {    if (sigismember(set,i))    {      sigaction(i, &sact, (struct sigaction*) 0);    }  }  sigaddset(set,THR_CLIENT_ALARM);  pthread_sigmask(SIG_UNBLOCK,(sigset_t*) set,(sigset_t*) 0);  alarm_thread=pthread_self();			/* For thr_alarm */  for (;;)  {						/* Wait for signals */#ifdef HAVE_NOT_BROKEN_SELECT    fd_set fd;    FD_ZERO(&fd);    select(0,&fd,0,0,0);#else    sleep(1);					/* Because of broken BSDI */#endif  }}int sigwait(sigset_t *setp, int *sigp){  if (!inited)  {    pthread_attr_t thr_attr;    pthread_t sigwait_thread_id;    inited=1;    sigemptyset(&pending_set);    pthread_mutex_init(&LOCK_sigwait,MY_MUTEX_INIT_FAST);    pthread_cond_init(&COND_sigwait,NULL);    pthread_attr_init(&thr_attr);    pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);    pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);    pthread_attr_setstacksize(&thr_attr,8196);    my_pthread_attr_setprio(&thr_attr,100);	/* Very high priority */    VOID(pthread_create(&sigwait_thread_id,&thr_attr,sigwait_thread,setp));    VOID(pthread_attr_destroy(&thr_attr));  }  pthread_mutex_lock(&LOCK_sigwait);  for (;;)  {    ulong *ptr= (ulong*) &pending_set;    ulong *end=ptr+sizeof(pending_set)/sizeof(ulong);    for ( ; ptr != end ; ptr++)    {      if (*ptr)      {	ulong set= *ptr;	int found= (int) ((char*) ptr - (char*) &pending_set)*8+1;	while (!(set & 1))	{	  found++;	  set>>=1;	}	*sigp=found;	sigdelset(&pending_set,found);	pthread_mutex_unlock(&LOCK_sigwait);	return 0;      }    }    VOID(pthread_cond_wait(&COND_sigwait,&LOCK_sigwait));  }  return 0;}#endif /* DONT_USE_SIGSUSPEND */#endif /* HAVE_SIGWAIT *//******************************************************************************* Implement pthread_signal for systems that can't use signal() with threads** Currently this is only used with BSDI 3.0*****************************************************************************/#ifdef USE_PTHREAD_SIGNALint pthread_signal(int sig, void (*func)()){  struct sigaction sact;  sact.sa_flags= 0;  sact.sa_handler= func;  sigemptyset(&sact.sa_mask);  sigaction(sig, &sact, (struct sigaction*) 0);  return 0;}#endif/******************************************************************************* Patches for AIX and DEC OSF/1 3.2*****************************************************************************/#if (defined(HAVE_NONPOSIX_PTHREAD_MUTEX_INIT) && !defined(HAVE_UNIXWARE7_THREADS)) || defined(HAVE_DEC_3_2_THREADS)#undef pthread_mutex_init#undef pthread_cond_init#include <netdb.h>int my_pthread_mutex_init(pthread_mutex_t *mp, const pthread_mutexattr_t *attr){  int error;  if (!attr)    error=pthread_mutex_init(mp,pthread_mutexattr_default);  else    error=pthread_mutex_init(mp,*attr);  return error;}int my_pthread_cond_init(pthread_cond_t *mp, const pthread_condattr_t *attr){  int error;  if (!attr)    error=pthread_cond_init(mp,pthread_condattr_default);  else    error=pthread_cond_init(mp,*attr);  return error;}#endif/*** Emulate SOLARIS style calls, not because it's better, but just to make the** usage of getbostbyname_r simpler.*/#if !defined(my_gethostbyname_r) && defined(HAVE_GETHOSTBYNAME_R)#if defined(HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE)struct hostent *my_gethostbyname_r(const char *name,				   struct hostent *result, char *buffer,				   int buflen, int *h_errnop){  struct hostent *hp;  dbug_assert((size_t) buflen >= sizeof(*result));  if (gethostbyname_r(name,result, buffer, (size_t) buflen, &hp, h_errnop))    return 0;  return hp;}#elif defined(HAVE_GETHOSTBYNAME_R_RETURN_INT)struct hostent *my_gethostbyname_r(const char *name,				   struct hostent *result, char *buffer,				   int buflen, int *h_errnop){  dbug_assert(buflen >= sizeof(struct hostent_data));  if (gethostbyname_r(name,result,(struct hostent_data *) buffer) == -1)  {    *h_errnop= errno;    return 0;  }  return result;}#elsestruct hostent *my_gethostbyname_r(const char *name,				   struct hostent *result, char *buffer,				   int buflen, int *h_errnop){  struct hostent *hp;  dbug_assert(buflen >= sizeof(struct hostent_data));  hp= gethostbyname_r(name,result,(struct hostent_data *) buffer);  *h_errnop= errno;  return hp;}#endif /* GLIBC2_STYLE_GETHOSTBYNAME_R */#endif/* Some help functions */int pthread_no_free(void *not_used __attribute__((unused))){  return 0;}int pthread_dummy(int ret){  return ret;}#endif /* THREAD */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -