~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/os/os0sync.c

  • Committer: Lee Bieber
  • Date: 2010-12-23 02:14:02 UTC
  • mfrom: (2021.1.2 build)
  • Revision ID: kalebral@gmail.com-20101223021402-o4zhdsv3x8s0q6pz
Merge Stewart - Update innobase plugin to be based on innodb 1.1.4 from MySQL 5.5.8 
Merge Marisa - fixed markup in 'administrative.rst', which was throwing an error in the build

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
Created 9/6/1995 Heikki Tuuri
25
25
*******************************************************/
 
26
#include "univ.i"
 
27
 
 
28
#include <errno.h>
26
29
 
27
30
#include "os0sync.h"
28
31
#ifdef UNIV_NONINL
73
76
UNIV_INTERN ulint       os_mutex_count          = 0;
74
77
UNIV_INTERN ulint       os_fast_mutex_count     = 0;
75
78
 
 
79
/* The number of microsecnds in a second. */
 
80
static const ulint MICROSECS_IN_A_SECOND = 1000000;
 
81
 
76
82
/* Because a mutex is embedded inside an event and there is an
77
83
event embedded inside a mutex, on free, this generates a recursive call.
78
84
This version of the free event function doesn't acquire the global lock */
123
129
}
124
130
 
125
131
/*********************************************************//**
 
132
Do a timed wait on condition variable.
 
133
@return TRUE if timed out, FALSE otherwise */
 
134
UNIV_INLINE
 
135
ibool
 
136
os_cond_wait_timed(
 
137
/*===============*/
 
138
        os_cond_t*              cond,           /*!< in: condition variable. */
 
139
        os_fast_mutex_t*        mutex,          /*!< in: fast mutex */
 
140
#ifndef __WIN__
 
141
        const struct timespec*  abstime         /*!< in: timeout */
 
142
#else
 
143
        DWORD                   time_in_ms      /*!< in: timeout in
 
144
                                                milliseconds*/
 
145
#endif /* !__WIN__ */
 
146
)
 
147
{
 
148
#ifdef __WIN__
 
149
        BOOL    ret;
 
150
        DWORD   err;
 
151
 
 
152
        ut_a(sleep_condition_variable != NULL);
 
153
 
 
154
        ret = sleep_condition_variable(cond, mutex, time_in_ms);
 
155
 
 
156
        if (!ret) {
 
157
                err = GetLastError();
 
158
                /* From http://msdn.microsoft.com/en-us/library/ms686301%28VS.85%29.aspx,
 
159
                "Condition variables are subject to spurious wakeups
 
160
                (those not associated with an explicit wake) and stolen wakeups
 
161
                (another thread manages to run before the woken thread)."
 
162
                Check for both types of timeouts.
 
163
                Conditions are checked by the caller.*/
 
164
                if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) {
 
165
                        return(TRUE);
 
166
                }
 
167
        }
 
168
 
 
169
        ut_a(ret);
 
170
 
 
171
        return(FALSE);
 
172
#else
 
173
        int     ret;
 
174
 
 
175
        ret = pthread_cond_timedwait(cond, mutex, abstime);
 
176
 
 
177
        switch (ret) {
 
178
        case 0:
 
179
        case ETIMEDOUT:
 
180
        /* We play it safe by checking for EINTR even though
 
181
        according to the POSIX documentation it can't return EINTR. */
 
182
        case EINTR:
 
183
                break;
 
184
 
 
185
        default:
 
186
                fprintf(stderr, "  InnoDB: pthread_cond_timedwait() returned: "
 
187
                                "%d: abstime={%lu,%lu}\n",
 
188
                                ret, (ulong) abstime->tv_sec, (ulong) abstime->tv_nsec);
 
189
                ut_error;
 
190
        }
 
191
 
 
192
        return(ret == ETIMEDOUT);
 
193
#endif
 
194
}
 
195
/*********************************************************//**
126
196
Wait on condition variable */
127
197
UNIV_INLINE
128
198
void
573
643
        }
574
644
}
575
645
 
 
646
/**********************************************************//**
 
647
Waits for an event object until it is in the signaled state or
 
648
a timeout is exceeded.
 
649
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
 
650
UNIV_INTERN
 
651
ulint
 
652
os_event_wait_time_low(
 
653
/*===================*/
 
654
        os_event_t      event,                  /*!< in: event to wait */
 
