diff options
author | Sergei Golubchik <sergii@pisem.net> | 2010-11-25 18:17:28 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2010-11-25 18:17:28 +0100 |
commit | 65ca700def99289cc31a7040537f5aa6e12bf485 (patch) | |
tree | 97b3a07299b626c519da0e80c122b5b79b933914 /mysys/my_compress.c | |
parent | 2ab57de38d13d927ddff2d51aed4af34e13998f5 (diff) | |
parent | 6e5bcca7935d3c62f84bb640e5357664a210ee12 (diff) | |
download | mariadb-git-65ca700def99289cc31a7040537f5aa6e12bf485.tar.gz |
merge.
checkpoint.
does not compile.
Diffstat (limited to 'mysys/my_compress.c')
-rw-r--r-- | mysys/my_compress.c | 77 |
1 files changed, 72 insertions, 5 deletions
diff --git a/mysys/my_compress.c b/mysys/my_compress.c index 360390d376a..d408520a862 100644 --- a/mysys/my_compress.c +++ b/mysys/my_compress.c @@ -57,19 +57,86 @@ my_bool my_compress(uchar *packet, size_t *len, size_t *complen) } +/* + Valgrind normally gives false alarms for zlib operations, in the form of + "conditional jump depends on uninitialised values" etc. The reason is + explained in the zlib FAQ (http://www.zlib.net/zlib_faq.html#faq36): + + "That is intentional for performance reasons, and the output of deflate + is not affected." + + Also discussed on a blog + (http://www.sirena.org.uk/log/2006/02/19/zlib-generating-valgrind-warnings/): + + "...loop unrolling in the zlib library causes the mentioned + “Conditional jump or move depends on uninitialised value(s)” + warnings. These are safe since the results of the comparison are + subsequently ignored..." + + "the results of the calculations are discarded by bounds checking done + after the loop exits" + + Fix by initializing the memory allocated by zlib when running under Valgrind. + + This fix is safe, since such memory is only used internally by zlib, so we + will not hide any bugs in mysql this way. +*/ +void *my_az_allocator(void *dummy __attribute__((unused)), unsigned int items, + unsigned int size) +{ + return my_malloc((size_t)items*(size_t)size, IF_VALGRIND(MY_ZEROFILL, MYF(0))); +} + +void my_az_free(void *dummy __attribute__((unused)), void *address) +{ + my_free(address, MYF(MY_ALLOW_ZERO_PTR)); +} + +/* + This works like zlib compress(), but using custom memory allocators to work + better with my_malloc leak detection and Valgrind. +*/ +int my_compress_buffer(uchar *dest, size_t *destLen, + const uchar *source, size_t sourceLen) +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + stream.next_out = (Bytef*)dest; + stream.avail_out = (uInt)*destLen; + if ((size_t)stream.avail_out != *destLen) + return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)my_az_allocator; + stream.zfree = (free_func)my_az_free; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, Z_DEFAULT_COMPRESSION); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + uchar *my_compress_alloc(const uchar *packet, size_t *len, size_t *complen) { uchar *compbuf; - uLongf tmp_complen; int res; *complen= *len * 120 / 100 + 12; if (!(compbuf= (uchar *) my_malloc(*complen, MYF(MY_WME)))) return 0; /* Not enough memory */ - tmp_complen= (uint) *complen; - res= compress((Bytef*) compbuf, &tmp_complen, (Bytef*) packet, (uLong) *len); - *complen= tmp_complen; + res= my_compress_buffer(compbuf, complen, packet, *len); if (res != Z_OK) { @@ -118,7 +185,7 @@ my_bool my_uncompress(uchar *packet, size_t len, size_t *complen) if (!compbuf) DBUG_RETURN(1); /* Not enough memory */ - tmp_complen= (uint) *complen; + tmp_complen= (uLongf) *complen; error= uncompress((Bytef*) compbuf, &tmp_complen, (Bytef*) packet, (uLong) len); *complen= tmp_complen; |