msgpack 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ChangeLog +8 -0
- data/README.md +27 -0
- data/ext/java/org/msgpack/jruby/Factory.java +1 -1
- data/ext/java/org/msgpack/jruby/Packer.java +3 -0
- data/ext/java/org/msgpack/jruby/Unpacker.java +3 -0
- data/ext/msgpack/buffer.c +9 -12
- data/ext/msgpack/buffer.h +2 -10
- data/ext/msgpack/extconf.rb +0 -14
- data/ext/msgpack/factory_class.c +1 -1
- data/ext/msgpack/packer_class.c +4 -0
- data/ext/msgpack/rmem.c +3 -4
- data/ext/msgpack/unpacker.c +7 -20
- data/ext/msgpack/unpacker.h +0 -4
- data/ext/msgpack/unpacker_class.c +6 -14
- data/lib/msgpack/factory.rb +41 -53
- data/lib/msgpack/version.rb +1 -1
- data/msgpack.gemspec +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1414cbfba4f8503d851d6084ef42eb39cfe652d0cadedcf75523e5f472bf425b
|
4
|
+
data.tar.gz: a863d42ac8880a77afe84398b103f4b27d0782db70dd31aad4c785759bcfa20f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ffd9d63c8354684cedfcd682beaf525823646aa9b0b6854175e81f1879eea22fcbf3fba560744210129001263ff80b2fc83ebc99a7405d9f03570921567b1d7
|
7
|
+
data.tar.gz: 4bd0b851caa3d39c05e32d6d90f9f52c376aae4f799247d3d9569db9bc273171c85973e6229de6b9c55e956e2f8c9790a9a4c23e8482944233ed499b421f30c6
|
data/ChangeLog
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
2023-03-29 1.7.0:
|
2
|
+
|
3
|
+
* Fix a possible double-free issue when GC triggers inside `_msgpack_rmem_alloc2`.
|
4
|
+
* `Unpacker#feed` now always directly read in provided strings instead of copying content in its buffer.
|
5
|
+
* `Unpacker#feed` is now an alias of `Unpacker#feed_reference`.
|
6
|
+
* Implement `Factory::Pool#unpacker` and `Factory::Pool#packer` to allow for more precise serialization.
|
7
|
+
* Require Ruby 2.5+.
|
8
|
+
|
1
9
|
2023-03-03 1.6.1:
|
2
10
|
|
3
11
|
* Undefine `#clone` and `#dup` on `MessagePack::Buffer`, `MessagePack::Packer` and `MessagePack::Unpacker`.
|
data/README.md
CHANGED
@@ -211,6 +211,33 @@ factory.register_type(
|
|
211
211
|
factory.load(factory.dump(Point.new(12, 34))) # => #<struct Point x=12, y=34>
|
212
212
|
```
|
213
213
|
|
214
|
+
## Pooling
|
215
|
+
|
216
|
+
Creating `Packer` and `Unpacker` objects is expensive. For best performance it is preferable to re-use these objects.
|
217
|
+
|
218
|
+
`MessagePack::Factory#pool` makes that easier:
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
factory = MessagePack::Factory.new
|
222
|
+
factory.register_type(
|
223
|
+
0x01,
|
224
|
+
Point,
|
225
|
+
packer: ->(point, packer) {
|
226
|
+
packer.write(point.x)
|
227
|
+
packer.write(point.y)
|
228
|
+
},
|
229
|
+
unpacker: ->(unpacker) {
|
230
|
+
x = unpacker.read
|
231
|
+
y = unpacker.read
|
232
|
+
Point.new(x, y)
|
233
|
+
},
|
234
|
+
recursive: true,
|
235
|
+
)
|
236
|
+
pool = factory.pool(5) # The pool size should match the number of threads expected to use the factory concurrently.
|
237
|
+
|
238
|
+
pool.load(pool.dump(Point.new(12, 34))) # => #<struct Point x=12, y=34>
|
239
|
+
```
|
240
|
+
|
214
241
|
## Buffer API
|
215
242
|
|
216
243
|
MessagePack for Ruby provides a buffer API so that you can read or write data by hand, not via Packer or Unpacker API.
|
@@ -96,6 +96,9 @@ public class Packer extends RubyObject {
|
|
96
96
|
@JRubyMethod(name = "register_type", required = 2, optional = 1)
|
97
97
|
public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
|
98
98
|
Ruby runtime = ctx.runtime;
|
99
|
+
if (isFrozen()) {
|
100
|
+
throw runtime.newFrozenError("MessagePack::Packer");
|
101
|
+
}
|
99
102
|
IRubyObject type = args[0];
|
100
103
|
IRubyObject mod = args[1];
|
101
104
|
|
@@ -130,6 +130,9 @@ public class Unpacker extends RubyObject {
|
|
130
130
|
@JRubyMethod(name = "register_type", required = 1, optional = 2)
|
131
131
|
public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
|
132
132
|
Ruby runtime = ctx.runtime;
|
133
|
+
if (isFrozen()) {
|
134
|
+
throw runtime.newFrozenError("MessagePack::Unpacker");
|
135
|
+
}
|
133
136
|
IRubyObject type = args[0];
|
134
137
|
|
135
138
|
RubyModule extModule;
|
data/ext/msgpack/buffer.c
CHANGED
@@ -19,10 +19,6 @@
|
|
19
19
|
#include "buffer.h"
|
20
20
|
#include "rmem.h"
|
21
21
|
|
22
|
-
#ifndef HAVE_RB_STR_REPLACE
|
23
|
-
static ID s_replace;
|
24
|
-
#endif
|
25
|
-
|
26
22
|
int msgpack_rb_encindex_utf8;
|
27
23
|
int msgpack_rb_encindex_usascii;
|
28
24
|
int msgpack_rb_encindex_ascii8bit;
|
@@ -40,10 +36,6 @@ void msgpack_buffer_static_init(void)
|
|
40
36
|
msgpack_rb_encindex_ascii8bit = rb_ascii8bit_encindex();
|
41
37
|
|
42
38
|
msgpack_rmem_init(&s_rmem);
|
43
|
-
|
44
|
-
#ifndef HAVE_RB_STR_REPLACE
|
45
|
-
s_replace = rb_intern("replace");
|
46
|
-
#endif
|
47
39
|
}
|
48
40
|
|
49
41
|
void msgpack_buffer_static_destroy(void)
|
@@ -66,7 +58,11 @@ void msgpack_buffer_init(msgpack_buffer_t* b)
|
|
66
58
|
static void _msgpack_buffer_chunk_destroy(msgpack_buffer_chunk_t* c)
|
67
59
|
{
|
68
60
|
if(c->mem != NULL) {
|
69
|
-
if(
|
61
|
+
if(c->rmem) {
|
62
|
+
if(!msgpack_rmem_free(&s_rmem, c->mem)) {
|
63
|
+
rb_bug("Failed to free an rmem pointer, memory leak?");
|
64
|
+
}
|
65
|
+
} else {
|
70
66
|
xfree(c->mem);
|
71
67
|
}
|
72
68
|
/* no needs to update rmem_owner because chunks will not be
|
@@ -330,14 +326,12 @@ static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE s
|
|
330
326
|
|
331
327
|
void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string)
|
332
328
|
{
|
333
|
-
size_t length = RSTRING_LEN(string);
|
334
|
-
|
335
329
|
if(b->io != Qnil) {
|
336
330
|
msgpack_buffer_flush(b);
|
337
331
|
if (ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit) {
|
338
332
|
rb_funcall(b->io, b->io_write_all_method, 1, string);
|
339
333
|
} else {
|
340
|
-
msgpack_buffer_append(b, RSTRING_PTR(string),
|
334
|
+
msgpack_buffer_append(b, RSTRING_PTR(string), RSTRING_LEN(string));
|
341
335
|
}
|
342
336
|
} else {
|
343
337
|
_msgpack_buffer_append_reference(b, string);
|
@@ -349,6 +343,8 @@ static inline void* _msgpack_buffer_chunk_malloc(
|
|
349
343
|
size_t required_size, size_t* allocated_size)
|
350
344
|
{
|
351
345
|
if(required_size <= MSGPACK_RMEM_PAGE_SIZE) {
|
346
|
+
c->rmem = true;
|
347
|
+
|
352
348
|
if((size_t)(b->rmem_end - b->rmem_last) < required_size) {
|
353
349
|
/* alloc new rmem page */
|
354
350
|
*allocated_size = MSGPACK_RMEM_PAGE_SIZE;
|
@@ -379,6 +375,7 @@ static inline void* _msgpack_buffer_chunk_malloc(
|
|
379
375
|
*allocated_size = required_size;
|
380
376
|
void* mem = xmalloc(required_size);
|
381
377
|
c->mem = mem;
|
378
|
+
c->rmem = false;
|
382
379
|
return mem;
|
383
380
|
}
|
384
381
|
|
data/ext/msgpack/buffer.h
CHANGED
@@ -78,6 +78,7 @@ struct msgpack_buffer_chunk_t {
|
|
78
78
|
void* mem;
|
79
79
|
msgpack_buffer_chunk_t* next;
|
80
80
|
VALUE mapped_string; /* RBString or NO_MAPPED_STRING */
|
81
|
+
bool rmem;
|
81
82
|
};
|
82
83
|
|
83
84
|
union msgpack_buffer_cast_block_t {
|
@@ -267,14 +268,7 @@ static inline size_t msgpack_buffer_append_string(msgpack_buffer_t* b, VALUE str
|
|
267
268
|
static inline size_t msgpack_buffer_append_string_reference(msgpack_buffer_t* b, VALUE string)
|
268
269
|
{
|
269
270
|
size_t length = RSTRING_LEN(string);
|
270
|
-
|
271
|
-
if(length > MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM) {
|
272
|
-
_msgpack_buffer_append_long_string(b, string);
|
273
|
-
|
274
|
-
} else {
|
275
|
-
msgpack_buffer_append(b, RSTRING_PTR(string), length);
|
276
|
-
}
|
277
|
-
|
271
|
+
_msgpack_buffer_append_long_string(b, string);
|
278
272
|
return length;
|
279
273
|
}
|
280
274
|
|
@@ -479,7 +473,6 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
|
|
479
473
|
result = rb_str_new(b->read_buffer, length);
|
480
474
|
}
|
481
475
|
|
482
|
-
#if STR_UMINUS_DEDUPE
|
483
476
|
if (will_be_frozen) {
|
484
477
|
#if STR_UMINUS_DEDUPE_FROZEN
|
485
478
|
// Starting from MRI 2.8 it is preferable to freeze the string
|
@@ -491,7 +484,6 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
|
|
491
484
|
// frozen.
|
492
485
|
result = rb_funcall(result, s_uminus, 0);
|
493
486
|
}
|
494
|
-
#endif // STR_UMINUS_DEDUPE
|
495
487
|
_msgpack_buffer_consumed(b, length);
|
496
488
|
return result;
|
497
489
|
|
data/ext/msgpack/extconf.rb
CHANGED
@@ -28,20 +28,6 @@ else
|
|
28
28
|
$CFLAGS << ' -DHASH_ASET_DEDUPE=0 '
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
# checking if String#-@ (str_uminus) dedupes... ' (Ruby 2.5+)
|
33
|
-
begin
|
34
|
-
a = -(%w(t e s t).join)
|
35
|
-
b = -(%w(t e s t).join)
|
36
|
-
if a.equal?(b)
|
37
|
-
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=1 '
|
38
|
-
else
|
39
|
-
$CFLAGS += ' -DSTR_UMINUS_DEDUPE=0 '
|
40
|
-
end
|
41
|
-
rescue NoMethodError
|
42
|
-
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
|
43
|
-
end
|
44
|
-
|
45
31
|
# checking if String#-@ (str_uminus) directly interns frozen strings... ' (Ruby 3.0+)
|
46
32
|
begin
|
47
33
|
s = rand.to_s.freeze
|
data/ext/msgpack/factory_class.c
CHANGED
@@ -212,7 +212,7 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
212
212
|
VALUE packer_proc, unpacker_proc;
|
213
213
|
|
214
214
|
if (OBJ_FROZEN(self)) {
|
215
|
-
rb_raise(
|
215
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Factory");
|
216
216
|
}
|
217
217
|
|
218
218
|
switch (argc) {
|
data/ext/msgpack/packer_class.c
CHANGED
@@ -349,6 +349,10 @@ static VALUE Packer_registered_types_internal(VALUE self)
|
|
349
349
|
|
350
350
|
static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
|
351
351
|
{
|
352
|
+
if (OBJ_FROZEN(self)) {
|
353
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Packer");
|
354
|
+
}
|
355
|
+
|
352
356
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
353
357
|
|
354
358
|
int ext_type;
|
data/ext/msgpack/rmem.c
CHANGED
@@ -65,11 +65,10 @@ void* _msgpack_rmem_alloc2(msgpack_rmem_t* pm)
|
|
65
65
|
/* allocate new chunk */
|
66
66
|
c = pm->array_last++;
|
67
67
|
|
68
|
-
/* move to
|
69
|
-
|
70
|
-
pm->head = *c;
|
71
|
-
*c = tmp;
|
68
|
+
/* move head to array */
|
69
|
+
*c = pm->head;
|
72
70
|
|
71
|
+
pm->head.pages = NULL; /* make sure we don't point to another chunk's pages in case xmalloc triggers GC */
|
73
72
|
pm->head.mask = 0xffffffff & (~1); /* "& (~1)" means first chunk is already allocated */
|
74
73
|
pm->head.pages = xmalloc(MSGPACK_RMEM_PAGE_SIZE * 32);
|
75
74
|
|
data/ext/msgpack/unpacker.c
CHANGED
@@ -20,19 +20,17 @@
|
|
20
20
|
#include "rmem.h"
|
21
21
|
#include "extension_value_class.h"
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
_Static_assert(
|
24
|
+
sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE,
|
25
|
+
"msgpack_unpacker_stack_entry_t is too big to fit MSGPACK_UNPACKER_STACK_CAPACITY in MSGPACK_RMEM_PAGE_SIZE"
|
26
|
+
);
|
27
27
|
|
28
28
|
static int RAW_TYPE_STRING = 256;
|
29
29
|
static int RAW_TYPE_BINARY = 257;
|
30
30
|
|
31
31
|
static ID s_call;
|
32
32
|
|
33
|
-
#ifdef UNPACKER_STACK_RMEM
|
34
33
|
static msgpack_rmem_t s_stack_rmem;
|
35
|
-
#endif
|
36
34
|
|
37
35
|
#if !defined(HAVE_RB_HASH_NEW_CAPA)
|
38
36
|
static inline VALUE rb_hash_new_capa(long capa)
|
@@ -43,18 +41,14 @@ static inline VALUE rb_hash_new_capa(long capa)
|
|
43
41
|
|
44
42
|
void msgpack_unpacker_static_init(void)
|
45
43
|
{
|
46
|
-
#ifdef UNPACKER_STACK_RMEM
|
47
44
|
msgpack_rmem_init(&s_stack_rmem);
|
48
|
-
#endif
|
49
45
|
|
50
46
|
s_call = rb_intern("call");
|
51
47
|
}
|
52
48
|
|
53
49
|
void msgpack_unpacker_static_destroy(void)
|
54
50
|
{
|
55
|
-
#ifdef UNPACKER_STACK_RMEM
|
56
51
|
msgpack_rmem_destroy(&s_stack_rmem);
|
57
|
-
#endif
|
58
52
|
}
|
59
53
|
|
60
54
|
#define HEAD_BYTE_REQUIRED 0xc1
|
@@ -62,13 +56,8 @@ void msgpack_unpacker_static_destroy(void)
|
|
62
56
|
static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
|
63
57
|
msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
|
64
58
|
stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
65
|
-
#ifdef UNPACKER_STACK_RMEM
|
66
59
|
stack->data = msgpack_rmem_alloc(&s_stack_rmem);
|
67
60
|
/*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
|
68
|
-
#else
|
69
|
-
/*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_entry_t));*/
|
70
|
-
stack->data = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_entry_t));
|
71
|
-
#endif
|
72
61
|
return stack;
|
73
62
|
}
|
74
63
|
|
@@ -85,11 +74,9 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
|
85
74
|
}
|
86
75
|
|
87
76
|
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
xfree(stack->data);
|
92
|
-
#endif
|
77
|
+
if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
|
78
|
+
rb_bug("Failed to free an rmem pointer, memory leak?");
|
79
|
+
}
|
93
80
|
xfree(stack);
|
94
81
|
}
|
95
82
|
|
data/ext/msgpack/unpacker.h
CHANGED
@@ -21,9 +21,7 @@
|
|
21
21
|
#include "buffer.h"
|
22
22
|
#include "unpacker_ext_registry.h"
|
23
23
|
|
24
|
-
#ifndef MSGPACK_UNPACKER_STACK_CAPACITY
|
25
24
|
#define MSGPACK_UNPACKER_STACK_CAPACITY 128
|
26
|
-
#endif
|
27
25
|
|
28
26
|
struct msgpack_unpacker_t;
|
29
27
|
typedef struct msgpack_unpacker_t msgpack_unpacker_t;
|
@@ -49,8 +47,6 @@ struct msgpack_unpacker_stack_t {
|
|
49
47
|
msgpack_unpacker_stack_t *parent;
|
50
48
|
};
|
51
49
|
|
52
|
-
#define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */
|
53
|
-
|
54
50
|
struct msgpack_unpacker_t {
|
55
51
|
msgpack_buffer_t buffer;
|
56
52
|
msgpack_unpacker_stack_t *stack;
|
@@ -249,18 +249,6 @@ static VALUE Unpacker_read_map_header(VALUE self)
|
|
249
249
|
return ULONG2NUM(size); // long at least 32 bits
|
250
250
|
}
|
251
251
|
|
252
|
-
|
253
|
-
static VALUE Unpacker_feed(VALUE self, VALUE data)
|
254
|
-
{
|
255
|
-
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
256
|
-
|
257
|
-
StringValue(data);
|
258
|
-
|
259
|
-
msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data);
|
260
|
-
|
261
|
-
return self;
|
262
|
-
}
|
263
|
-
|
264
252
|
static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
265
253
|
{
|
266
254
|
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
@@ -360,6 +348,10 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
|
|
360
348
|
|
361
349
|
static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
362
350
|
{
|
351
|
+
if (OBJ_FROZEN(self)) {
|
352
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Unpacker");
|
353
|
+
}
|
354
|
+
|
363
355
|
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
364
356
|
|
365
357
|
int ext_type;
|
@@ -457,8 +449,8 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
457
449
|
rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
|
458
450
|
rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
|
459
451
|
rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
|
460
|
-
rb_define_method(cMessagePack_Unpacker, "feed",
|
461
|
-
|
452
|
+
rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed_reference, 1);
|
453
|
+
rb_define_alias(cMessagePack_Unpacker, "feed_reference", "feed");
|
462
454
|
rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
|
463
455
|
rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);
|
464
456
|
rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
|
data/lib/msgpack/factory.rb
CHANGED
@@ -88,33 +88,34 @@ module MessagePack
|
|
88
88
|
|
89
89
|
class Pool
|
90
90
|
if RUBY_ENGINE == "ruby"
|
91
|
-
class
|
91
|
+
class MemberPool
|
92
92
|
def initialize(size, &block)
|
93
93
|
@size = size
|
94
94
|
@new_member = block
|
95
95
|
@members = []
|
96
96
|
end
|
97
97
|
|
98
|
-
def
|
99
|
-
@members.pop || @new_member.call
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
98
|
+
def with
|
99
|
+
member = @members.pop || @new_member.call
|
100
|
+
begin
|
101
|
+
yield member
|
102
|
+
ensure
|
103
|
+
# If the pool is already full, we simply drop the extra member.
|
104
|
+
# This is because contrary to a connection pool, creating an extra instance
|
105
|
+
# is extremely unlikely to cause some kind of resource exhaustion.
|
106
|
+
#
|
107
|
+
# We could cycle the members (keep the newer one) but first It's more work and second
|
108
|
+
# the older member might have been created pre-fork, so it might be at least partially
|
109
|
+
# in shared memory.
|
110
|
+
if member && @members.size < @size
|
111
|
+
member.reset
|
112
|
+
@members << member
|
113
|
+
end
|
113
114
|
end
|
114
115
|
end
|
115
116
|
end
|
116
117
|
else
|
117
|
-
class
|
118
|
+
class MemberPool
|
118
119
|
def initialize(size, &block)
|
119
120
|
@size = size
|
120
121
|
@new_member = block
|
@@ -122,63 +123,50 @@ module MessagePack
|
|
122
123
|
@mutex = Mutex.new
|
123
124
|
end
|
124
125
|
|
125
|
-
def
|
126
|
-
@mutex.synchronize { @members.pop } || @new_member.call
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
member.
|
133
|
-
|
126
|
+
def with
|
127
|
+
member = @mutex.synchronize { @members.pop } || @new_member.call
|
128
|
+
begin
|
129
|
+
yield member
|
130
|
+
ensure
|
131
|
+
member.reset
|
132
|
+
@mutex.synchronize do
|
133
|
+
if member && @members.size < @size
|
134
|
+
@members << member
|
135
|
+
end
|
134
136
|
end
|
135
137
|
end
|
136
138
|
end
|
137
139
|
end
|
138
140
|
end
|
139
141
|
|
140
|
-
class PackerPool < AbstractPool
|
141
|
-
private
|
142
|
-
|
143
|
-
def reset(packer)
|
144
|
-
packer.clear
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
class UnpackerPool < AbstractPool
|
149
|
-
private
|
150
|
-
|
151
|
-
def reset(unpacker)
|
152
|
-
unpacker.reset
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
142
|
def initialize(factory, size, options = nil)
|
157
143
|
options = nil if !options || options.empty?
|
158
144
|
@factory = factory
|
159
|
-
@packers =
|
160
|
-
@unpackers =
|
145
|
+
@packers = MemberPool.new(size) { factory.packer(options).freeze }
|
146
|
+
@unpackers = MemberPool.new(size) { factory.unpacker(options).freeze }
|
161
147
|
end
|
162
148
|
|
163
149
|
def load(data)
|
164
|
-
|
165
|
-
|
166
|
-
unpacker.feed_reference(data)
|
150
|
+
@unpackers.with do |unpacker|
|
151
|
+
unpacker.feed(data)
|
167
152
|
unpacker.full_unpack
|
168
|
-
ensure
|
169
|
-
@unpackers.checkin(unpacker)
|
170
153
|
end
|
171
154
|
end
|
172
155
|
|
173
156
|
def dump(object)
|
174
|
-
|
175
|
-
begin
|
157
|
+
@packers.with do |packer|
|
176
158
|
packer.write(object)
|
177
159
|
packer.full_pack
|
178
|
-
ensure
|
179
|
-
@packers.checkin(packer)
|
180
160
|
end
|
181
161
|
end
|
162
|
+
|
163
|
+
def unpacker(&block)
|
164
|
+
@unpackers.with(&block)
|
165
|
+
end
|
166
|
+
|
167
|
+
def packer(&block)
|
168
|
+
@packers.with(&block)
|
169
|
+
end
|
182
170
|
end
|
183
171
|
end
|
184
172
|
end
|
data/lib/msgpack/version.rb
CHANGED
data/msgpack.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: msgpack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-03-
|
13
|
+
date: 2023-03-29 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -201,7 +201,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
201
201
|
requirements:
|
202
202
|
- - ">="
|
203
203
|
- !ruby/object:Gem::Version
|
204
|
-
version: '2.
|
204
|
+
version: '2.5'
|
205
205
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
206
206
|
requirements:
|
207
207
|
- - ">="
|