From 3e1a792c9b68c9a337c8df2dce188fc1c82f10c9 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Tue, 1 Jun 2010 21:37:45 +0400 Subject: [PATCH 1/7] Bug #45882: dtoa.c might not work with gcc 4.4.0 - Ported relevant changes from the upstream version to not break strict-aliasing rules and to fix compiler warnings and and infinite loops caused by that issue. - Fixed compilation with Honor_FLT_ROUNDS defined. - Fixed an unused variable warning. --- strings/dtoa.c | 373 +++++++++++++++++++++++++------------------------ 1 file changed, 192 insertions(+), 181 deletions(-) diff --git a/strings/dtoa.c b/strings/dtoa.c index 0a0e4031ea8..d64c420b499 100644 --- a/strings/dtoa.c +++ b/strings/dtoa.c @@ -551,14 +551,14 @@ typedef union { double d; ULong L[2]; } U; #if defined(WORDS_BIGENDIAN) || (defined(__FLOAT_WORD_ORDER) && \ (__FLOAT_WORD_ORDER == __BIG_ENDIAN)) -#define word0(x) ((U*)&x)->L[0] -#define word1(x) ((U*)&x)->L[1] +#define word0(x) (x)->L[0] +#define word1(x) (x)->L[1] #else -#define word0(x) ((U*)&x)->L[1] -#define word1(x) ((U*)&x)->L[0] +#define word0(x) (x)->L[1] +#define word1(x) (x)->L[0] #endif -#define dval(x) ((U*)&x)->d +#define dval(x) (x)->d /* #define P DBL_MANT_DIG */ /* Ten_pmax= floor(P*log(2)/log(5)) */ @@ -1159,15 +1159,15 @@ static Bigint *diff(Bigint *a, Bigint *b, Stack_alloc *alloc) } -static double ulp(double x) +static double ulp(U *x) { register Long L; - double a; + U u; L= (word0(x) & Exp_mask) - (P - 1)*Exp_msk1; - word0(a) = L; - word1(a) = 0; - return dval(a); + word0(&u) = L; + word1(&u) = 0; + return dval(&u); } @@ -1175,9 +1175,9 @@ static double b2d(Bigint *a, int *e) { ULong *xa, *xa0, w, y, z; int k; - double d; -#define d0 word0(d) -#define d1 word1(d) + U d; +#define d0 word0(&d) +#define d1 word1(&d) xa0= a->p.x; xa= xa0 + a->wds; @@ -1206,11 +1206,11 @@ static double b2d(Bigint *a, int *e) ret_d: #undef d0 #undef d1 - return dval(d); + return dval(&d); } -static Bigint *d2b(double d, int *e, int *bits, Stack_alloc *alloc) +static Bigint *d2b(U *d, int *e, int *bits, Stack_alloc *alloc) { Bigint *b; int de, k; @@ -1262,20 +1262,20 @@ static Bigint *d2b(double d, int *e, int *bits, Stack_alloc *alloc) static double ratio(Bigint *a, Bigint *b) { - double da, db; + U da, db; int k, ka, kb; - dval(da)= b2d(a, &ka); - dval(db)= b2d(b, &kb); + dval(&da)= b2d(a, &ka); + dval(&db)= b2d(b, &kb); k= ka - kb + 32*(a->wds - b->wds); if (k > 0) - word0(da)+= k*Exp_msk1; + word0(&da)+= k*Exp_msk1; else { k= -k; - word0(db)+= k*Exp_msk1; + word0(&db)+= k*Exp_msk1; } - return dval(da) / dval(db); + return dval(&da) / dval(&db); } static const double tens[] = @@ -1329,10 +1329,11 @@ static const double tinytens[]= static double my_strtod_int(const char *s00, char **se, int *error, char *buf, size_t buf_size) { int scale; - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, UNINIT_VAR(c), dsign, e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; const char *s, *s0, *s1, *end = *se; - double aadj, aadj1, adj, rv, rv0; + double aadj, aadj1; + U aadj2, adj, rv, rv0; Long L; ULong y, z; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; @@ -1343,7 +1344,6 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s int rounding; #endif Stack_alloc alloc; - LINT_INIT(c); *error= 0; @@ -1352,7 +1352,7 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s memset(alloc.freelist, 0, sizeof(alloc.freelist)); sign= nz0= nz= 0; - dval(rv)= 0.; + dval(&rv)= 0.; for (s= s00; s < end; s++) switch (*s) { case '-': @@ -1488,14 +1488,14 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s if (!nd0) nd0= nd; k= nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(rv)= y; + dval(&rv)= y; if (k > 9) { #ifdef SET_INEXACT if (k > DBL_DIG) oldinexact = get_inexact(); #endif - dval(rv)= tens[k - 9] * dval(rv) + z; + dval(&rv)= tens[k - 9] * dval(&rv) + z; } bd0= 0; if (nd <= DBL_DIG @@ -1514,11 +1514,11 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { - rv= -rv; + rv.d= -rv.d; sign= 0; } #endif - /* rv = */ rounded_product(dval(rv), tens[e]); + /* rv = */ rounded_product(dval(&rv), tens[e]); goto ret; } i= DBL_DIG - nd; @@ -1532,13 +1532,13 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { - rv= -rv; + rv.d= -rv.d; sign= 0; } #endif e-= i; - dval(rv)*= tens[i]; - /* rv = */ rounded_product(dval(rv), tens[e]); + dval(&rv)*= tens[i]; + /* rv = */ rounded_product(dval(&rv), tens[e]); goto ret; } } @@ -1549,11 +1549,11 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { - rv= -rv; + rv.d= -rv.d; sign= 0; } #endif - /* rv = */ rounded_quotient(dval(rv), tens[-e]); + /* rv = */ rounded_quotient(dval(&rv), tens[-e]); goto ret; } #endif @@ -1582,7 +1582,7 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s if (e1 > 0) { if ((i= e1 & 15)) - dval(rv)*= tens[i]; + dval(&rv)*= tens[i]; if (e1&= ~15) { if (e1 > DBL_MAX_10_EXP) @@ -1595,21 +1595,21 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s { case 0: /* toward 0 */ case 3: /* toward -infinity */ - word0(rv)= Big0; - word1(rv)= Big1; + word0(&rv)= Big0; + word1(&rv)= Big1; break; default: - word0(rv)= Exp_mask; - word1(rv)= 0; + word0(&rv)= Exp_mask; + word1(&rv)= 0; } #else /*Honor_FLT_ROUNDS*/ - word0(rv)= Exp_mask; - word1(rv)= 0; + word0(&rv)= Exp_mask; + word1(&rv)= 0; #endif /*Honor_FLT_ROUNDS*/ #ifdef SET_INEXACT /* set overflow bit */ - dval(rv0)= 1e300; - dval(rv0)*= dval(rv0); + dval(&rv0)= 1e300; + dval(&rv0)*= dval(&rv0); #endif if (bd0) goto retfree; @@ -1618,27 +1618,27 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s e1>>= 4; for(j= 0; e1 > 1; j++, e1>>= 1) if (e1 & 1) - dval(rv)*= bigtens[j]; + dval(&rv)*= bigtens[j]; /* The last multiplication could overflow. */ - word0(rv)-= P*Exp_msk1; - dval(rv)*= bigtens[j]; - if ((z= word0(rv) & Exp_mask) > Exp_msk1 * (DBL_MAX_EXP + Bias - P)) + word0(&rv)-= P*Exp_msk1; + dval(&rv)*= bigtens[j]; + if ((z= word0(&rv) & Exp_mask) > Exp_msk1 * (DBL_MAX_EXP + Bias - P)) goto ovfl; if (z > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P)) { /* set to largest number (Can't trust DBL_MAX) */ - word0(rv)= Big0; - word1(rv)= Big1; + word0(&rv)= Big0; + word1(&rv)= Big1; } else - word0(rv)+= P*Exp_msk1; + word0(&rv)+= P*Exp_msk1; } } else if (e1 < 0) { e1= -e1; if ((i= e1 & 15)) - dval(rv)/= tens[i]; + dval(&rv)/= tens[i]; if ((e1>>= 4)) { if (e1 >= 1 << n_bigtens) @@ -1647,25 +1647,25 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s scale= 2 * P; for(j= 0; e1 > 0; j++, e1>>= 1) if (e1 & 1) - dval(rv)*= tinytens[j]; - if (scale && (j = 2 * P + 1 - ((word0(rv) & Exp_mask) >> Exp_shift)) > 0) + dval(&rv)*= tinytens[j]; + if (scale && (j = 2 * P + 1 - ((word0(&rv) & Exp_mask) >> Exp_shift)) > 0) { /* scaled rv is denormal; zap j low bits */ if (j >= 32) { - word1(rv)= 0; + word1(&rv)= 0; if (j >= 53) - word0(rv)= (P + 2) * Exp_msk1; + word0(&rv)= (P + 2) * Exp_msk1; else - word0(rv)&= 0xffffffff << (j - 32); + word0(&rv)&= 0xffffffff << (j - 32); } else - word1(rv)&= 0xffffffff << j; + word1(&rv)&= 0xffffffff << j; } - if (!dval(rv)) + if (!dval(&rv)) { undfl: - dval(rv)= 0.; + dval(&rv)= 0.; if (bd0) goto retfree; goto ret; @@ -1683,7 +1683,7 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s { bd= Balloc(bd0->k, &alloc); Bcopy(bd, bd0); - bb= d2b(dval(rv), &bbe, &bbbits, &alloc); /* rv = bb * 2^bbe */ + bb= d2b(&rv, &bbe, &bbbits, &alloc); /* rv = bb * 2^bbe */ bs= i2b(1, &alloc); if (e >= 0) @@ -1748,7 +1748,7 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s if (i < 0) { /* Error is less than an ulp */ - if (!delta->x[0] && delta->wds <= 1) + if (!delta->p.x[0] && delta->wds <= 1) { /* exact */ #ifdef SET_INEXACT @@ -1760,51 +1760,51 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s { if (dsign) { - adj= 1.; + adj.d= 1.; goto apply_adj; } } else if (!dsign) { - adj= -1.; - if (!word1(rv) && !(word0(rv) & Frac_mask)) + adj.d= -1.; + if (!word1(&rv) && !(word0(&rv) & Frac_mask)) { - y= word0(rv) & Exp_mask; + y= word0(&rv) & Exp_mask; if (!scale || y > 2*P*Exp_msk1) { - delta= lshift(delta,Log2P); + delta= lshift(delta, Log2P, &alloc); if (cmp(delta, bs) <= 0) - adj= -0.5; + adj.d= -0.5; } } apply_adj: - if (scale && (y= word0(rv) & Exp_mask) <= 2 * P * Exp_msk1) - word0(adj)+= (2 * P + 1) * Exp_msk1 - y; - dval(rv)+= adj * ulp(dval(rv)); + if (scale && (y= word0(&rv) & Exp_mask) <= 2 * P * Exp_msk1) + word0(&adj)+= (2 * P + 1) * Exp_msk1 - y; + dval(&rv)+= adj.d * ulp(&rv); } break; } - adj= ratio(delta, bs); - if (adj < 1.) - adj= 1.; - if (adj <= 0x7ffffffe) + adj.d= ratio(delta, bs); + if (adj.d < 1.) + adj.d= 1.; + if (adj.d <= 0x7ffffffe) { /* adj = rounding ? ceil(adj) : floor(adj); */ - y= adj; - if (y != adj) + y= adj.d; + if (y != adj.d) { if (!((rounding >> 1) ^ dsign)) y++; - adj= y; + adj.d= y; } } - if (scale && (y= word0(rv) & Exp_mask) <= 2 * P * Exp_msk1) - word0(adj)+= (2 * P + 1) * Exp_msk1 - y; - adj*= ulp(dval(rv)); + if (scale && (y= word0(&rv) & Exp_mask) <= 2 * P * Exp_msk1) + word0(&adj)+= (2 * P + 1) * Exp_msk1 - y; + adj.d*= ulp(&rv); if (dsign) - dval(rv)+= adj; + dval(&rv)+= adj.d; else - dval(rv)-= adj; + dval(&rv)-= adj.d; goto cont; } #endif /*Honor_FLT_ROUNDS*/ @@ -1815,8 +1815,8 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s Error is less than half an ulp -- check for special case of mantissa a power of two. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask || - (word0(rv) & Exp_mask) <= (2 * P + 1) * Exp_msk1) + if (dsign || word1(&rv) || word0(&rv) & Bndry_mask || + (word0(&rv) & Exp_mask) <= (2 * P + 1) * Exp_msk1) { #ifdef SET_INEXACT if (!delta->x[0] && delta->wds <= 1) @@ -1842,26 +1842,26 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s /* exactly half-way between */ if (dsign) { - if ((word0(rv) & Bndry_mask1) == Bndry_mask1 && - word1(rv) == - ((scale && (y = word0(rv) & Exp_mask) <= 2 * P * Exp_msk1) ? + if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 && + word1(&rv) == + ((scale && (y = word0(&rv) & Exp_mask) <= 2 * P * Exp_msk1) ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : 0xffffffff)) { /*boundary case -- increment exponent*/ - word0(rv)= (word0(rv) & Exp_mask) + Exp_msk1; - word1(rv) = 0; + word0(&rv)= (word0(&rv) & Exp_mask) + Exp_msk1; + word1(&rv) = 0; dsign = 0; break; } } - else if (!(word0(rv) & Bndry_mask) && !word1(rv)) + else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { drop_down: /* boundary case -- decrement exponent */ if (scale) { - L= word0(rv) & Exp_mask; + L= word0(&rv) & Exp_mask; if (L <= (2 *P + 1) * Exp_msk1) { if (L > (P + 2) * Exp_msk1) @@ -1871,19 +1871,19 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s goto undfl; } } - L= (word0(rv) & Exp_mask) - Exp_msk1; - word0(rv)= L | Bndry_mask1; - word1(rv)= 0xffffffff; + L= (word0(&rv) & Exp_mask) - Exp_msk1; + word0(&rv)= L | Bndry_mask1; + word1(&rv)= 0xffffffff; break; } - if (!(word1(rv) & LSB)) + if (!(word1(&rv) & LSB)) break; if (dsign) - dval(rv)+= ulp(dval(rv)); + dval(&rv)+= ulp(&rv); else { - dval(rv)-= ulp(dval(rv)); - if (!dval(rv)) + dval(&rv)-= ulp(&rv); + if (!dval(&rv)) goto undfl; } dsign= 1 - dsign; @@ -1893,9 +1893,9 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s { if (dsign) aadj= aadj1= 1.; - else if (word1(rv) || word0(rv) & Bndry_mask) + else if (word1(&rv) || word0(&rv) & Bndry_mask) { - if (word1(rv) == Tiny1 && !word0(rv)) + if (word1(&rv) == Tiny1 && !word0(&rv)) goto undfl; aadj= 1.; aadj1= -1.; @@ -1929,26 +1929,26 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s aadj1+= 0.5; #endif /*Check_FLT_ROUNDS*/ } - y= word0(rv) & Exp_mask; + y= word0(&rv) & Exp_mask; /* Check for overflow */ if (y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1)) { - dval(rv0)= dval(rv); - word0(rv)-= P * Exp_msk1; - adj= aadj1 * ulp(dval(rv)); - dval(rv)+= adj; - if ((word0(rv) & Exp_mask) >= Exp_msk1 * (DBL_MAX_EXP + Bias - P)) + dval(&rv0)= dval(&rv); + word0(&rv)-= P * Exp_msk1; + adj.d= aadj1 * ulp(&rv); + dval(&rv)+= adj.d; + if ((word0(&rv) & Exp_mask) >= Exp_msk1 * (DBL_MAX_EXP + Bias - P)) { - if (word0(rv0) == Big0 && word1(rv0) == Big1) + if (word0(&rv0) == Big0 && word1(&rv0) == Big1) goto ovfl; - word0(rv)= Big0; - word1(rv)= Big1; + word0(&rv)= Big0; + word1(&rv)= Big1; goto cont; } else - word0(rv)+= P * Exp_msk1; + word0(&rv)+= P * Exp_msk1; } else { @@ -1961,12 +1961,21 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s aadj= z; aadj1= dsign ? aadj : -aadj; } - word0(aadj1)+= (2 * P + 1) * Exp_msk1 - y; + dval(&aadj2) = aadj1; + word0(&aadj2)+= (2 * P + 1) * Exp_msk1 - y; + aadj1= dval(&aadj2); + adj.d= aadj1 * ulp(&rv); + dval(&rv)+= adj.d; + if (rv.d == 0.) + goto undfl; + } + else + { + adj.d= aadj1 * ulp(&rv); + dval(&rv)+= adj.d; } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; } - z= word0(rv) & Exp_mask; + z= word0(&rv) & Exp_mask; #ifndef SET_INEXACT if (!scale) if (y == z) @@ -1975,7 +1984,7 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s L= (Long)aadj; aadj-= L; /* The tolerances below are conservative. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask) + if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) { if (aadj < .4999999 || aadj > .5000001) break; @@ -1995,9 +2004,9 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s { if (!oldinexact) { - word0(rv0)= Exp_1 + (70 << Exp_shift); - word1(rv0)= 0; - dval(rv0)+= 1.; + word0(&rv0)= Exp_1 + (70 << Exp_shift); + word1(&rv0)= 0; + dval(&rv0)+= 1.; } } else if (!oldinexact) @@ -2005,16 +2014,16 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s #endif if (scale) { - word0(rv0)= Exp_1 - 2 * P * Exp_msk1; - word1(rv0)= 0; - dval(rv)*= dval(rv0); + word0(&rv0)= Exp_1 - 2 * P * Exp_msk1; + word1(&rv0)= 0; + dval(&rv)*= dval(&rv0); } #ifdef SET_INEXACT - if (inexact && !(word0(rv) & Exp_mask)) + if (inexact && !(word0(&rv) & Exp_mask)) { /* set underflow bit */ - dval(rv0)= 1e-300; - dval(rv0)*= dval(rv0); + dval(&rv0)= 1e-300; + dval(&rv0)*= dval(&rv0); } #endif retfree: @@ -2025,7 +2034,7 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s Bfree(delta, &alloc); ret: *se= (char *)s; - return sign ? -dval(rv) : dval(rv); + return sign ? -dval(&rv) : dval(&rv); } @@ -2128,7 +2137,7 @@ static int quorem(Bigint *b, Bigint *S) calculation. */ -static char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, +static char *dtoa(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve, char *buf, size_t buf_size) { /* @@ -2173,7 +2182,8 @@ static char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, int denorm; ULong x; Bigint *b, *b1, *delta, *mlo, *mhi, *S; - double d2, ds, eps; + U d2, eps, u; + double ds; char *s, *s0; #ifdef Honor_FLT_ROUNDS int rounding; @@ -2184,18 +2194,19 @@ static char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, alloc.end= buf + buf_size; memset(alloc.freelist, 0, sizeof(alloc.freelist)); - if (word0(d) & Sign_bit) + u.d= dd; + if (word0(&u) & Sign_bit) { /* set sign for everything, including 0's and NaNs */ *sign= 1; - word0(d) &= ~Sign_bit; /* clear sign bit */ + word0(&u) &= ~Sign_bit; /* clear sign bit */ } else *sign= 0; /* If infinity, set decpt to DTOA_OVERFLOW, if 0 set it to 1 */ - if (((word0(d) & Exp_mask) == Exp_mask && (*decpt= DTOA_OVERFLOW)) || - (!dval(d) && (*decpt= 1))) + if (((word0(&u) & Exp_mask) == Exp_mask && (*decpt= DTOA_OVERFLOW)) || + (!dval(&u) && (*decpt= 1))) { /* Infinity, NaN, 0 */ char *res= (char*) dtoa_alloc(2, &alloc); @@ -2217,12 +2228,12 @@ static char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, } #endif - b= d2b(dval(d), &be, &bbits, &alloc); - if ((i= (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) + b= d2b(&u, &be, &bbits, &alloc); + if ((i= (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { - dval(d2)= dval(d); - word0(d2) &= Frac_mask1; - word0(d2) |= Exp_11; + dval(&d2)= dval(&u); + word0(&d2) &= Frac_mask1; + word0(&d2) |= Exp_11; /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 @@ -2255,21 +2266,21 @@ static char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, /* d is denormalized */ i= bbits + be + (Bias + (P-1) - 1); - x= i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) - : word1(d) << (32 - i); - dval(d2)= x; - word0(d2)-= 31*Exp_msk1; /* adjust exponent */ + x= i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) + : word1(&u) << (32 - i); + dval(&d2)= x; + word0(&d2)-= 31*Exp_msk1; /* adjust exponent */ i-= (Bias + (P-1) - 1) + 1; denorm= 1; } - ds= (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + ds= (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; k= (int)ds; if (ds < 0. && ds != k) k--; /* want k= floor(ds) */ k_check= 1; if (k >= 0 && k <= Ten_pmax) { - if (dval(d) < tens[k]) + if (dval(&u) < tens[k]) k--; k_check= 0; } @@ -2347,7 +2358,7 @@ static char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, { /* Try to get by with floating-point arithmetic. */ i= 0; - dval(d2)= dval(d); + dval(&d2)= dval(&u); k0= k; ilim0= ilim; ieps= 2; /* conservative */ @@ -2359,7 +2370,7 @@ static char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, { /* prevent overflows */ j&= Bletch - 1; - dval(d)/= bigtens[n_bigtens-1]; + dval(&u)/= bigtens[n_bigtens-1]; ieps++; } for (; j; j>>= 1, i++) @@ -2370,75 +2381,75 @@ static char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, ds*= bigtens[i]; } } - dval(d)/= ds; + dval(&u)/= ds; } else if ((j1= -k)) { - dval(d)*= tens[j1 & 0xf]; + dval(&u)*= tens[j1 & 0xf]; for (j= j1 >> 4; j; j>>= 1, i++) { if (j & 1) { ieps++; - dval(d)*= bigtens[i]; + dval(&u)*= bigtens[i]; } } } - if (k_check && dval(d) < 1. && ilim > 0) + if (k_check && dval(&u) < 1. && ilim > 0) { if (ilim1 <= 0) goto fast_failed; ilim= ilim1; k--; - dval(d)*= 10.; + dval(&u)*= 10.; ieps++; } - dval(eps)= ieps*dval(d) + 7.; - word0(eps)-= (P-1)*Exp_msk1; + dval(&eps)= ieps*dval(&u) + 7.; + word0(&eps)-= (P-1)*Exp_msk1; if (ilim == 0) { S= mhi= 0; - dval(d)-= 5.; - if (dval(d) > dval(eps)) + dval(&u)-= 5.; + if (dval(&u) > dval(&eps)) goto one_digit; - if (dval(d) < -dval(eps)) + if (dval(&u) < -dval(&eps)) goto no_digits; goto fast_failed; } if (leftright) { /* Use Steele & White method of only generating digits needed. */ - dval(eps)= 0.5/tens[ilim-1] - dval(eps); + dval(&eps)= 0.5/tens[ilim-1] - dval(&eps); for (i= 0;;) { - L= (Long) dval(d); - dval(d)-= L; + L= (Long) dval(&u); + dval(&u)-= L; *s++= '0' + (int)L; - if (dval(d) < dval(eps)) + if (dval(&u) < dval(&eps)) goto ret1; - if (1. - dval(d) < dval(eps)) + if (1. - dval(&u) < dval(&eps)) goto bump_up; if (++i >= ilim) break; - dval(eps)*= 10.; - dval(d)*= 10.; + dval(&eps)*= 10.; + dval(&u)*= 10.; } } else { /* Generate ilim digits, then fix them up. */ - dval(eps)*= tens[ilim-1]; - for (i= 1;; i++, dval(d)*= 10.) + dval(&eps)*= tens[ilim-1]; + for (i= 1;; i++, dval(&u)*= 10.) { - L= (Long)(dval(d)); - if (!(dval(d)-= L)) + L= (Long)(dval(&u)); + if (!(dval(&u)-= L)) ilim= i; *s++= '0' + (int)L; if (i == ilim) { - if (dval(d) > 0.5 + dval(eps)) + if (dval(&u) > 0.5 + dval(&eps)) goto bump_up; - else if (dval(d) < 0.5 - dval(eps)) + else if (dval(&u) < 0.5 - dval(&eps)) { while (*--s == '0'); s++; @@ -2450,7 +2461,7 @@ static char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, } fast_failed: s= s0; - dval(d)= dval(d2); + dval(&u)= dval(&d2); k= k0; ilim= ilim0; } @@ -2464,24 +2475,24 @@ static char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, if (ndigits < 0 && ilim <= 0) { S= mhi= 0; - if (ilim < 0 || dval(d) <= 5*ds) + if (ilim < 0 || dval(&u) <= 5*ds) goto no_digits; goto one_digit; } - for (i= 1;; i++, dval(d)*= 10.) + for (i= 1;; i++, dval(&u)*= 10.) { - L= (Long)(dval(d) / ds); - dval(d)-= L*ds; + L= (Long)(dval(&u) / ds); + dval(&u)-= L*ds; #ifdef Check_FLT_ROUNDS /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(d) < 0) + if (dval(&u) < 0) { L--; - dval(d)+= ds; + dval(&u)+= ds; } #endif *s++= '0' + (int)L; - if (!dval(d)) + if (!dval(&u)) { break; } @@ -2496,8 +2507,8 @@ static char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, } } #endif - dval(d)+= dval(d); - if (dval(d) > ds || (dval(d) == ds && L & 1)) + dval(&u)+= dval(&u); + if (dval(&u) > ds || (dval(&u) == ds && L & 1)) { bump_up: while (*--s == '9') @@ -2562,8 +2573,8 @@ bump_up: #endif ) { - if (!word1(d) && !(word0(d) & Bndry_mask) && - word0(d) & (Exp_mask & ~Exp_msk1) + if (!word1(&u) && !(word0(&u) & Bndry_mask) && + word0(&u) & (Exp_mask & ~Exp_msk1) ) { /* The special case */ @@ -2652,7 +2663,7 @@ one_digit: delta= diff(S, mhi, &alloc); j1= delta->sign ? 1 : cmp(b, delta); Bfree(delta, &alloc); - if (j1 == 0 && mode != 1 && !(word1(d) & 1) + if (j1 == 0 && mode != 1 && !(word1(&u) & 1) #ifdef Honor_FLT_ROUNDS && rounding >= 1 #endif @@ -2665,7 +2676,7 @@ one_digit: *s++= dig; goto ret; } - if (j < 0 || (j == 0 && mode != 1 && !(word1(d) & 1))) + if (j < 0 || (j == 0 && mode != 1 && !(word1(&u) & 1))) { if (!b->p.x[0] && b->wds <= 1) { From 6eaf7e6c45ad7b508bad9108027d80d180699c7e Mon Sep 17 00:00:00 2001 From: "Horst.Hunger" Date: Thu, 3 Jun 2010 11:27:27 +0200 Subject: [PATCH 2/7] Patch for trunk after merge from 5.1-bugteam of bug52913. --- mysql-test/collections/default.experimental | 2 + mysql-test/include/mysqlhotcopy.inc | 116 ++++++++++++++ mysql-test/lib/mtr_misc.pl | 22 +++ mysql-test/mysql-test-run.pl | 9 ++ mysql-test/r/mysqlhotcopy_archive.result | 118 ++++++++++++++ mysql-test/r/mysqlhotcopy_myisam.result | 164 ++++++++++++++++++++ mysql-test/t/mysqlhotcopy_archive.test | 8 + mysql-test/t/mysqlhotcopy_myisam.test | 7 + 8 files changed, 446 insertions(+) create mode 100644 mysql-test/include/mysqlhotcopy.inc create mode 100644 mysql-test/r/mysqlhotcopy_archive.result create mode 100644 mysql-test/r/mysqlhotcopy_myisam.result create mode 100644 mysql-test/t/mysqlhotcopy_archive.test create mode 100644 mysql-test/t/mysqlhotcopy_myisam.test diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 9fa352a6412..84fb2ac5e76 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -91,3 +91,5 @@ parts.partition_mgm_lc1_ndb # joro : NDB tests marked as experiment parts.partition_mgm_lc2_ndb # joro : NDB tests marked as experimental as agreed with bochklin parts.partition_syntax_ndb # joro : NDB tests marked as experimental as agreed with bochklin parts.partition_value_ndb # joro : NDB tests marked as experimental as agreed with bochklin +main.mysqlhotcopy_myisam # horst: due to bug#54129 +main.mysqlhotcopy_archive # horst: due to bug#54129 diff --git a/mysql-test/include/mysqlhotcopy.inc b/mysql-test/include/mysqlhotcopy.inc new file mode 100644 index 00000000000..585f8c13e74 --- /dev/null +++ b/mysql-test/include/mysqlhotcopy.inc @@ -0,0 +1,116 @@ +# Test of mysqlhotcopy (perl script) +# Author: Horst Hunger +# Created: 2010-05-10 + +--source include/not_windows.inc +--source include/not_embedded.inc + +let $MYSQLD_DATADIR= `SELECT @@datadir`; +--disable_warnings +DROP DATABASE IF EXISTS hotcopy_test; +--enable_warnings +CREATE DATABASE hotcopy_test; +USE hotcopy_test; +eval CREATE TABLE t1 (c1 int, c2 varchar(20)) ENGINE=$engine; +eval CREATE TABLE t2 (c1 int, c2 varchar(20)) ENGINE=$engine; +eval CREATE TABLE t3 (c1 int, c2 varchar(20)) ENGINE=$engine; + +INSERT INTO t1 VALUES (1,'aaaaaaaaaaaaaaaaaaaa'),(2, 'bbbbbbbbbbbbbbbbbbbbbbb'); +INSERT INTO t2 VALUES (1,'aaaaaaaaaaaaaaaaaaaa'),(2, 'bbbbbbbbbbbbbbbbbbbbbbb'); +INSERT INTO t3 VALUES (1,'aaaaaaaaaaaaaaaaaaaa'),(2, 'bbbbbbbbbbbbbbbbbbbbbbb'); + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +--list_files $MYSQLD_DATADIR/hotcopy_test + +# backup into another database in the same directory +--replace_result $MASTER_MYSOCK MASTER_MYSOCK +--exec $MYSQLHOTCOPY --quiet -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +--list_files $MYSQLD_DATADIR/hotcopy_save + +USE hotcopy_save; +SELECT * FROM t1; +SELECT * FROM t2; +SELECT * FROM t3; + +# restore data into the original database with mysqlhotcopy +if(`SELECT engine= 'MyISAM' FROM information_schema.tables WHERE table_name='t1'`) +{ +USE hotcopy_test; +DELETE FROM t1; +SELECT * FROM t1; + +--replace_result $MASTER_MYSOCK MASTER_MYSOCK +--exec $MYSQLHOTCOPY --quiet --addtodest -S $MASTER_MYSOCK -u root hotcopy_save hotcopy_test + +USE hotcopy_save; +SELECT * FROM t1; +SELECT * FROM t2; +SELECT * FROM t3; +} + +USE hotcopy_test; +DROP TABLE t2; +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +--list_files $MYSQLD_DATADIR/hotcopy_test + +--replace_result $MASTER_MYSOCK MASTER_MYSOCK +--exec $MYSQLHOTCOPY --quiet --addtodest -S $MASTER_MYSOCK -u root hotcopy_save hotcopy_test + +FLUSH TABLES; +SELECT * FROM t1; +SELECT * FROM t2; +SELECT * FROM t3; + +# backup of db into a directory +USE hotcopy_test; +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--exec $MYSQLHOTCOPY --quiet -S $MASTER_MYSOCK -u root hotcopy_test $MYSQLTEST_VARDIR/tmp +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--list_files $MYSQLTEST_VARDIR/tmp/hotcopy_test +#--exec rm -rf $MYSQLTEST_VARDIR/tmp/hotcopy_test +--remove_files_wildcard $MYSQLTEST_VARDIR/tmp/hotcopy_test * +--rmdir $MYSQLTEST_VARDIR/tmp/hotcopy_test + +# backup without full index files +# reproduction of bug#53556, "--list_files" shows MYI files, which is wrong. +DROP DATABASE hotcopy_save; +--replace_result $MASTER_MYSOCK MASTER_MYSOCK +--exec $MYSQLHOTCOPY --quiet --noindices -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +--list_files $MYSQLD_DATADIR/hotcopy_save + +# test of option "allowold" +DROP DATABASE hotcopy_save; +--replace_result $MASTER_MYSOCK MASTER_MYSOCK +--exec $MYSQLHOTCOPY --quiet -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +--list_files $MYSQLD_DATADIR/hotcopy_save +--replace_result $MASTER_MYSOCK MASTER_MYSOCK +--error 9,2304 +--exec $MYSQLHOTCOPY --quiet -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save +--replace_result $MASTER_MYSOCK MASTER_MYSOCK +--exec $MYSQLHOTCOPY --quiet --allowold -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +--list_files $MYSQLD_DATADIR/hotcopy_save + +# test of option "keepold" +--replace_result $MASTER_MYSOCK MASTER_MYSOCK +--exec $MYSQLHOTCOPY --quiet --keepold -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +--list_files $MYSQLD_DATADIR/hotcopy_save_old +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +--list_files $MYSQLD_DATADIR/hotcopy_save + +# test of option "suffix" +--replace_result $MASTER_MYSOCK MASTER_MYSOCK +--exec $MYSQLHOTCOPY --quiet --suffix=_cpy -S $MASTER_MYSOCK -u root hotcopy_test +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +--list_files $MYSQLD_DATADIR/hotcopy_test_cpy +DROP DATABASE hotcopy_test_cpy; + +DROP DATABASE hotcopy_test; +DROP DATABASE hotcopy_save; +DROP DATABASE hotcopy_save_old; + diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index 97eb693b52e..32960d866ce 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -147,6 +147,28 @@ sub mtr_exe_maybe_exists (@) { } +# +# NOTE! More specific paths should be given before less specific. +# +sub mtr_pl_maybe_exists (@) { + my @path= @_; + + map {$_.= ".pl"} @path if IS_WINDOWS; + foreach my $path ( @path ) + { + if(IS_WINDOWS) + { + return $path if -f $path; + } + else + { + return $path if -x $path; + } + } + return ""; +} + + # # NOTE! More specific paths should be given before less specific. # For example /client/debug should be listed before /client diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 68955010696..83c07eaa5f1 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2110,6 +2110,15 @@ sub environment_setup { "$basedir/storage/myisam/myisampack", "$basedir/myisam/myisampack")); + # ---------------------------------------------------- + # mysqlhotcopy + # ---------------------------------------------------- + my $mysqlhotcopy= + mtr_pl_maybe_exists("$basedir/scripts/mysqlhotcopy"); + # Since mysqltest interprets the real path as "false" in an if, + # use 1 ("true") to indicate "not exists" so it can be tested for + $ENV{'MYSQLHOTCOPY'}= $mysqlhotcopy || 1; + # ---------------------------------------------------- # perror # ---------------------------------------------------- diff --git a/mysql-test/r/mysqlhotcopy_archive.result b/mysql-test/r/mysqlhotcopy_archive.result new file mode 100644 index 00000000000..bea78597336 --- /dev/null +++ b/mysql-test/r/mysqlhotcopy_archive.result @@ -0,0 +1,118 @@ +DROP DATABASE IF EXISTS hotcopy_test; +CREATE DATABASE hotcopy_test; +USE hotcopy_test; +CREATE TABLE t1 (c1 int, c2 varchar(20)) ENGINE=archive; +CREATE TABLE t2 (c1 int, c2 varchar(20)) ENGINE=archive; +CREATE TABLE t3 (c1 int, c2 varchar(20)) ENGINE=archive; +INSERT INTO t1 VALUES (1,'aaaaaaaaaaaaaaaaaaaa'),(2, 'bbbbbbbbbbbbbbbbbbbbbbb'); +Warnings: +Warning 1265 Data truncated for column 'c2' at row 2 +INSERT INTO t2 VALUES (1,'aaaaaaaaaaaaaaaaaaaa'),(2, 'bbbbbbbbbbbbbbbbbbbbbbb'); +Warnings: +Warning 1265 Data truncated for column 'c2' at row 2 +INSERT INTO t3 VALUES (1,'aaaaaaaaaaaaaaaaaaaa'),(2, 'bbbbbbbbbbbbbbbbbbbbbbb'); +Warnings: +Warning 1265 Data truncated for column 'c2' at row 2 +db.opt +t1.ARZ +t1.frm +t2.ARZ +t2.frm +t3.ARZ +t3.frm +db.opt +t1.ARZ +t1.frm +t2.ARZ +t2.frm +t3.ARZ +t3.frm +USE hotcopy_save; +SELECT * FROM t1; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +SELECT * FROM t2; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +SELECT * FROM t3; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +USE hotcopy_test; +DROP TABLE t2; +db.opt +t1.ARZ +t1.frm +t3.ARZ +t3.frm +FLUSH TABLES; +SELECT * FROM t1; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +SELECT * FROM t2; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +SELECT * FROM t3; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +USE hotcopy_test; +db.opt +t1.ARZ +t1.frm +t2.ARZ +t2.frm +t3.ARZ +t3.frm +DROP DATABASE hotcopy_save; +db.opt +t1.ARZ +t1.frm +t2.ARZ +t2.frm +t3.ARZ +t3.frm +DROP DATABASE hotcopy_save; +db.opt +t1.ARZ +t1.frm +t2.ARZ +t2.frm +t3.ARZ +t3.frm +db.opt +t1.ARZ +t1.frm +t2.ARZ +t2.frm +t3.ARZ +t3.frm +db.opt +t1.ARZ +t1.frm +t2.ARZ +t2.frm +t3.ARZ +t3.frm +db.opt +t1.ARZ +t1.frm +t2.ARZ +t2.frm +t3.ARZ +t3.frm +db.opt +t1.ARZ +t1.frm +t2.ARZ +t2.frm +t3.ARZ +t3.frm +DROP DATABASE hotcopy_test_cpy; +DROP DATABASE hotcopy_test; +DROP DATABASE hotcopy_save; +DROP DATABASE hotcopy_save_old; diff --git a/mysql-test/r/mysqlhotcopy_myisam.result b/mysql-test/r/mysqlhotcopy_myisam.result new file mode 100644 index 00000000000..52aeffce5cf --- /dev/null +++ b/mysql-test/r/mysqlhotcopy_myisam.result @@ -0,0 +1,164 @@ +DROP DATABASE IF EXISTS hotcopy_test; +CREATE DATABASE hotcopy_test; +USE hotcopy_test; +CREATE TABLE t1 (c1 int, c2 varchar(20)) ENGINE=MyISAM; +CREATE TABLE t2 (c1 int, c2 varchar(20)) ENGINE=MyISAM; +CREATE TABLE t3 (c1 int, c2 varchar(20)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,'aaaaaaaaaaaaaaaaaaaa'),(2, 'bbbbbbbbbbbbbbbbbbbbbbb'); +Warnings: +Warning 1265 Data truncated for column 'c2' at row 2 +INSERT INTO t2 VALUES (1,'aaaaaaaaaaaaaaaaaaaa'),(2, 'bbbbbbbbbbbbbbbbbbbbbbb'); +Warnings: +Warning 1265 Data truncated for column 'c2' at row 2 +INSERT INTO t3 VALUES (1,'aaaaaaaaaaaaaaaaaaaa'),(2, 'bbbbbbbbbbbbbbbbbbbbbbb'); +Warnings: +Warning 1265 Data truncated for column 'c2' at row 2 +db.opt +t1.MYD +t1.MYI +t1.frm +t2.MYD +t2.MYI +t2.frm +t3.MYD +t3.MYI +t3.frm +db.opt +t1.MYD +t1.MYI +t1.frm +t2.MYD +t2.MYI +t2.frm +t3.MYD +t3.MYI +t3.frm +USE hotcopy_save; +SELECT * FROM t1; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +SELECT * FROM t2; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +SELECT * FROM t3; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +USE hotcopy_test; +DELETE FROM t1; +SELECT * FROM t1; +c1 c2 +USE hotcopy_save; +SELECT * FROM t1; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +SELECT * FROM t2; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +SELECT * FROM t3; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +USE hotcopy_test; +DROP TABLE t2; +db.opt +t1.MYD +t1.MYI +t1.frm +t3.MYD +t3.MYI +t3.frm +FLUSH TABLES; +SELECT * FROM t1; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +SELECT * FROM t2; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +SELECT * FROM t3; +c1 c2 +1 aaaaaaaaaaaaaaaaaaaa +2 bbbbbbbbbbbbbbbbbbbb +USE hotcopy_test; +db.opt +t1.MYD +t1.MYI +t1.frm +t2.MYD +t2.MYI +t2.frm +t3.MYD +t3.MYI +t3.frm +DROP DATABASE hotcopy_save; +db.opt +t1.MYD +t1.MYI +t1.frm +t2.MYD +t2.MYI +t2.frm +t3.MYD +t3.MYI +t3.frm +DROP DATABASE hotcopy_save; +db.opt +t1.MYD +t1.MYI +t1.frm +t2.MYD +t2.MYI +t2.frm +t3.MYD +t3.MYI +t3.frm +db.opt +t1.MYD +t1.MYI +t1.frm +t2.MYD +t2.MYI +t2.frm +t3.MYD +t3.MYI +t3.frm +db.opt +t1.MYD +t1.MYI +t1.frm +t2.MYD +t2.MYI +t2.frm +t3.MYD +t3.MYI +t3.frm +db.opt +t1.MYD +t1.MYI +t1.frm +t2.MYD +t2.MYI +t2.frm +t3.MYD +t3.MYI +t3.frm +db.opt +t1.MYD +t1.MYI +t1.frm +t2.MYD +t2.MYI +t2.frm +t3.MYD +t3.MYI +t3.frm +DROP DATABASE hotcopy_test_cpy; +DROP DATABASE hotcopy_test; +DROP DATABASE hotcopy_save; +DROP DATABASE hotcopy_save_old; diff --git a/mysql-test/t/mysqlhotcopy_archive.test b/mysql-test/t/mysqlhotcopy_archive.test new file mode 100644 index 00000000000..4bfad3ce138 --- /dev/null +++ b/mysql-test/t/mysqlhotcopy_archive.test @@ -0,0 +1,8 @@ +# Test of mysqlhotcopy (perl script) +# Author: Horst Hunger +# Created: 2010-05-10 + +--source include/have_archive.inc +let $engine= archive; +--source include/mysqlhotcopy.inc +--exit diff --git a/mysql-test/t/mysqlhotcopy_myisam.test b/mysql-test/t/mysqlhotcopy_myisam.test new file mode 100644 index 00000000000..adf26e42245 --- /dev/null +++ b/mysql-test/t/mysqlhotcopy_myisam.test @@ -0,0 +1,7 @@ +# Test of mysqlhotcopy (perl script) +# Author: Horst Hunger +# Created: 2010-05-10 + +let $engine= MyISAM; +--source include/mysqlhotcopy.inc +--exit From e5bcb6f36ae784fb794a3363acf8ba75f937ca8b Mon Sep 17 00:00:00 2001 From: "Horst.Hunger" Date: Fri, 4 Jun 2010 11:31:03 +0200 Subject: [PATCH 3/7] merge of patch for bug#52913 from 5.1-bugteam to trunk-bugfixing. Changed $basedir to $bindir in mysql-test-run.pl. --- mysql-test/include/mysqlhotcopy.inc | 5 +++++ mysql-test/mysql-test-run.pl | 2 +- mysql-test/t/disabled.def | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/mysql-test/include/mysqlhotcopy.inc b/mysql-test/include/mysqlhotcopy.inc index 585f8c13e74..b3fd5e47179 100644 --- a/mysql-test/include/mysqlhotcopy.inc +++ b/mysql-test/include/mysqlhotcopy.inc @@ -5,6 +5,11 @@ --source include/not_windows.inc --source include/not_embedded.inc +if ($MYSQLHOTCOPY) +{ + die due to missing mysqlhotcopy tool; +} + let $MYSQLD_DATADIR= `SELECT @@datadir`; --disable_warnings DROP DATABASE IF EXISTS hotcopy_test; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 83c07eaa5f1..fa2db663e1e 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2114,7 +2114,7 @@ sub environment_setup { # mysqlhotcopy # ---------------------------------------------------- my $mysqlhotcopy= - mtr_pl_maybe_exists("$basedir/scripts/mysqlhotcopy"); + mtr_pl_maybe_exists("$bindir/scripts/mysqlhotcopy"); # Since mysqltest interprets the real path as "false" in an if, # use 1 ("true") to indicate "not exists" so it can be tested for $ENV{'MYSQLHOTCOPY'}= $mysqlhotcopy || 1; diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index ac1f62a508c..cf64289bb5d 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -13,3 +13,5 @@ kill : Bug#37780 2008-12-03 HHunger need some changes to be query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically sp_sync : Bug#48157 2010-02-06 5.5-m3 demands a differnt solution plugin_load : Bug#42144 2009-12-21 alik plugin_load fails +mysqlhotcopy_myisam : bug#54129 2010-06-04 Horst +mysqlhotcopy_archive : bug#54129 2010-06-04 Horst From a8c288054efb4de42cefa5bf06bcb487171ed9d3 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 31 May 2010 12:29:54 -0300 Subject: [PATCH 4/7] Bug#53445: Build with -Wall and fix warnings that it generates Fix various mismatches between function's language linkage. Any particular function that is declared in C++ but should be callable from C must have C linkage. Note that function types with different linkages are also distinct. Thus, if a function type is declared in C code, it will have C linkage (same if declared in a extern "C" block). client/mysql.cc: Mismatch between prototype and declaration. client/mysqltest.cc: mysqltest used to be C code. Use C linkage where appropriate. cmd-line-utils/readline/input.c: Isolate unreachable code. include/my_alloc.h: Function type must have C linkage. include/my_base.h: Function type must have C linkage. include/my_global.h: Add helper macros to avoid spurious namespace indentation. include/mysql.h.pp: Update ABI file. mysys/my_gethwaddr.c: Remove stray carriage return and fix coding style. plugin/semisync/semisync_master_plugin.cc: Callback function types have C linkage. plugin/semisync/semisync_slave_plugin.cc: Callback function types have C linkage. sql/derror.cc: Expected function type has C linkage. sql/field.cc: Use helper macro and fix indentation. sql/handler.cc: Expected function type has C linkage. sql/item_sum.cc: Correct function linkages. Remove now unnecessary cast. sql/item_sum.h: Add prototypes with the appropriate linkage as otherwise they are distinct. sql/mysqld.cc: Wrap functions in C linkage mode. sql/opt_range.cc: C language linkage is ignored for class member functions. sql/partition_info.cc: Add wrapper functions with C linkage for class member functions. sql/rpl_utility.h: Use helper macro and fix indentation. sql/sql_class.cc: Change type of thd argument -- THD is a class. Use helper macro and fix indentation. sql/sql_class.h: Change type of thd argument -- THD is a class. sql/sql_select.cc: Expected function type has C linkage. sql/sql_select.h: Move prototype to sql_test.h sql/sql_show.cc: Expected function type has C linkage. sql/sql_test.cc: Fix required function prototype and fix coding style. sql/sql_test.h: Removed unnecessary export and add another. storage/myisammrg/ha_myisammrg.cc: Expected function type has C linkage. storage/perfschema/pfs.cc: PSI headers are declared with C language linkage, which also applies to function types. --- client/mysql.cc | 10 ++-- client/mysqltest.cc | 30 +++++++----- cmd-line-utils/readline/input.c | 2 + include/my_alloc.h | 5 ++ include/my_base.h | 2 + include/my_global.h | 5 ++ include/mysql.h.pp | 2 + mysys/my_gethwaddr.c | 56 ++++++++++++----------- plugin/semisync/semisync_master_plugin.cc | 4 ++ plugin/semisync/semisync_slave_plugin.cc | 3 ++ sql/derror.cc | 5 +- sql/field.cc | 21 +++++---- sql/handler.cc | 7 +-- sql/item_sum.cc | 12 +++-- sql/item_sum.h | 14 +++++- sql/mdl.h | 2 +- sql/mysqld.cc | 21 +++++---- sql/opt_range.cc | 44 ++++++++++-------- sql/opt_range.h | 1 - sql/partition_info.cc | 31 ++++++++++--- sql/rpl_utility.h | 4 +- sql/sql_class.cc | 10 ++-- sql/sql_class.h | 2 +- sql/sql_select.cc | 4 +- sql/sql_select.h | 1 - sql/sql_show.cc | 3 ++ sql/sql_test.cc | 29 +++++++++--- sql/sql_test.h | 2 +- storage/myisammrg/ha_myisammrg.cc | 14 ++++-- storage/perfschema/pfs.cc | 7 ++- storage/perfschema/pfs_instr.cc | 4 ++ storage/perfschema/pfs_instr_class.cc | 4 ++ storage/perfschema/pfs_server.cc | 7 ++- 33 files changed, 245 insertions(+), 123 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 4a7a8f0e58c..45fabe9cf8c 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2316,8 +2316,10 @@ static bool add_line(String &buffer,char *line,char *in_string, #ifdef HAVE_READLINE +C_MODE_START static char *new_command_generator(const char *text, int); -extern "C" char **new_mysql_completion (const char *text, int start, int end); +static char **new_mysql_completion(const char *text, int start, int end); +C_MODE_END /* Tell the GNU Readline library how to complete. We want to try to complete @@ -2449,9 +2451,9 @@ static void initialize_readline (char *name) array of matches, or NULL if there aren't any. */ -char **new_mysql_completion (const char *text, - int start __attribute__((unused)), - int end __attribute__((unused))) +static char **new_mysql_completion(const char *text, + int start __attribute__((unused)), + int end __attribute__((unused))) { if (!status.batch && !quick) #if defined(USE_NEW_READLINE_INTERFACE) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 24d520ff97f..d0c948e67bb 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -77,6 +77,12 @@ static int setenv(const char *name, const char *value, int overwrite); #endif +C_MODE_START +static sig_handler signal_handler(int sig); +static my_bool get_one_option(int optid, const struct my_option *, + char *argument); +C_MODE_END + enum { OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION, OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, @@ -462,7 +468,6 @@ void log_msg(const char *fmt, ...) VAR* var_from_env(const char *, const char *); VAR* var_init(VAR* v, const char *name, int name_len, const char *val, int val_len); -void var_free(void* v); VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw, my_bool ignore_not_existing); void eval_expr(VAR* v, const char *p, const char** p_end); @@ -1914,6 +1919,8 @@ static void strip_parentheses(struct st_command *command) } +C_MODE_START + static uchar *get_var_key(const uchar* var, size_t *len, my_bool __attribute__((unused)) t) { @@ -1924,6 +1931,16 @@ static uchar *get_var_key(const uchar* var, size_t *len, } +static void var_free(void *v) +{ + my_free(((VAR*) v)->str_val, MYF(MY_WME)); + if (((VAR*)v)->alloced) + my_free(v, MYF(MY_WME)); +} + +C_MODE_END + + VAR *var_init(VAR *v, const char *name, int name_len, const char *val, int val_len) { @@ -1966,14 +1983,6 @@ VAR *var_init(VAR *v, const char *name, int name_len, const char *val, } -void var_free(void *v) -{ - my_free(((VAR*) v)->str_val, MYF(MY_WME)); - if (((VAR*)v)->alloced) - my_free(v, MYF(MY_WME)); -} - - VAR* var_from_env(const char *name, const char *def_val) { const char *tmp; @@ -6070,8 +6079,7 @@ void read_embedded_server_arguments(const char *name) static my_bool -get_one_option(int optid, const struct my_option *opt __attribute__((unused)), - char *argument) +get_one_option(int optid, const struct my_option *, char *argument) { switch(optid) { case '#': diff --git a/cmd-line-utils/readline/input.c b/cmd-line-utils/readline/input.c index 84c0422059a..af81d9cd3b0 100644 --- a/cmd-line-utils/readline/input.c +++ b/cmd-line-utils/readline/input.c @@ -318,7 +318,9 @@ _rl_input_available () return (_kbhit ()); #endif +#if !defined (HAVE_SELECT) return 0; +#endif } int diff --git a/include/my_alloc.h b/include/my_alloc.h index 93b7438a1df..dbf104bda9a 100644 --- a/include/my_alloc.h +++ b/include/my_alloc.h @@ -23,6 +23,8 @@ #define ALLOC_MAX_BLOCK_TO_DROP 4096 #define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP 10 +C_MODE_START + typedef struct st_used_mem { /* struct for once_alloc (block) */ struct st_used_mem *next; /* Next block in use */ @@ -48,4 +50,7 @@ typedef struct st_mem_root void (*error_handler)(void); } MEM_ROOT; + +C_MODE_END + #endif diff --git a/include/my_base.h b/include/my_base.h index 7766d4165a2..28dc55b1b84 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -562,6 +562,8 @@ typedef ulong ha_rows; #define HA_VARCHAR_PACKLENGTH(field_length) ((field_length) < 256 ? 1 :2) /* invalidator function reference for Query Cache */ +C_MODE_START typedef void (* invalidator_by_filename)(const char * filename); +C_MODE_END #endif /* _my_base_h */ diff --git a/include/my_global.h b/include/my_global.h index 41735f4e4f5..c21a8a1f9ea 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -73,6 +73,11 @@ #define C_MODE_END #endif +#ifdef __cplusplus +#define CPP_UNNAMED_NS_START namespace { +#define CPP_UNNAMED_NS_END } +#endif + #if defined(_WIN32) #include #elif defined(__NETWARE__) diff --git a/include/mysql.h.pp b/include/mysql.h.pp index 4fef9e9ec0b..9c1d8adcd2f 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -202,6 +202,7 @@ typedef unsigned int MYSQL_FIELD_OFFSET; typedef unsigned long long my_ulonglong; #include "typelib.h" #include "my_alloc.h" +C_MODE_START typedef struct st_used_mem { struct st_used_mem *next; @@ -219,6 +220,7 @@ typedef struct st_mem_root unsigned int first_block_usage; void (*error_handler)(void); } MEM_ROOT; +C_MODE_END typedef struct st_typelib { unsigned int count; const char *name; diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index 38fa0313c5d..c6a7af58f57 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -102,47 +102,49 @@ err: } #elif defined(__WIN__) - -/* Workaround for BUG#32082 (Definition of VOID in my_global.h conflicts with -windows headers) */ -#ifdef VOID -#undef VOID -#define VOID void -#endif + +/* + Workaround for BUG#32082 (Definition of VOID in my_global.h conflicts with + windows headers) +*/ +#ifdef VOID +#undef VOID +#define VOID void +#endif #include -/* - The following typedef is for dynamically loading - iphlpapi.dll / GetAdaptersAddresses. Dynamic loading is - used because GetAdaptersAddresses is not available on Windows 2000 - which MySQL still supports. Static linking would cause an unresolved export. +/* + The following typedef is for dynamically loading iphlpapi.dll / + GetAdaptersAddresses. Dynamic loading is used because + GetAdaptersAddresses is not available on Windows 2000 which MySQL + still supports. Static linking would cause an unresolved export. */ typedef DWORD (WINAPI *pfnGetAdaptersAddresses)(IN ULONG Family, IN DWORD Flags,IN PVOID Reserved, - OUT PIP_ADAPTER_ADDRESSES pAdapterAddresses, + OUT PIP_ADAPTER_ADDRESSES pAdapterAddresses, IN OUT PULONG pOutBufLen); /* - my_gethwaddr - Windows version + my_gethwaddr - Windows version @brief Retrieve MAC address from network hardware - + @param[out] to MAC address exactly six bytes - + @return Operation status @retval 0 OK - @retval <>0 FAILED + @retval <>0 FAILED */ my_bool my_gethwaddr(uchar *to) -{ +{ PIP_ADAPTER_ADDRESSES pAdapterAddresses; PIP_ADAPTER_ADDRESSES pCurrAddresses; IP_ADAPTER_ADDRESSES adapterAddresses; ULONG address_len; - my_bool return_val= 1; - static pfnGetAdaptersAddresses fnGetAdaptersAddresses= - (pfnGetAdaptersAddresses)-1; + my_bool return_val= 1; + static pfnGetAdaptersAddresses fnGetAdaptersAddresses= + (pfnGetAdaptersAddresses)-1; if(fnGetAdaptersAddresses == (pfnGetAdaptersAddresses)-1) { @@ -156,7 +158,7 @@ my_bool my_gethwaddr(uchar *to) address_len= sizeof (IP_ADAPTER_ADDRESSES); /* Get the required size for the address data. */ - if (fnGetAdaptersAddresses(AF_UNSPEC, 0, 0, &adapterAddresses, &address_len) + if (fnGetAdaptersAddresses(AF_UNSPEC, 0, 0, &adapterAddresses, &address_len) == ERROR_BUFFER_OVERFLOW) { pAdapterAddresses= my_malloc(address_len, 0); @@ -167,29 +169,29 @@ my_bool my_gethwaddr(uchar *to) pAdapterAddresses= &adapterAddresses; /* one is enough don't alloc */ /* Get the hardware info. */ - if (fnGetAdaptersAddresses(AF_UNSPEC, 0, 0, pAdapterAddresses, &address_len) + if (fnGetAdaptersAddresses(AF_UNSPEC, 0, 0, pAdapterAddresses, &address_len) == NO_ERROR) { pCurrAddresses= pAdapterAddresses; - while (pCurrAddresses) + while (pCurrAddresses) { /* Look for ethernet cards. */ if (pCurrAddresses->IfType == IF_TYPE_ETHERNET_CSMACD) { /* check for a good address */ if (pCurrAddresses->PhysicalAddressLength < 6) - continue; /* bad address */ + continue; /* bad address */ /* save 6 bytes of the address in the 'to' parameter */ memcpy(to, pCurrAddresses->PhysicalAddress, 6); /* Network card found, we're done. */ return_val= 0; - break; + break; } pCurrAddresses= pCurrAddresses->Next; - } + } } /* Clean up memory allocation. */ diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc index d6cc23a43b7..a55ba184a17 100644 --- a/plugin/semisync/semisync_master_plugin.cc +++ b/plugin/semisync/semisync_master_plugin.cc @@ -20,6 +20,8 @@ ReplSemiSyncMaster repl_semisync; +C_MODE_START + int repl_semi_report_binlog_update(Binlog_storage_param *param, const char *log_file, my_off_t log_pos, uint32 flags) @@ -145,6 +147,8 @@ int repl_semi_reset_master(Binlog_transmit_param *param) return 0; } +C_MODE_END + /* semisync system variables */ diff --git a/plugin/semisync/semisync_slave_plugin.cc b/plugin/semisync/semisync_slave_plugin.cc index 66073f8a5e6..5aa32cdfd5f 100644 --- a/plugin/semisync/semisync_slave_plugin.cc +++ b/plugin/semisync/semisync_slave_plugin.cc @@ -29,6 +29,8 @@ ReplSemiSyncSlave repl_semisync; */ bool semi_sync_need_reply= false; +C_MODE_START + int repl_semi_reset_slave(Binlog_relay_IO_param *param) { // TODO: reset semi-sync slave status here @@ -124,6 +126,7 @@ int repl_semi_slave_io_end(Binlog_relay_IO_param *param) return repl_semisync.slaveStop(param); } +C_MODE_END static void fix_rpl_semi_sync_slave_enabled(MYSQL_THD thd, SYS_VAR *var, diff --git a/sql/derror.cc b/sql/derror.cc index 04a82860d45..7f1435e89c1 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -32,11 +32,12 @@ static void init_myfunc_errs(void); -const char **get_server_errmsgs() +C_MODE_START +static const char **get_server_errmsgs() { return CURRENT_THD_ERRMSGS; } - +C_MODE_END /** Read messages from errorfile. diff --git a/sql/field.cc b/sql/field.cc index ac40ae53d7c..88a7f43819d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1009,17 +1009,20 @@ test_if_important_data(CHARSET_INFO *cs, const char *str, const char *strend) Used below. In an anonymous namespace to not clash with definitions in other files. */ -namespace { - int compare(unsigned int a, unsigned int b) - { - if (a < b) - return -1; - if (b < a) - return 1; - return 0; -} + +CPP_UNNAMED_NS_START + +int compare(unsigned int a, unsigned int b) +{ + if (a < b) + return -1; + if (b < a) + return 1; + return 0; } +CPP_UNNAMED_NS_END + /** Detect Item_result by given field type of UNION merge result. diff --git a/sql/handler.cc b/sql/handler.cc index 844c7305825..11f684a8010 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -299,13 +299,14 @@ handler *get_ha_partition(partition_info *part_info) #endif -const char **handler_errmsgs; +static const char **handler_errmsgs; - -const char **get_handler_errmsgs() +C_MODE_START +static const char **get_handler_errmsgs() { return handler_errmsgs; } +C_MODE_END /** diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 917acb0e908..15927c4b11e 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -2827,6 +2827,7 @@ String *Item_sum_udf_str::val_str(String *str) @retval 1 : key1 > key2 */ +extern "C" int group_concat_key_cmp_with_distinct(void* arg, const void* key1, const void* key2) { @@ -2861,6 +2862,7 @@ int group_concat_key_cmp_with_distinct(void* arg, const void* key1, function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... ) */ +extern "C" int group_concat_key_cmp_with_order(void* arg, const void* key1, const void* key2) { @@ -2905,13 +2907,16 @@ int group_concat_key_cmp_with_order(void* arg, const void* key1, Append data from current leaf to item->result. */ -int dump_leaf_key(uchar* key, element_count count __attribute__((unused)), - Item_func_group_concat *item) +extern "C" +int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)), + void* item_arg) { + Item_func_group_concat *item= (Item_func_group_concat *) item_arg; TABLE *table= item->table; String tmp((char *)table->record[1], table->s->reclength, default_charset_info); String tmp2; + uchar *key= (uchar *) key_arg; String *result= &item->result; Item **arg= item->args, **arg_end= item->args + item->arg_count_field; uint old_length= result->length(); @@ -3385,8 +3390,7 @@ String* Item_func_group_concat::val_str(String* str) return 0; if (no_appended && tree) /* Tree is used for sorting as in ORDER BY */ - tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this, - left_root_right); + tree_walk(tree, &dump_leaf_key, this, left_root_right); return &result; } diff --git a/sql/item_sum.h b/sql/item_sum.h index c76f3102003..99fcb14d160 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1319,6 +1319,16 @@ public: #endif /* HAVE_DLOPEN */ +C_MODE_START +int group_concat_key_cmp_with_distinct(void* arg, const void* key1, + const void* key2); +int group_concat_key_cmp_with_order(void* arg, const void* key1, + const void* key2); +int dump_leaf_key(void* key_arg, + element_count count __attribute__((unused)), + void* item_arg); +C_MODE_END + class Item_func_group_concat : public Item_sum { TMP_TABLE_PARAM *tmp_table_param; @@ -1358,9 +1368,9 @@ class Item_func_group_concat : public Item_sum const void* key2); friend int group_concat_key_cmp_with_order(void* arg, const void* key1, const void* key2); - friend int dump_leaf_key(uchar* key, + friend int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)), - Item_func_group_concat *group_concat_item); + void* item_arg); public: Item_func_group_concat(Name_resolution_context *context_arg, diff --git a/sql/mdl.h b/sql/mdl.h index 2fb21a5aa18..89a679be264 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -718,7 +718,7 @@ void mdl_destroy(); extern bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use, bool needs_thr_lock_abort); extern void mysql_ha_flush(THD *thd); -extern "C" const char *set_thd_proc_info(THD *thd, const char *info, +extern "C" const char *set_thd_proc_info(void *thd_arg, const char *info, const char *calling_function, const char *calling_file, const unsigned int calling_line); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index eb76132c080..db0080451f2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -857,12 +857,15 @@ void Buffered_logs::print() /** Logs reported before a logger is available. */ static Buffered_logs buffered_logs; +#ifndef EMBEDDED_LIBRARY /** Error reporter that buffer log messages. @param level log message level @param format log message format string */ -void buffered_option_error_reporter(enum loglevel level, const char *format, ...) +C_MODE_START +static void buffered_option_error_reporter(enum loglevel level, + const char *format, ...) { va_list args; char buffer[1024]; @@ -872,6 +875,8 @@ void buffered_option_error_reporter(enum loglevel level, const char *format, ... va_end(args); buffered_logs.buffer(level, buffer); } +C_MODE_END +#endif /* !EMBEDDED_LIBRARY */ #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */ static my_socket unix_sock,ip_sock; @@ -973,7 +978,6 @@ uint connection_count= 0; pthread_handler_t signal_hand(void *arg); static int mysql_init_variables(void); -extern "C" void option_error_reporter(enum loglevel level, const char *format, ...); static int get_options(int *argc_ptr, char ***argv_ptr); static bool add_terminator(DYNAMIC_ARRAY *options); extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *); @@ -4020,9 +4024,8 @@ static int init_server_components() } } - proc_info_hook= (const char *(*)(void *, const char *, const char *, - const char *, const unsigned int)) - set_thd_proc_info; + proc_info_hook= set_thd_proc_info; + #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE /* Parsing the performance schema command line option may have reported @@ -7420,10 +7423,7 @@ mysqld_get_one_option(int optid, /** Handle arguments for multiple key caches. */ -extern "C" int mysql_getopt_value(uchar **value, - const char *keyname, uint key_length, - const struct my_option *option, - int *error); +C_MODE_START static uchar* * mysql_getopt_value(const char *keyname, uint key_length, @@ -7459,7 +7459,7 @@ mysql_getopt_value(const char *keyname, uint key_length, return option->value; } -void option_error_reporter(enum loglevel level, const char *format, ...) +static void option_error_reporter(enum loglevel level, const char *format, ...) { va_list args; va_start(args, format); @@ -7473,6 +7473,7 @@ void option_error_reporter(enum loglevel level, const char *format, ...) va_end(args); } +C_MODE_END /** Get server options from the command line, diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 5e985625c78..9363b637862 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1538,6 +1538,29 @@ QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param, } +/* + Comparison function to be used QUICK_ROR_UNION_SELECT::queue priority + queue. + + SYNPOSIS + QUICK_ROR_UNION_SELECT_queue_cmp() + arg Pointer to QUICK_ROR_UNION_SELECT + val1 First merged select + val2 Second merged select +*/ + +C_MODE_START + +static int QUICK_ROR_UNION_SELECT_queue_cmp(void *arg, uchar *val1, uchar *val2) +{ + QUICK_ROR_UNION_SELECT *self= (QUICK_ROR_UNION_SELECT*)arg; + return self->head->file->cmp_ref(((QUICK_SELECT_I*)val1)->last_rowid, + ((QUICK_SELECT_I*)val2)->last_rowid); +} + +C_MODE_END + + /* Do post-constructor initialization. SYNOPSIS @@ -1552,7 +1575,7 @@ int QUICK_ROR_UNION_SELECT::init() { DBUG_ENTER("QUICK_ROR_UNION_SELECT::init"); if (init_queue(&queue, quick_selects.elements, 0, - FALSE , QUICK_ROR_UNION_SELECT::queue_cmp, + FALSE , QUICK_ROR_UNION_SELECT_queue_cmp, (void*) this)) { bzero(&queue, sizeof(QUEUE)); @@ -1566,25 +1589,6 @@ int QUICK_ROR_UNION_SELECT::init() } -/* - Comparison function to be used QUICK_ROR_UNION_SELECT::queue priority - queue. - - SYNPOSIS - QUICK_ROR_UNION_SELECT::queue_cmp() - arg Pointer to QUICK_ROR_UNION_SELECT - val1 First merged select - val2 Second merged select -*/ - -int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, uchar *val1, uchar *val2) -{ - QUICK_ROR_UNION_SELECT *self= (QUICK_ROR_UNION_SELECT*)arg; - return self->head->file->cmp_ref(((QUICK_SELECT_I*)val1)->last_rowid, - ((QUICK_SELECT_I*)val2)->last_rowid); -} - - /* Initialize quick select for row retrieval. SYNOPSIS diff --git a/sql/opt_range.h b/sql/opt_range.h index 85d59671b42..72f2eb4b51d 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -657,7 +657,6 @@ public: bool have_prev_rowid; /* true if prev_rowid has valid data */ uint rowid_length; /* table rowid length */ private: - static int queue_cmp(void *arg, uchar *val1, uchar *val2); bool scans_inited; }; diff --git a/sql/partition_info.cc b/sql/partition_info.cc index a689d53d953..5b0b681c3a6 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -802,7 +802,8 @@ range_not_increasing_error: -1 a < b */ -int partition_info::list_part_cmp(const void* a, const void* b) +extern "C" +int partition_info_list_part_cmp(const void* a, const void* b) { longlong a1= ((LIST_PART_ENTRY*)a)->list_value; longlong b1= ((LIST_PART_ENTRY*)b)->list_value; @@ -814,7 +815,14 @@ int partition_info::list_part_cmp(const void* a, const void* b) return 0; } - /* + +int partition_info::list_part_cmp(const void* a, const void* b) +{ + return partition_info_list_part_cmp(a, b); +} + + +/* Compare two lists of column values in RANGE/LIST partitioning SYNOPSIS compare_column_values() @@ -826,8 +834,9 @@ int partition_info::list_part_cmp(const void* a, const void* b) +1 First argument is larger */ -int partition_info::compare_column_values(const void *first_arg, - const void *second_arg) +extern "C" +int partition_info_compare_column_values(const void *first_arg, + const void *second_arg) { const part_column_list_val *first= (part_column_list_val*)first_arg; const part_column_list_val *second= (part_column_list_val*)second_arg; @@ -863,6 +872,14 @@ int partition_info::compare_column_values(const void *first_arg, return 0; } + +int partition_info::compare_column_values(const void *first_arg, + const void *second_arg) +{ + return partition_info_compare_column_values(first_arg, second_arg); +} + + /* This routine allocates an array for all list constants to achieve a fast check what partition a certain value belongs to. At the same time it does @@ -895,7 +912,7 @@ bool partition_info::check_list_constants(THD *thd) void *UNINIT_VAR(prev_value); partition_element* part_def; bool found_null= FALSE; - int (*compare_func)(const void *, const void*); + qsort_cmp compare_func; void *ptr; List_iterator list_func_it(partitions); DBUG_ENTER("partition_info::check_list_constants"); @@ -952,7 +969,7 @@ bool partition_info::check_list_constants(THD *thd) part_column_list_val *loc_list_col_array; loc_list_col_array= (part_column_list_val*)ptr; list_col_array= (part_column_list_val*)ptr; - compare_func= compare_column_values; + compare_func= partition_info_compare_column_values; i= 0; do { @@ -972,7 +989,7 @@ bool partition_info::check_list_constants(THD *thd) } else { - compare_func= list_part_cmp; + compare_func= partition_info_list_part_cmp; list_array= (LIST_PART_ENTRY*)ptr; i= 0; /* diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index cf28d2c8e29..25f2a60bece 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -233,7 +233,7 @@ struct RPL_TABLE_LIST /* Anonymous namespace for template functions/classes */ -namespace { +CPP_UNNAMED_NS_START /* Smart pointer that will automatically call my_afree (a macro) when @@ -260,7 +260,7 @@ namespace { Obj* get() { return m_ptr; } }; -} +CPP_UNNAMED_NS_END #endif // NB. number of printed bit values is limited to sizeof(buf) - 1 diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b090f35a607..ac092756a74 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -261,11 +261,13 @@ int thd_tablespace_op(const THD *thd) extern "C" -const char *set_thd_proc_info(THD *thd, const char *info, +const char *set_thd_proc_info(void *thd_arg, const char *info, const char *calling_function, const char *calling_file, const unsigned int calling_line) { + THD *thd= (THD *) thd_arg; + if (!thd) thd= current_thd; @@ -4207,7 +4209,9 @@ field_type_name(enum_field_types type) #endif -namespace { +/* Declare in unnamed namespace. */ +CPP_UNNAMED_NS_START + /** Class to handle temporary allocation of memory for row data. @@ -4326,8 +4330,8 @@ namespace { uchar *m_memory; uchar *m_ptr[2]; }; -} +CPP_UNNAMED_NS_END int THD::binlog_write_row(TABLE* table, bool is_trans, MY_BITMAP const* cols, size_t colcnt, diff --git a/sql/sql_class.h b/sql/sql_class.h index 015a87cb5cc..f1fce5ef472 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3685,7 +3685,7 @@ inline bool add_group_to_list(THD *thd, Item *item, bool asc) three calling-info parameters. */ extern "C" -const char *set_thd_proc_info(THD *thd, const char *info, +const char *set_thd_proc_info(void *thd_arg, const char *info, const char *calling_func, const char *calling_file, const unsigned int calling_line); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8112bbba267..10884a95b74 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -44,7 +44,7 @@ #include "sql_partition.h" // make_used_partitions_str #include "sql_acl.h" // *_ACL #include "sql_test.h" // print_where, print_keyuse_array, - // print_sjm, print_plan + // print_sjm, print_plan, TEST_join #include "records.h" // init_read_record, end_read_record #include "filesort.h" // filesort_free_buffers #include "sql_union.h" // mysql_union @@ -90,8 +90,10 @@ static bool best_extension_by_limited_search(JOIN *join, double read_time, uint depth, uint prune_level); static uint determine_search_depth(JOIN* join); +C_MODE_START static int join_tab_cmp(const void* ptr1, const void* ptr2); static int join_tab_cmp_straight(const void* ptr1, const void* ptr2); +C_MODE_END /* TODO: 'find_best' is here only temporarily until 'greedy_search' is tested and approved. diff --git a/sql/sql_select.h b/sql/sql_select.h index ccf88c2cc5c..2c44dba74c3 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -597,7 +597,6 @@ typedef struct st_select_check { } SELECT_CHECK; extern const char *join_type_str[]; -void TEST_join(JOIN *join); /* Extern functions in sql_select.cc */ bool store_val_in_field(Field *field, Item *val, enum_check_fields check_flag); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index dda434a557a..16a17744279 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1945,10 +1945,13 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) static DYNAMIC_ARRAY all_status_vars; static bool status_vars_inited= 0; + +C_MODE_START static int show_var_cmp(const void *var1, const void *var2) { return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name); } +C_MODE_END /* deletes all the SHOW_UNDEF elements from the array and calls diff --git a/sql/sql_test.cc b/sql/sql_test.cc index d34aee854d0..43d203e6498 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -76,7 +76,7 @@ print_where(COND *cond,const char *info, enum_query_type query_type) /* This is for debugging purposes */ -void print_cached_tables(void) +static void print_cached_tables(void) { uint idx,count,unused; TABLE_SHARE *share; @@ -341,6 +341,11 @@ print_plan(JOIN* join, uint idx, double record_count, double read_time, #endif +C_MODE_START +static int dl_compare(const void *p1, const void *p2); +static int print_key_cache_status(const char *name, KEY_CACHE *key_cache); +C_MODE_END + typedef struct st_debug_lock { ulong thread_id; @@ -350,8 +355,13 @@ typedef struct st_debug_lock enum thr_lock_type type; } TABLE_LOCK_INFO; -static int dl_compare(TABLE_LOCK_INFO *a,TABLE_LOCK_INFO *b) +static int dl_compare(const void *p1, const void *p2) { + TABLE_LOCK_INFO *a, *b; + + a= (TABLE_LOCK_INFO *) p1; + b= (TABLE_LOCK_INFO *) p2; + if (a->thread_id > b->thread_id) return 1; if (a->thread_id < b->thread_id) @@ -401,9 +411,10 @@ static void push_locks_into_array(DYNAMIC_ARRAY *ar, THR_LOCK_DATA *data, function so that we can easily add this if we ever need this. */ -static void display_table_locks(void) +static void display_table_locks(void) { LIST *list; + void *saved_base; DYNAMIC_ARRAY saved_table_locks; (void) my_init_dynamic_array(&saved_table_locks,sizeof(TABLE_LOCK_INFO), table_cache_count + 20,50); @@ -424,13 +435,17 @@ static void display_table_locks(void) mysql_mutex_unlock(&lock->mutex); } mysql_mutex_unlock(&THR_LOCK_lock); - if (!saved_table_locks.elements) goto end; - - qsort((uchar*) dynamic_element(&saved_table_locks,0,TABLE_LOCK_INFO *),saved_table_locks.elements,sizeof(TABLE_LOCK_INFO),(qsort_cmp) dl_compare); + + if (!saved_table_locks.elements) + goto end; + + saved_base= dynamic_element(&saved_table_locks, 0, TABLE_LOCK_INFO *); + my_qsort(saved_base, saved_table_locks.elements, sizeof(TABLE_LOCK_INFO), + dl_compare); freeze_size(&saved_table_locks); puts("\nThread database.table_name Locked/Waiting Lock_type\n"); - + unsigned int i; for (i=0 ; i < saved_table_locks.elements ; i++) { diff --git a/sql/sql_test.h b/sql/sql_test.h index 539e89ec949..d7fcc126cb2 100644 --- a/sql/sql_test.h +++ b/sql/sql_test.h @@ -26,8 +26,8 @@ typedef struct st_sort_field SORT_FIELD; #ifndef DBUG_OFF void print_where(COND *cond,const char *info, enum_query_type query_type); -void print_cached_tables(void); void TEST_filesort(SORT_FIELD *sortorder,uint s_length); +void TEST_join(JOIN *join); void print_plan(JOIN* join,uint idx, double record_count, double read_time, double current_read_time, const char *info); void dump_TABLE_LIST_graph(SELECT_LEX *select_lex, TABLE_LIST* tl); diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 6b7e60b126c..9fc868a2ebe 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -221,8 +221,10 @@ const char *ha_myisammrg::index_type(uint key_number) children_last_l -----------------------------------------+ */ -static int myisammrg_parent_open_callback(void *callback_param, - const char *filename) +CPP_UNNAMED_NS_START + +extern "C" int myisammrg_parent_open_callback(void *callback_param, + const char *filename) { ha_myisammrg *ha_myrg= (ha_myisammrg*) callback_param; TABLE *parent= ha_myrg->table_ptr(); @@ -320,6 +322,8 @@ static int myisammrg_parent_open_callback(void *callback_param, DBUG_RETURN(0); } +CPP_UNNAMED_NS_END + /** Open a MERGE parent table, but not its children. @@ -575,7 +579,9 @@ public: next child table. It is called for each child table. */ -static MI_INFO *myisammrg_attach_children_callback(void *callback_param) +CPP_UNNAMED_NS_START + +extern "C" MI_INFO *myisammrg_attach_children_callback(void *callback_param) { Mrg_attach_children_callback_param *param= (Mrg_attach_children_callback_param*) callback_param; @@ -643,6 +649,8 @@ static MI_INFO *myisammrg_attach_children_callback(void *callback_param) DBUG_RETURN(myisam); } +CPP_UNNAMED_NS_END + /** Returns a cloned instance of the current handler. diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc index 380801c8677..f5901540ab0 100644 --- a/storage/perfschema/pfs.cc +++ b/storage/perfschema/pfs.cc @@ -806,6 +806,10 @@ static int build_prefix(const LEX_STRING *prefix, const char *category, } \ return; +/* Use C linkage for the interface functions. */ + +C_MODE_START + static void register_mutex_v1(const char *category, PSI_mutex_info_v1 *info, int count) @@ -2054,8 +2058,9 @@ static void* get_interface(int version) } } +C_MODE_END + struct PSI_bootstrap PFS_bootstrap= { get_interface }; - diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc index fb40db02ca3..9507e2d2582 100644 --- a/storage/perfschema/pfs_instr.cc +++ b/storage/perfschema/pfs_instr.cc @@ -134,6 +134,10 @@ static PFS_events_waits *thread_history_array= NULL; static LF_HASH filename_hash; /** True if filename_hash is initialized. */ static bool filename_hash_inited= false; +C_MODE_START +/** Get hash table key for instrumented files. */ +static uchar *filename_hash_get_key(const uchar *, size_t *, my_bool); +C_MODE_END /** Initialize all the instruments instance buffers. diff --git a/storage/perfschema/pfs_instr_class.cc b/storage/perfschema/pfs_instr_class.cc index ac8aa64b0c5..d1535aa851b 100644 --- a/storage/perfschema/pfs_instr_class.cc +++ b/storage/perfschema/pfs_instr_class.cc @@ -118,6 +118,10 @@ PFS_instr_class global_table_class= static LF_HASH table_share_hash; /** True if table_share_hash is initialized. */ static bool table_share_hash_inited= false; +C_MODE_START +/** Get hash table key for instrumented tables. */ +static uchar *table_share_hash_get_key(const uchar *, size_t *, my_bool); +C_MODE_END static volatile uint32 file_class_dirty_count= 0; static volatile uint32 file_class_allocated_count= 0; diff --git a/storage/perfschema/pfs_server.cc b/storage/perfschema/pfs_server.cc index a1216c6ac30..f852a9fe732 100644 --- a/storage/perfschema/pfs_server.cc +++ b/storage/perfschema/pfs_server.cc @@ -32,8 +32,11 @@ PFS_global_param pfs_param; +C_MODE_START static void destroy_pfs_thread(void *key); -void cleanup_performance_schema(void); +C_MODE_END + +static void cleanup_performance_schema(void); struct PSI_bootstrap* initialize_performance_schema(const PFS_global_param *param) @@ -100,7 +103,7 @@ static void destroy_pfs_thread(void *key) destroy_thread(pfs); } -void cleanup_performance_schema(void) +static void cleanup_performance_schema(void) { cleanup_instruments(); cleanup_sync_class(); From 60a9d9bbb94ac03159bcc2d75b649abb1c9dc956 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Sat, 5 Jun 2010 16:39:03 -0300 Subject: [PATCH 5/7] Post-merge fix: header is used by the client API. Obvious in retrospect. Also, update a few cases missed by the initial patch. client/mysqltest.cc: Remove trailing comma. include/my_alloc.h: Do not use wrapper. include/mysql.h.pp: Update ABI file. plugin/semisync/semisync_master.h: Initialize variable. sql/debug_sync.cc: Use C linkage. --- client/mysqltest.cc | 2 +- include/my_alloc.h | 8 ++++++-- include/mysql.h.pp | 2 -- plugin/semisync/semisync_master.h | 2 +- sql/debug_sync.cc | 11 +++++++++-- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index d0c948e67bb..0312a0a030b 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -87,7 +87,7 @@ enum { OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION, OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, OPT_MAX_CONNECT_RETRIES, OPT_MAX_CONNECTIONS, OPT_MARK_PROGRESS, - OPT_LOG_DIR, OPT_TAIL_LINES, OPT_RESULT_FORMAT_VERSION, + OPT_LOG_DIR, OPT_TAIL_LINES, OPT_RESULT_FORMAT_VERSION }; static int record= 0, opt_sleep= -1; diff --git a/include/my_alloc.h b/include/my_alloc.h index dbf104bda9a..4b1ffd3d444 100644 --- a/include/my_alloc.h +++ b/include/my_alloc.h @@ -23,7 +23,9 @@ #define ALLOC_MAX_BLOCK_TO_DROP 4096 #define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP 10 -C_MODE_START +#ifdef __cplusplus +extern "C" { +#endif typedef struct st_used_mem { /* struct for once_alloc (block) */ @@ -51,6 +53,8 @@ typedef struct st_mem_root void (*error_handler)(void); } MEM_ROOT; -C_MODE_END +#ifdef __cplusplus +} +#endif #endif diff --git a/include/mysql.h.pp b/include/mysql.h.pp index 9c1d8adcd2f..4fef9e9ec0b 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -202,7 +202,6 @@ typedef unsigned int MYSQL_FIELD_OFFSET; typedef unsigned long long my_ulonglong; #include "typelib.h" #include "my_alloc.h" -C_MODE_START typedef struct st_used_mem { struct st_used_mem *next; @@ -220,7 +219,6 @@ typedef struct st_mem_root unsigned int first_block_usage; void (*error_handler)(void); } MEM_ROOT; -C_MODE_END typedef struct st_typelib { unsigned int count; const char *name; diff --git a/plugin/semisync/semisync_master.h b/plugin/semisync/semisync_master.h index e1ad28cd9f6..1a562e8bb77 100644 --- a/plugin/semisync/semisync_master.h +++ b/plugin/semisync/semisync_master.h @@ -153,7 +153,7 @@ public: int free_nodes_before(TranxNode* node) { Block *block; - Block *prev_block; + Block *prev_block= NULL; block= first_block; while (block != current_block->next) diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index d16fa4b2468..dde6267331f 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -387,6 +387,13 @@ static st_debug_sync_globals debug_sync_global; /* All globals in one object */ */ extern "C" void (*debug_sync_C_callback_ptr)(const char *, size_t); +/** + Callbacks from C files. +*/ +C_MODE_START +static void debug_sync_C_callback(const char *, size_t); +static int debug_sync_qsort_cmp(const void *, const void *); +C_MODE_END /** Callback for debug sync, to be used by C files. See thr_lock.c for example. @@ -422,8 +429,8 @@ extern "C" void (*debug_sync_C_callback_ptr)(const char *, size_t); static void debug_sync_C_callback(const char *sync_point_name, size_t name_len) { - if (unlikely(opt_debug_sync_timeout)) - debug_sync(current_thd, sync_point_name, name_len); + if (unlikely(opt_debug_sync_timeout)) + debug_sync(current_thd, sync_point_name, name_len); } #ifdef HAVE_PSI_INTERFACE From be9c400638403e082be9cb2c70d43f96211ce41e Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Tue, 8 Jun 2010 06:41:48 -0600 Subject: [PATCH 6/7] Bug#54334 Double initialization of mysys mutexes Prior to this fix, mysys mutexes such as THR_LOCK_lock could be initialized twice by a call to my_init(). The root cause was out of place initialization in my_basic_init(), calling my_thread_global_init(). With this fix, - my_basic_init() properly initializes the mutex implementation itself, for SAFE or FAST mutexes, and for platform dependent initializations, before initialiazing a mutex. - my_init() properly initializes mysys mutexes once, when making the first call to my_thread_global_init(). --- mysys/my_init.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/mysys/my_init.c b/mysys/my_init.c index f27f3f7b3e8..e7ab98bcb73 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -104,8 +104,6 @@ my_bool my_basic_init(void) mysql_stdin= & instrumented_stdin; #if defined(THREAD) - if (my_thread_global_init()) - return 1; # if defined(SAFE_MUTEX) safe_mutex_global_init(); /* Must be called early */ # endif From 14182ec9176f2b368270cd82a4a3b31b218f9252 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Thu, 10 Jun 2010 17:44:19 +0400 Subject: [PATCH 7/7] Revert a patch for Bug#54334 (Double initialization of mysys mutexes). Revision ID of the patch: marc.alff@oracle.com-20100608124148-lr1ult7lwo75niev --- mysys/my_init.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysys/my_init.c b/mysys/my_init.c index e7ab98bcb73..f27f3f7b3e8 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -104,6 +104,8 @@ my_bool my_basic_init(void) mysql_stdin= & instrumented_stdin; #if defined(THREAD) + if (my_thread_global_init()) + return 1; # if defined(SAFE_MUTEX) safe_mutex_global_init(); /* Must be called early */ # endif