655
        ulint           time_in_usec,           /*!< in: timeout in
 
656
                                                microseconds, or
 
657
                                                OS_SYNC_INFINITE_TIME */
 
658
        ib_int64_t      reset_sig_count)        /*!< in: zero or the value
 
659
                                                returned by previous call of
 
660
                                                os_event_reset(). */
 
661
 
 
662
{
 
663
        ibool           timed_out = FALSE;
 
664
        ib_int64_t      old_signal_count;
 
665
 
 
666
#ifdef __WIN__
 
667
        DWORD           time_in_ms;
 
668
 
 
669
        if (!srv_use_native_conditions) {
 
670
                DWORD   err;
 
671
 
 
672
                ut_a(event);
 
673
 
 
674
                if (time_in_usec != OS_SYNC_INFINITE_TIME) {
 
675
                        time_in_ms = time_in_usec / 1000;
 
676
                        err = WaitForSingleObject(event->handle, time_in_ms);
 
677
                } else {
 
678
                        err = WaitForSingleObject(event->handle, INFINITE);
 
679
                }
 
680
 
 
681
                if (err == WAIT_OBJECT_0) {
 
682
                        return(0);
 
683
                } else if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) {
 
684
                        return(OS_SYNC_TIME_EXCEEDED);
 
685
                }
 
686
 
 
687
                ut_error;
 
688
                /* Dummy value to eliminate compiler warning. */
 
689
                return(42);
 
690
        } else {
 
691
                ut_a(sleep_condition_variable != NULL);
 
692
 
 
693
                if (time_in_usec != OS_SYNC_INFINITE_TIME) {
 
694
                        time_in_ms = time_in_usec / 1000;
 
695
                } else {
 
696
                        time_in_ms = INFINITE;
 
697
                }
 
698
        }
 
699
#else
 
700
        struct timespec abstime;
 
701
 
 
702
        if (time_in_usec != OS_SYNC_INFINITE_TIME) {
 
703
                struct timeval  tv;
 
704
                int             ret;
 
705
                ulint           sec;
 
706
                ulint           usec;
 
707
 
 
708
                ret = ut_usectime(&sec, &usec);
 
709
                ut_a(ret == 0);
 
710
 
 
711
                tv.tv_sec = sec;
 
712
                tv.tv_usec = usec;
 
713
 
 
714
                tv.tv_usec += time_in_usec;
 
715
 
 
716
                if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) {
 
717
                        tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND;
 
718
                        tv.tv_usec %= MICROSECS_IN_A_SECOND;
 
719
                }
 
720
 
 
721
                abstime.tv_sec  = tv.tv_sec;
 
722
                abstime.tv_nsec = tv.tv_usec * 1000;
 
723
        } else {
 
724
                abstime.tv_nsec = 999999999;
 
725
                abstime.tv_sec = (time_t) ULINT_MAX;
 
726
        }
 
727
 
 
728
        ut_a(abstime.tv_nsec <= 999999999);
 
729
 
 
730
#endif /* __WIN__ */
 
731
 
 
732
        os_fast_mutex_lock(&event->os_mutex);
 
733
 
 
734
        if (reset_sig_count) {
 
735
                old_signal_count = reset_sig_count;
 
736
        } else {
 
737
                old_signal_count = event->signal_count;
 
738
        }
 
739
 
 
740
        do {
 
741
                if (event->is_set == TRUE
 
742
                    || event->signal_count != old_signal_count) {
 
743
 
 
744
                        break;
 
745
                }
 
746
 
 
747
                timed_out = os_cond_wait_timed(
 
748
                        &event->cond_var, &event->os_mutex,
 
749
#ifndef __WIN__
 
750
                        &abstime
 
751
#else
 
752
                        time_in_ms
 
753
#endif /* !__WIN__ */
 
754
                );
 
755
 
 
756
        } while (!timed_out);
 
757
 
 
758
        os_fast_mutex_unlock(&event->os_mutex);
 
759
 
 
760
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
 
761
 
 
762
                os_thread_exit(NULL);
 
763
        }
 
764
 
 
765
        return(timed_out ? OS_SYNC_TIME_EXCEEDED : 0);
 
766
}
 
767
 
576
768
/*********************************************************//**
577
769
Creates an operating system mutex semaphore. Because these are slow, the
578
770
mutex semaphore of InnoDB itself (mutex_t) should be used where possible.