Project

General

Profile

Feature #6615 » zlib.release_gvl.patch

drbrain (Eric Hodel), 06/21/2012 09:20 AM

View differences:

ext/zlib/zlib.c (working copy)
struct zstream;
struct zstream_funcs;
struct zstream_run_args;
static void zstream_init(struct zstream*, const struct zstream_funcs*);
static void zstream_expand_buffer(struct zstream*);
static void zstream_expand_buffer_into(struct zstream*, unsigned long);
......
#define ZSTREAM_AVAIL_OUT_STEP_MIN 2048
static const struct zstream_funcs deflate_funcs = {
deflateReset, deflateEnd, deflate,
deflateReset, deflateEnd, deflate
};
static const struct zstream_funcs inflate_funcs = {
inflateReset, inflateEnd, inflate,
inflateReset, inflateEnd, inflate
};
struct zstream_run_args {
struct zstream * z;
int flush;
};
static voidpf
zlib_mem_alloc(voidpf opaque, uInt items, uInt size)
......
return Qnil;
}
static VALUE
zstream_run_func(void *ptr) {
struct zstream_run_args *args = (struct zstream_run_args *)ptr;
int err, flush = args->flush;
struct zstream *z = args->z;
uInt n;
n = z->stream.avail_out;
err = z->func->run(&z->stream, flush);
z->buf_filled += n - z->stream.avail_out;
return (VALUE)err;
}
/*
* There is no safe way to interrupt z->run->func().
*/
static void
zstream_unblock_func(void *ptr) {
}
static void
zstream_run(struct zstream *z, Bytef *src, long len, int flush)
{
uInt n;
struct zstream_run_args args;
int err;
volatile VALUE guard = Qnil;
args.z = z;
args.flush = flush;
if (NIL_P(z->input) && len == 0) {
z->stream.next_in = (Bytef*)"";
z->stream.avail_in = 0;
......
/* VC allocates err and guard to same address. accessing err and guard
in same scope prevents it. */
RB_GC_GUARD(guard);
n = z->stream.avail_out;
err = z->func->run(&z->stream, flush);
z->buf_filled += n - z->stream.avail_out;
rb_thread_schedule();
err = (int)rb_thread_blocking_region(
zstream_run_func, (void *)&args,
zstream_unblock_func, NULL);
if (err == Z_STREAM_END) {
z->flags &= ~ZSTREAM_FLAG_IN_STREAM;
(1-1/3)