Feature #6615 » zlib.release_gvl.patch
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;
|