summaryrefslogtreecommitdiff
path: root/mysys/thr_alarm.c
diff options
context:
space:
mode:
Diffstat (limited to 'mysys/thr_alarm.c')
-rw-r--r--mysys/thr_alarm.c241
1 files changed, 63 insertions, 178 deletions
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index d11883a4ea4..afa5aadece7 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -14,8 +14,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* To avoid problems with alarms in debug code, we disable DBUG here */
-#undef DBUG_OFF
-#define DBUG_OFF
+#define FORCE_DBUG_OFF
#include <my_global.h>
#if defined(THREAD) && !defined(DONT_USE_THR_ALARM)
@@ -39,10 +38,10 @@ uint thr_client_alarm;
static int alarm_aborted=1; /* No alarm thread */
my_bool thr_alarm_inited= 0;
volatile my_bool alarm_thread_running= 0;
-
+time_t next_alarm_expire_time= ~ (time_t) 0;
static sig_handler process_alarm_part2(int sig);
-#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
+#if !defined(__WIN__)
static pthread_mutex_t LOCK_alarm;
static pthread_cond_t COND_alarm;
@@ -61,7 +60,7 @@ static void *alarm_handler(void *arg);
static sig_handler thread_alarm(int sig __attribute__((unused)));
static int compare_ulong(void *not_used __attribute__((unused)),
- byte *a_ptr,byte* b_ptr)
+ uchar *a_ptr,uchar* b_ptr)
{
ulong a=*((ulong*) a_ptr),b= *((ulong*) b_ptr);
return (a < b) ? -1 : (a == b) ? 0 : 1;
@@ -72,6 +71,7 @@ void init_thr_alarm(uint max_alarms)
sigset_t s;
DBUG_ENTER("init_thr_alarm");
alarm_aborted=0;
+ next_alarm_expire_time= ~ (time_t) 0;
init_queue(&alarm_queue,max_alarms+1,offsetof(ALARM,expire_time),0,
compare_ulong,NullS);
sigfillset(&full_signal_set); /* Neaded to block signals */
@@ -151,21 +151,28 @@ void resize_thr_alarm(uint max_alarms)
my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
{
- ulong now;
+ time_t now;
+#ifndef USE_ONE_SIGNAL_HAND
sigset_t old_mask;
+#endif
my_bool reschedule;
+ struct st_my_thread_var *current_my_thread_var= my_thread_var;
DBUG_ENTER("thr_alarm");
DBUG_PRINT("enter",("thread: %s sec: %d",my_thread_name(),sec));
- now=(ulong) time((time_t*) 0);
+ now= my_time(0);
+#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
+#endif
pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
if (alarm_aborted > 0)
{ /* No signal thread */
DBUG_PRINT("info", ("alarm aborted"));
*alrm= 0; /* No alarm */
pthread_mutex_unlock(&LOCK_alarm);
+#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
+#endif
DBUG_RETURN(1);
}
if (alarm_aborted < 0)
@@ -179,14 +186,14 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
fprintf(stderr,"Warning: thr_alarm queue is full\n");
*alrm= 0; /* No alarm */
pthread_mutex_unlock(&LOCK_alarm);
+#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
+#endif
DBUG_RETURN(1);
}
max_used_alarms=alarm_queue.elements+1;
}
- reschedule= (!alarm_queue.elements ||
- (int) (((ALARM*) queue_top(&alarm_queue))->expire_time - now) >
- (int) sec);
+ reschedule= (ulong) next_alarm_expire_time > (ulong) now + sec;
if (!alarm_data)
{
if (!(alarm_data=(ALARM*) my_malloc(sizeof(ALARM),MYF(MY_WME))))
@@ -194,7 +201,9 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
DBUG_PRINT("info", ("failed my_malloc()"));
*alrm= 0; /* No alarm */
pthread_mutex_unlock(&LOCK_alarm);
+#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
+#endif
DBUG_RETURN(1);
}
alarm_data->malloced=1;
@@ -203,20 +212,26 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
alarm_data->malloced=0;
alarm_data->expire_time=now+sec;
alarm_data->alarmed=0;
- alarm_data->thread=pthread_self();
- queue_insert(&alarm_queue,(byte*) alarm_data);
+ alarm_data->thread= current_my_thread_var->pthread_self;
+ alarm_data->thread_id= current_my_thread_var->id;
+ queue_insert(&alarm_queue,(uchar*) alarm_data);
/* Reschedule alarm if the current one has more than sec left */
if (reschedule)
{
DBUG_PRINT("info", ("reschedule"));
if (pthread_equal(pthread_self(),alarm_thread))
+ {
alarm(sec); /* purecov: inspected */
+ next_alarm_expire_time= now + sec;
+ }
else
reschedule_alarms(); /* Reschedule alarms */
}
pthread_mutex_unlock(&LOCK_alarm);
+#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
+#endif
(*alrm)= &alarm_data->alarmed;
DBUG_RETURN(0);
}
@@ -229,21 +244,25 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
void thr_end_alarm(thr_alarm_t *alarmed)
{
ALARM *alarm_data;
+#ifndef USE_ONE_SIGNAL_HAND
sigset_t old_mask;
+#endif
uint i, found=0;
DBUG_ENTER("thr_end_alarm");
+#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
+#endif
pthread_mutex_lock(&LOCK_alarm);
- alarm_data= (ALARM*) ((byte*) *alarmed - offsetof(ALARM,alarmed));
+ alarm_data= (ALARM*) ((uchar*) *alarmed - offsetof(ALARM,alarmed));
for (i=0 ; i < alarm_queue.elements ; i++)
{
if ((ALARM*) queue_element(&alarm_queue,i) == alarm_data)
{
queue_remove(&alarm_queue,i),MYF(0);
if (alarm_data->malloced)
- my_free((gptr) alarm_data,MYF(0));
+ my_free((uchar*) alarm_data,MYF(0));
found++;
#ifdef DBUG_OFF
break;
@@ -260,7 +279,9 @@ void thr_end_alarm(thr_alarm_t *alarmed)
(long) *alarmed));
}
pthread_mutex_unlock(&LOCK_alarm);
+#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
+#endif
DBUG_VOID_RETURN;
}
@@ -350,7 +371,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
}
else
{
- ulong now=(ulong) time((time_t*) 0);
+ ulong now=(ulong) my_time(0);
ulong next=now+10-(now%10);
while ((alarm_data=(ALARM*) queue_top(&alarm_queue))->expire_time <= now)
{
@@ -379,10 +400,18 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
alarm(0); /* Remove old alarm */
#endif
alarm((uint) (alarm_data->expire_time-now));
+ next_alarm_expire_time= alarm_data->expire_time;
}
#endif
}
}
+ else
+ {
+ /*
+ Ensure that next time we call thr_alarm(), we will schedule a new alarm
+ */
+ next_alarm_expire_time= ~(time_t) 0;
+ }
DBUG_VOID_RETURN;
}
@@ -451,7 +480,7 @@ void end_thr_alarm(my_bool free_structures)
Remove another thread from the alarm
*/
-void thr_alarm_kill(pthread_t thread_id)
+void thr_alarm_kill(my_thread_id thread_id)
{
uint i;
if (alarm_aborted)
@@ -459,12 +488,11 @@ void thr_alarm_kill(pthread_t thread_id)
pthread_mutex_lock(&LOCK_alarm);
for (i=0 ; i < alarm_queue.elements ; i++)
{
- if (pthread_equal(((ALARM*) queue_element(&alarm_queue,i))->thread,
- thread_id))
+ if (((ALARM*) queue_element(&alarm_queue,i))->thread_id == thread_id)
{
ALARM *tmp=(ALARM*) queue_remove(&alarm_queue,i);
tmp->expire_time=0;
- queue_insert(&alarm_queue,(byte*) tmp);
+ queue_insert(&alarm_queue,(uchar*) tmp);
reschedule_alarms();
break;
}
@@ -480,7 +508,7 @@ void thr_alarm_info(ALARM_INFO *info)
info->max_used_alarms= max_used_alarms;
if ((info->active_alarms= alarm_queue.elements))
{
- ulong now=(ulong) time((time_t*) 0);
+ ulong now=(ulong) my_time(0);
long time_diff;
ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue);
time_diff= (long) (alarm_data->expire_time - now);
@@ -528,7 +556,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
{
if (alarm_queue.elements)
{
- ulong sleep_time,now=time((time_t*) 0);
+ ulong sleep_time,now= my_time(0);
if (alarm_aborted)
sleep_time=now+1;
else
@@ -537,6 +565,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
{
abstime.tv_sec=sleep_time;
abstime.tv_nsec=0;
+ next_alarm_expire_time= sleep_time;
if ((error=pthread_cond_timedwait(&COND_alarm,&LOCK_alarm,&abstime)) &&
error != ETIME && error != ETIMEDOUT)
{
@@ -549,12 +578,16 @@ static void *alarm_handler(void *arg __attribute__((unused)))
}
else if (alarm_aborted == -1)
break;
- else if ((error=pthread_cond_wait(&COND_alarm,&LOCK_alarm)))
+ else
{
+ next_alarm_expire_time= ~ (time_t) 0;
+ if ((error=pthread_cond_wait(&COND_alarm,&LOCK_alarm)))
+ {
#ifdef MAIN
- printf("Got error: %d from ptread_cond_wait (errno: %d)\n",
- error,errno);
+ printf("Got error: %d from ptread_cond_wait (errno: %d)\n",
+ error,errno);
#endif
+ }
}
process_alarm(0);
}
@@ -568,151 +601,12 @@ static void *alarm_handler(void *arg __attribute__((unused)))
#endif /* USE_ALARM_THREAD */
/*****************************************************************************
- thr_alarm for OS/2
-*****************************************************************************/
-
-#elif defined(__EMX__) || defined(OS2)
-
-#define INCL_BASE
-#define INCL_NOPMAPI
-#include <os2.h>
-
-static pthread_mutex_t LOCK_alarm;
-static sigset_t full_signal_set;
-static QUEUE alarm_queue;
-pthread_t alarm_thread;
-
-#ifdef USE_ALARM_THREAD
-static pthread_cond_t COND_alarm;
-static void *alarm_handler(void *arg);
-#define reschedule_alarms() pthread_cond_signal(&COND_alarm)
-#else
-#define reschedule_alarms() pthread_kill(alarm_thread,THR_SERVER_ALARM)
-#endif
-
-sig_handler process_alarm(int sig __attribute__((unused)))
-{
- sigset_t old_mask;
- ALARM *alarm_data;
- DBUG_PRINT("info",("sig: %d active alarms: %d",sig,alarm_queue.elements));
-}
-
-
-/*
- Remove another thread from the alarm
-*/
-
-void thr_alarm_kill(pthread_t thread_id)
-{
- uint i;
-
- pthread_mutex_lock(&LOCK_alarm);
- for (i=0 ; i < alarm_queue.elements ; i++)
- {
- if (pthread_equal(((ALARM*) queue_element(&alarm_queue,i))->thread,
- thread_id))
- {
- ALARM *tmp=(ALARM*) queue_remove(&alarm_queue,i);
- tmp->expire_time=0;
- queue_insert(&alarm_queue,(byte*) tmp);
- reschedule_alarms();
- break;
- }
- }
- pthread_mutex_unlock(&LOCK_alarm);
-}
-
-bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm)
-{
- APIRET rc;
- if (alarm_aborted)
- {
- alarm->alarmed.crono=0;
- alarm->alarmed.event=0;
- return 1;
- }
- if (rc = DosCreateEventSem(NULL,(HEV *) &alarm->alarmed.event,
- DC_SEM_SHARED,FALSE))
- {
- printf("Error creating event semaphore! [%d] \n",rc);
- alarm->alarmed.crono=0;
- alarm->alarmed.event=0;
- return 1;
- }
- if (rc = DosAsyncTimer((long) sec*1000L, (HSEM) alarm->alarmed.event,
- (HTIMER *) &alarm->alarmed.crono))
- {
- printf("Error starting async timer! [%d] \n",rc);
- DosCloseEventSem((HEV) alarm->alarmed.event);
- alarm->alarmed.crono=0;
- alarm->alarmed.event=0;
- return 1;
- } /* endif */
- (*alrm)= &alarm->alarmed;
- return 1;
-}
-
-
-bool thr_got_alarm(thr_alarm_t *alrm_ptr)
-{
- thr_alarm_t alrm= *alrm_ptr;
- APIRET rc;
-
- if (alrm->crono)
- {
- rc = DosWaitEventSem((HEV) alrm->event, SEM_IMMEDIATE_RETURN);
- if (rc == 0) {
- DosCloseEventSem((HEV) alrm->event);
- alrm->crono = 0;
- alrm->event = 0;
- } /* endif */
- }
- return !alrm->crono || alarm_aborted;
-}
-
-
-void thr_end_alarm(thr_alarm_t *alrm_ptr)
-{
- thr_alarm_t alrm= *alrm_ptr;
- if (alrm->crono)
- {
- DosStopTimer((HTIMER) alrm->crono);
- DosCloseEventSem((HEV) alrm->event);
- alrm->crono = 0;
- alrm->event = 0;
- }
-}
-
-void end_thr_alarm(my_bool free_structures)
-{
- DBUG_ENTER("end_thr_alarm");
- alarm_aborted=1; /* No more alarms */
- DBUG_VOID_RETURN;
-}
-
-void init_thr_alarm(uint max_alarm)
-{
- DBUG_ENTER("init_thr_alarm");
- alarm_aborted=0; /* Yes, Gimmie alarms */
- DBUG_VOID_RETURN;
-}
-
-void thr_alarm_info(ALARM_INFO *info)
-{
- bzero((char*) info, sizeof(*info));
-}
-
-void resize_thr_alarm(uint max_alarms)
-{
-}
-
-/*****************************************************************************
thr_alarm for win95
*****************************************************************************/
#else /* __WIN__ */
-void thr_alarm_kill(pthread_t thread_id)
+void thr_alarm_kill(my_thread_id thread_id)
{
/* Can't do this yet */
}
@@ -824,7 +718,7 @@ static void *test_thread(void *arg)
for (i=1 ; i <= 10 ; i++)
{
wait_time=param ? 11-i : i;
- start_time=time((time_t*) 0);
+ start_time= my_time(0);
if (thr_alarm(&got_alarm,wait_time,0))
{
printf("Thread: %s Alarms aborted\n",my_thread_name());
@@ -886,7 +780,7 @@ static void *test_thread(void *arg)
}
}
printf("Thread: %s Slept for %d (%d) sec\n",my_thread_name(),
- (int) (time((time_t*) 0)-start_time), wait_time); fflush(stdout);
+ (int) (my_time(0)-start_time), wait_time); fflush(stdout);
thr_end_alarm(&got_alarm);
fflush(stdout);
}
@@ -894,7 +788,7 @@ static void *test_thread(void *arg)
thread_count--;
VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
pthread_mutex_unlock(&LOCK_thread_count);
- free((gptr) arg);
+ free((uchar*) arg);
return 0;
}
@@ -906,10 +800,8 @@ static sig_handler print_signal_warning(int sig)
#ifdef DONT_REMEMBER_SIGNAL
my_sigset(sig,print_signal_warning); /* int. thread system calls */
#endif
-#ifndef OS2
if (sig == SIGALRM)
alarm(2); /* reschedule alarm */
-#endif
}
#endif /* USE_ONE_SIGNAL_HAND */
@@ -926,7 +818,6 @@ static void *signal_hand(void *arg __attribute__((unused)))
VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
pthread_mutex_unlock(&LOCK_thread_count);
-#ifndef OS2
sigemptyset(&set); /* Catch all signals */
sigaddset(&set,SIGINT);
sigaddset(&set,SIGQUIT);
@@ -941,7 +832,6 @@ static void *signal_hand(void *arg __attribute__((unused)))
#else
puts("Starting signal handling thread");
#endif
-#endif /* OS2 */
printf("server alarm: %d thread alarm: %d\n",
THR_SERVER_ALARM, thr_client_alarm);
DBUG_PRINT("info",("Starting signal and alarm handling thread"));
@@ -964,9 +854,7 @@ static void *signal_hand(void *arg __attribute__((unused)))
case SIGINT:
case SIGQUIT:
case SIGTERM:
-#ifndef OS2
case SIGHUP:
-#endif
printf("Aborting nicely\n");
end_thr_alarm(0);
break;
@@ -976,13 +864,11 @@ static void *signal_hand(void *arg __attribute__((unused)))
exit(1);
return 0; /* Keep some compilers happy */
#endif
-#ifndef OS2
#ifdef USE_ONE_SIGNAL_HAND
case THR_SERVER_ALARM:
process_alarm(sig);
break;
#endif
-#endif /* OS2 */
}
}
}
@@ -998,13 +884,13 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
MY_INIT(argv[0]);
if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '#')
+ {
DBUG_PUSH(argv[1]+2);
-
+ }
pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
pthread_cond_init(&COND_thread_count,NULL);
/* Start a alarm handling thread */
-#ifndef OS2
sigemptyset(&set);
sigaddset(&set,SIGINT);
sigaddset(&set,SIGQUIT);
@@ -1022,7 +908,6 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
sigaddset(&set, thr_client_alarm);
VOID(pthread_sigmask(SIG_UNBLOCK, &set, (sigset_t*) 0));
#endif
-#endif /* OS2 */
pthread_attr_init(&thr_attr);
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);