rbczmq 1.6.4 → 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 +15 -0
- data/CHANGELOG.rdoc +7 -0
- data/Gemfile.lock +1 -1
- data/ext/rbczmq/beacon.c +1 -1
- data/ext/rbczmq/beacon.h +1 -1
- data/ext/rbczmq/frame.c +63 -50
- data/ext/rbczmq/frame.h +41 -9
- data/ext/rbczmq/message.c +186 -56
- data/ext/rbczmq/message.h +18 -2
- data/ext/rbczmq/pollitem.c +1 -1
- data/ext/rbczmq/rbczmq_ext.c +0 -4
- data/ext/rbczmq/rbczmq_ext.h +0 -2
- data/ext/rbczmq/socket.c +11 -5
- data/lib/zmq.rb +2 -1
- data/lib/zmq/logger.rb +58 -0
- data/lib/zmq/version.rb +2 -2
- data/test/test_frame.rb +2 -3
- data/test/test_logger.rb +41 -0
- data/test/test_message.rb +98 -5
- metadata +8 -10
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            !binary "U0hBMQ==":
         | 
| 3 | 
            +
              metadata.gz: !binary |-
         | 
| 4 | 
            +
                NTIyYzk0ZmFkOTc4Y2YwMmRlYzc3ZGE0NmQyZTBhOGRlODQyMDcxMA==
         | 
| 5 | 
            +
              data.tar.gz: !binary |-
         | 
| 6 | 
            +
                NTI4NzQyMDhkNGRjNGE5NDgxMDE3ZDg5MjU2YTViZWZiMWNjYzQxZA==
         | 
| 7 | 
            +
            !binary "U0hBNTEy":
         | 
| 8 | 
            +
              metadata.gz: !binary |-
         | 
| 9 | 
            +
                ZmQ5NzExNWFhM2ZiODBlZmY4ZDZkMmM5YjBjMDQxODNkZDFlNTUxZmZlMjIz
         | 
| 10 | 
            +
                N2JkZGU0Mjg4NzJlZTM2ZTEzYjI5ZDdkMGExNDU5MGMzMDE1ZjM2OTUxOTk4
         | 
| 11 | 
            +
                ZDAyYjcwNTcyOGUzYjNhOTFkYzYyZTM5NTBkNjgyNDgyN2Q0ZDg=
         | 
| 12 | 
            +
              data.tar.gz: !binary |-
         | 
| 13 | 
            +
                NDJmOGNmNmMwNGM3YjY5NmUwYTZmOTYzNzAyNGU5YzFmMTc0NGRhYTUzYjIw
         | 
| 14 | 
            +
                YzI0YjJiODBlMjliMGQyYThjNjFhMWE1MWExZTJhNjAzNTMyNjQzZTM2YWZk
         | 
| 15 | 
            +
                M2NiYzc5Mzc0NGE0NjlkMmQ1YzBmYTMyYjdiZjkxNmFkMGE5ZTI=
         | 
    
        data/CHANGELOG.rdoc
    CHANGED
    
    | @@ -1,5 +1,12 @@ | |
| 1 1 | 
             
            = Changelog
         | 
| 2 2 |  | 
| 3 | 
            +
            == 1.7.0 (July 21, 2013)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * ZMQ::Frame - Implemented an interal wrapper around the underlying czmq frame objects to better manage memory and object ownership. (Matt Connolly)
         | 
| 6 | 
            +
            * ZMQ::Frame#gone? and ZMQ::Message#gone? - new methods, return true when the frame/message has been sent and is no longer available for accessing. Methods may return nil for read operations or raise ZMQ::Error if the frame/message would be changed by that method. (Matt Connolly)
         | 
| 7 | 
            +
            * ZMQ::Message - iterators (#first, #next, #last and #to_a) return consistent frame objects (not duplicates as in previous versions) that can be used with #remove. (Matt Connolly)
         | 
| 8 | 
            +
            * Sending a message or frame marks it as "gone". The underlying data objects will be released by ZeroMQ as the frames/messages are sent over the socket. (Matt Connolly)
         | 
| 9 | 
            +
             | 
| 3 10 | 
             
            == 1.6.4 (July 10, 2013)
         | 
| 4 11 | 
             
            * Depend on a checkout task for vendored submodule init (Matt Connolly)
         | 
| 5 12 |  | 
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/ext/rbczmq/beacon.c
    CHANGED
    
    | @@ -315,4 +315,4 @@ void _init_rb_czmq_beacon() | |
| 315 315 | 
             
                rb_define_method(rb_cZmqBeacon, "subscribe", rb_czmq_beacon_subscribe, 1);
         | 
| 316 316 | 
             
                rb_define_method(rb_cZmqBeacon, "unsubscribe", rb_czmq_beacon_unsubscribe, 0);
         | 
| 317 317 | 
             
                rb_define_method(rb_cZmqBeacon, "pipe", rb_czmq_beacon_pipe, 0);
         | 
| 318 | 
            -
            }
         | 
| 318 | 
            +
            }
         | 
    
        data/ext/rbczmq/beacon.h
    CHANGED
    
    
    
        data/ext/rbczmq/frame.c
    CHANGED
    
    | @@ -1,18 +1,6 @@ | |
| 1 1 | 
             
            #include "rbczmq_ext.h"
         | 
| 2 2 | 
             
            static VALUE intern_data;
         | 
| 3 3 |  | 
| 4 | 
            -
            /*
         | 
| 5 | 
            -
             * :nodoc:
         | 
| 6 | 
            -
             *  Callback invoked by zframe_destroy in libczmq. We track all frames coerced to native objects in a symbol table
         | 
| 7 | 
            -
             *  to guard against a mismatch between allocated frames and the Ruby object space as zframe_destroy is invoked
         | 
| 8 | 
            -
             *  throughout libczmq (zmsg.c) where the Ruby GC can't easily track it. Ruby MRI Object finalizers are a real
         | 
| 9 | 
            -
             *  pita to deal with.
         | 
| 10 | 
            -
             *
         | 
| 11 | 
            -
            */
         | 
| 12 | 
            -
            void rb_czmq_frame_freed(zframe_t *frame)
         | 
| 13 | 
            -
            {
         | 
| 14 | 
            -
                st_delete(frames_map, (st_data_t*)&frame, 0);
         | 
| 15 | 
            -
            }
         | 
| 16 4 |  | 
| 17 5 | 
             
            /*
         | 
| 18 6 | 
             
             * :nodoc:
         | 
| @@ -22,8 +10,11 @@ void rb_czmq_frame_freed(zframe_t *frame) | |
| 22 10 | 
             
            VALUE rb_czmq_alloc_frame(zframe_t *frame)
         | 
| 23 11 | 
             
            {
         | 
| 24 12 | 
             
                VALUE frame_obj;
         | 
| 25 | 
            -
                 | 
| 26 | 
            -
                frame_obj =  | 
| 13 | 
            +
                zmq_frame_wrapper* f;
         | 
| 14 | 
            +
                frame_obj = Data_Make_Struct(rb_cZmqFrame, zmq_frame_wrapper, 0, rb_czmq_free_frame_gc, f);
         | 
| 15 | 
            +
                f->frame = frame;
         | 
| 16 | 
            +
                f->flags = ZMQ_FRAME_OWNED;
         | 
| 17 | 
            +
                f->message = NULL;
         | 
| 27 18 | 
             
                rb_obj_call_init(frame_obj, 0, NULL);
         | 
| 28 19 | 
             
                return frame_obj;
         | 
| 29 20 | 
             
            }
         | 
| @@ -35,13 +26,11 @@ VALUE rb_czmq_alloc_frame(zframe_t *frame) | |
| 35 26 | 
             
             *  libczmq.
         | 
| 36 27 | 
             
             *
         | 
| 37 28 | 
             
            */
         | 
| 38 | 
            -
            void rb_czmq_free_frame( | 
| 29 | 
            +
            void rb_czmq_free_frame(zmq_frame_wrapper *frame)
         | 
| 39 30 | 
             
            {
         | 
| 40 | 
            -
                if (frame) {
         | 
| 41 | 
            -
                     | 
| 42 | 
            -
             | 
| 43 | 
            -
                        zframe_destroy(&frame);
         | 
| 44 | 
            -
                    }
         | 
| 31 | 
            +
                if (frame && frame->frame && (frame->flags & ZMQ_FRAME_OWNED) != 0) {
         | 
| 32 | 
            +
                    zframe_destroy(&frame->frame);
         | 
| 33 | 
            +
                    frame->flags &= ~ZMQ_FRAME_OWNED;
         | 
| 45 34 | 
             
                }
         | 
| 46 35 | 
             
            }
         | 
| 47 36 |  | 
| @@ -52,7 +41,7 @@ void rb_czmq_free_frame(zframe_t *frame) | |
| 52 41 | 
             
            */
         | 
| 53 42 | 
             
            void rb_czmq_free_frame_gc(void *ptr)
         | 
| 54 43 | 
             
            {
         | 
| 55 | 
            -
                 | 
| 44 | 
            +
                zmq_frame_wrapper *frame = (zmq_frame_wrapper *)ptr;
         | 
| 56 45 | 
             
                rb_czmq_free_frame(frame);
         | 
| 57 46 | 
             
            }
         | 
| 58 47 |  | 
| @@ -85,10 +74,7 @@ static VALUE rb_czmq_frame_s_new(int argc, VALUE *argv, VALUE frame) | |
| 85 74 | 
             
                    ZmqAssertSysError();
         | 
| 86 75 | 
             
                    rb_memerror();
         | 
| 87 76 | 
             
                }
         | 
| 88 | 
            -
                 | 
| 89 | 
            -
                frame = Data_Wrap_Struct(rb_cZmqFrame, 0, rb_czmq_free_frame_gc, fr);
         | 
| 90 | 
            -
                rb_obj_call_init(frame, 0, NULL);
         | 
| 91 | 
            -
                return frame;
         | 
| 77 | 
            +
                return rb_czmq_alloc_frame(fr);
         | 
| 92 78 | 
             
            }
         | 
| 93 79 |  | 
| 94 80 | 
             
            /*
         | 
| @@ -108,6 +94,7 @@ static VALUE rb_czmq_frame_s_new(int argc, VALUE *argv, VALUE frame) | |
| 108 94 | 
             
            static VALUE rb_czmq_frame_destroy(VALUE obj)
         | 
| 109 95 | 
             
            {
         | 
| 110 96 | 
             
                ZmqGetFrame(obj);
         | 
| 97 | 
            +
                ZmqAssertFrameOwned(frame);
         | 
| 111 98 | 
             
                rb_czmq_free_frame(frame);
         | 
| 112 99 | 
             
                return Qnil;
         | 
| 113 100 | 
             
            }
         | 
| @@ -128,7 +115,8 @@ static VALUE rb_czmq_frame_size(VALUE obj) | |
| 128 115 | 
             
            {
         | 
| 129 116 | 
             
                size_t size;
         | 
| 130 117 | 
             
                ZmqGetFrame(obj);
         | 
| 131 | 
            -
                 | 
| 118 | 
            +
                ZmqReturnNilUnlessFrameOwned(frame);
         | 
| 119 | 
            +
                size = zframe_size(frame->frame);
         | 
| 132 120 | 
             
                return LONG2FIX(size);
         | 
| 133 121 | 
             
            }
         | 
| 134 122 |  | 
| @@ -148,8 +136,9 @@ static VALUE rb_czmq_frame_data(VALUE obj) | |
| 148 136 | 
             
            {
         | 
| 149 137 | 
             
                size_t size;
         | 
| 150 138 | 
             
                ZmqGetFrame(obj);
         | 
| 151 | 
            -
                 | 
| 152 | 
            -
                 | 
| 139 | 
            +
                ZmqReturnNilUnlessFrameOwned(frame);
         | 
| 140 | 
            +
                size = zframe_size(frame->frame);
         | 
| 141 | 
            +
                return ZmqEncode(rb_str_new((char *)zframe_data(frame->frame), (long)size));
         | 
| 153 142 | 
             
            }
         | 
| 154 143 |  | 
| 155 144 | 
             
            /*
         | 
| @@ -184,7 +173,8 @@ static VALUE rb_czmq_frame_to_s(VALUE obj) | |
| 184 173 | 
             
            static VALUE rb_czmq_frame_strhex(VALUE obj)
         | 
| 185 174 | 
             
            {
         | 
| 186 175 | 
             
                ZmqGetFrame(obj);
         | 
| 187 | 
            -
                 | 
| 176 | 
            +
                ZmqReturnNilUnlessFrameOwned(frame);
         | 
| 177 | 
            +
                return rb_str_new2(zframe_strhex(frame->frame));
         | 
| 188 178 | 
             
            }
         | 
| 189 179 |  | 
| 190 180 | 
             
            /*
         | 
| @@ -201,19 +191,15 @@ static VALUE rb_czmq_frame_strhex(VALUE obj) | |
| 201 191 |  | 
| 202 192 | 
             
            static VALUE rb_czmq_frame_dup(VALUE obj)
         | 
| 203 193 | 
             
            {
         | 
| 204 | 
            -
                VALUE dup;
         | 
| 205 194 | 
             
                zframe_t *dup_fr = NULL;
         | 
| 206 | 
            -
                errno = 0;
         | 
| 207 195 | 
             
                ZmqGetFrame(obj);
         | 
| 208 | 
            -
                 | 
| 196 | 
            +
                ZmqAssertFrameOwned(frame);
         | 
| 197 | 
            +
                dup_fr = zframe_dup(frame->frame);
         | 
| 209 198 | 
             
                if (dup_fr == NULL) {
         | 
| 210 199 | 
             
                    ZmqAssertSysError();
         | 
| 211 200 | 
             
                    rb_memerror();
         | 
| 212 201 | 
             
                }
         | 
| 213 | 
            -
                 | 
| 214 | 
            -
                dup = Data_Wrap_Struct(rb_cZmqFrame, 0, rb_czmq_free_frame_gc, dup_fr);
         | 
| 215 | 
            -
                rb_obj_call_init(dup, 0, NULL);
         | 
| 216 | 
            -
                return dup;
         | 
| 202 | 
            +
                return rb_czmq_alloc_frame(dup_fr);
         | 
| 217 203 | 
             
            }
         | 
| 218 204 |  | 
| 219 205 | 
             
            /*
         | 
| @@ -231,8 +217,9 @@ static VALUE rb_czmq_frame_dup(VALUE obj) | |
| 231 217 | 
             
            static VALUE rb_czmq_frame_data_equals_p(VALUE obj, VALUE data)
         | 
| 232 218 | 
             
            {
         | 
| 233 219 | 
             
                ZmqGetFrame(obj);
         | 
| 220 | 
            +
                ZmqAssertFrameOwned(frame);
         | 
| 234 221 | 
             
                Check_Type(data, T_STRING);
         | 
| 235 | 
            -
                return (zframe_streq(frame, RSTRING_PTR(data)) == true) ? Qtrue : Qfalse;
         | 
| 222 | 
            +
                return (zframe_streq(frame->frame, RSTRING_PTR(data)) == true) ? Qtrue : Qfalse;
         | 
| 236 223 | 
             
            }
         | 
| 237 224 |  | 
| 238 225 | 
             
            /*
         | 
| @@ -250,7 +237,8 @@ static VALUE rb_czmq_frame_data_equals_p(VALUE obj, VALUE data) | |
| 250 237 | 
             
            static VALUE rb_czmq_frame_more_p(VALUE obj)
         | 
| 251 238 | 
             
            {
         | 
| 252 239 | 
             
                ZmqGetFrame(obj);
         | 
| 253 | 
            -
                 | 
| 240 | 
            +
                ZmqReturnNilUnlessFrameOwned(frame);
         | 
| 241 | 
            +
                return (zframe_more(frame->frame) == ZFRAME_MORE) ? Qtrue : Qfalse;
         | 
| 254 242 | 
             
            }
         | 
| 255 243 |  | 
| 256 244 | 
             
            /*
         | 
| @@ -268,13 +256,14 @@ static VALUE rb_czmq_frame_more_p(VALUE obj) | |
| 268 256 |  | 
| 269 257 | 
             
            static VALUE rb_czmq_frame_eql_p(VALUE obj, VALUE other_frame)
         | 
| 270 258 | 
             
            {
         | 
| 271 | 
            -
                 | 
| 259 | 
            +
                zmq_frame_wrapper *other = NULL;
         | 
| 272 260 | 
             
                ZmqGetFrame(obj);
         | 
| 261 | 
            +
                ZmqAssertFrameOwned(frame);
         | 
| 273 262 | 
             
                ZmqAssertFrame(other_frame);
         | 
| 274 | 
            -
                Data_Get_Struct(other_frame,  | 
| 275 | 
            -
                if (!other) rb_raise(rb_eTypeError, "uninitialized ZMQ frame!"); \
         | 
| 276 | 
            -
                 | 
| 277 | 
            -
                return (zframe_eq(frame, other)) ? Qtrue : Qfalse;
         | 
| 263 | 
            +
                Data_Get_Struct(other_frame, zmq_frame_wrapper, other);
         | 
| 264 | 
            +
                if (!other || !other->frame) rb_raise(rb_eTypeError, "uninitialized ZMQ frame!"); \
         | 
| 265 | 
            +
                ZmqAssertFrameOwned(other);
         | 
| 266 | 
            +
                return (zframe_eq(frame->frame, other->frame)) ? Qtrue : Qfalse;
         | 
| 278 267 | 
             
            }
         | 
| 279 268 |  | 
| 280 269 | 
             
            /*
         | 
| @@ -313,14 +302,15 @@ static VALUE rb_czmq_frame_equals(VALUE obj, VALUE other_frame) | |
| 313 302 | 
             
            static VALUE rb_czmq_frame_cmp(VALUE obj, VALUE other_frame)
         | 
| 314 303 | 
             
            {
         | 
| 315 304 | 
             
                long diff;
         | 
| 316 | 
            -
                 | 
| 305 | 
            +
                zmq_frame_wrapper *other = NULL;
         | 
| 317 306 | 
             
                if (obj == other_frame) return INT2NUM(0);
         | 
| 318 307 | 
             
                ZmqGetFrame(obj);
         | 
| 308 | 
            +
                ZmqAssertFrameOwned(frame);
         | 
| 319 309 | 
             
                ZmqAssertFrame(other_frame);
         | 
| 320 | 
            -
                Data_Get_Struct(other_frame,  | 
| 321 | 
            -
                if (!other) rb_raise(rb_eTypeError, "uninitialized ZMQ frame!"); | 
| 322 | 
            -
                 | 
| 323 | 
            -
                diff = (zframe_size(frame) - zframe_size(other));
         | 
| 310 | 
            +
                Data_Get_Struct(other_frame, zmq_frame_wrapper, other);
         | 
| 311 | 
            +
                if (!other || !other->frame) rb_raise(rb_eTypeError, "uninitialized ZMQ frame!");
         | 
| 312 | 
            +
                ZmqAssertFrameOwned(frame);
         | 
| 313 | 
            +
                diff = (zframe_size(frame->frame) - zframe_size(other->frame));
         | 
| 324 314 | 
             
                if (diff == 0) return INT2NUM(0);
         | 
| 325 315 | 
             
                if (diff > 0) return INT2NUM(1);
         | 
| 326 316 | 
             
                return INT2NUM(-1);
         | 
| @@ -343,6 +333,7 @@ static VALUE rb_czmq_frame_print(int argc, VALUE *argv, VALUE obj) | |
| 343 333 | 
             
                VALUE prefix;
         | 
| 344 334 | 
             
                const char *print_prefix = NULL;
         | 
| 345 335 | 
             
                ZmqGetFrame(obj);
         | 
| 336 | 
            +
                ZmqAssertFrameOwned(frame);
         | 
| 346 337 | 
             
                rb_scan_args(argc, argv, "01", &prefix);
         | 
| 347 338 | 
             
                if (NIL_P(prefix)) {
         | 
| 348 339 | 
             
                    print_prefix = "";
         | 
| @@ -350,7 +341,7 @@ static VALUE rb_czmq_frame_print(int argc, VALUE *argv, VALUE obj) | |
| 350 341 | 
             
                    Check_Type(prefix, T_STRING);
         | 
| 351 342 | 
             
                    print_prefix = RSTRING_PTR(prefix);
         | 
| 352 343 | 
             
                }
         | 
| 353 | 
            -
                zframe_print(frame, (char *)print_prefix);
         | 
| 344 | 
            +
                zframe_print(frame->frame, (char *)print_prefix);
         | 
| 354 345 | 
             
                return Qnil;
         | 
| 355 346 | 
             
            }
         | 
| 356 347 |  | 
| @@ -371,12 +362,33 @@ static VALUE rb_czmq_frame_reset(VALUE obj, VALUE data) | |
| 371 362 | 
             
            {
         | 
| 372 363 | 
             
                errno = 0;
         | 
| 373 364 | 
             
                ZmqGetFrame(obj);
         | 
| 365 | 
            +
                ZmqAssertFrameOwned(frame);
         | 
| 374 366 | 
             
                Check_Type(data, T_STRING);
         | 
| 375 | 
            -
                zframe_reset(frame, (char *)RSTRING_PTR(data), (size_t)RSTRING_LEN(data));
         | 
| 367 | 
            +
                zframe_reset(frame->frame, (char *)RSTRING_PTR(data), (size_t)RSTRING_LEN(data));
         | 
| 376 368 | 
             
                ZmqAssertSysError();
         | 
| 377 369 | 
             
                return Qnil;
         | 
| 378 370 | 
             
            }
         | 
| 379 371 |  | 
| 372 | 
            +
            /*
         | 
| 373 | 
            +
             * call-seq:
         | 
| 374 | 
            +
             *    frame.gone?   #=> false
         | 
| 375 | 
            +
             *    frame.destroy # or send
         | 
| 376 | 
            +
             *    frame.gone?   #=> true
         | 
| 377 | 
            +
             *
         | 
| 378 | 
            +
             * Return boolean indicating if the ZMQ::Frame is gone (sent or destroyed). If the message is
         | 
| 379 | 
            +
             * gone, accessor methods will return nil and methods requiring data or methods that mutate
         | 
| 380 | 
            +
             * the message will raise an exception.
         | 
| 381 | 
            +
            */
         | 
| 382 | 
            +
             | 
| 383 | 
            +
            static VALUE rb_czmq_frame_gone(VALUE obj)
         | 
| 384 | 
            +
            {
         | 
| 385 | 
            +
                ZmqGetFrame(obj);
         | 
| 386 | 
            +
                return (frame->flags & ZMQ_FRAME_OWNED) ||
         | 
| 387 | 
            +
                       (frame->message != NULL && (frame->message->flags & ZMQ_MESSAGE_OWNED))
         | 
| 388 | 
            +
                           ? Qfalse : Qtrue;
         | 
| 389 | 
            +
            }
         | 
| 390 | 
            +
             | 
| 391 | 
            +
             | 
| 380 392 | 
             
            void _init_rb_czmq_frame()
         | 
| 381 393 | 
             
            {
         | 
| 382 394 | 
             
                intern_data = rb_intern("data");
         | 
| @@ -403,4 +415,5 @@ void _init_rb_czmq_frame() | |
| 403 415 | 
             
                rb_define_method(rb_cZmqFrame, "print", rb_czmq_frame_print, -1);
         | 
| 404 416 | 
             
                rb_define_alias(rb_cZmqFrame, "dump", "print");
         | 
| 405 417 | 
             
                rb_define_method(rb_cZmqFrame, "reset", rb_czmq_frame_reset, 1);
         | 
| 418 | 
            +
                rb_define_method(rb_cZmqFrame, "gone?", rb_czmq_frame_gone, 0);
         | 
| 406 419 | 
             
            }
         | 
    
        data/ext/rbczmq/frame.h
    CHANGED
    
    | @@ -1,21 +1,53 @@ | |
| 1 1 | 
             
            #ifndef RBCZMQ_FRAME_H
         | 
| 2 2 | 
             
            #define RBCZMQ_FRAME_H
         | 
| 3 3 |  | 
| 4 | 
            +
            #include "message.h"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            /* This flag indicates that the wrapped zframe_t is owned by ruby
         | 
| 7 | 
            +
               and can be freed when the ZMQ::Frame object is garbage collected */
         | 
| 8 | 
            +
            #define ZMQ_FRAME_OWNED 0x01
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            typedef struct {
         | 
| 11 | 
            +
                /* The czmq frame object. This is only valid if the frame is owned
         | 
| 12 | 
            +
                   by ruby, or the frame has been added to a message and the message
         | 
| 13 | 
            +
                   is owned by ruby. */
         | 
| 14 | 
            +
                zframe_t *frame;
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                /* The ruby ZMQ::Message object this frame is attached to, or NULL */
         | 
| 17 | 
            +
                zmq_message_wrapper* message;
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                int flags;
         | 
| 20 | 
            +
            } zmq_frame_wrapper;
         | 
| 21 | 
            +
             | 
| 4 22 | 
             
            #define ZmqAssertFrame(obj) ZmqAssertType(obj, rb_cZmqFrame, "ZMQ::Frame")
         | 
| 5 23 | 
             
            #define ZmqGetFrame(obj) \
         | 
| 6 | 
            -
                 | 
| 24 | 
            +
                zmq_frame_wrapper *frame = NULL; \
         | 
| 7 25 | 
             
                ZmqAssertFrame(obj); \
         | 
| 8 | 
            -
                Data_Get_Struct(obj,  | 
| 9 | 
            -
                if (!frame) rb_raise(rb_eTypeError, "uninitialized ZMQ frame!"); | 
| 10 | 
            -
             | 
| 26 | 
            +
                Data_Get_Struct(obj, zmq_frame_wrapper, frame); \
         | 
| 27 | 
            +
                if (!frame) rb_raise(rb_eTypeError, "uninitialized ZMQ frame!");
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            #define ZmqAssertFrameOwned(wrapper) if (!(\
         | 
| 30 | 
            +
                  (wrapper->flags & ZMQ_FRAME_OWNED) != 0 || \
         | 
| 31 | 
            +
                  (wrapper->message != NULL && (wrapper->message->flags & ZMQ_MESSAGE_OWNED) != 0 ) \
         | 
| 32 | 
            +
                )) { \
         | 
| 33 | 
            +
                    rb_raise(rb_eZmqError, "Cannot access frame that belongs to another message or is gone."); \
         | 
| 34 | 
            +
                }
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            #define ZmqAssertFrameOwnedNoMessage(wrapper) if (!(\
         | 
| 37 | 
            +
                  (wrapper->flags & ZMQ_FRAME_OWNED) != 0 \
         | 
| 38 | 
            +
                )) { \
         | 
| 39 | 
            +
                    rb_raise(rb_eZmqError, "Cannot access frame that belongs to another message or is gone."); \
         | 
| 40 | 
            +
                }
         | 
| 11 41 |  | 
| 12 | 
            -
            #define  | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 42 | 
            +
            #define ZmqReturnNilUnlessFrameOwned(wrapper) if (!(\
         | 
| 43 | 
            +
                  (wrapper->flags & ZMQ_FRAME_OWNED) != 0 || \
         | 
| 44 | 
            +
                  (wrapper->message != NULL && (wrapper->message->flags & ZMQ_MESSAGE_OWNED) != 0 ) \
         | 
| 45 | 
            +
                )) { \
         | 
| 46 | 
            +
                    return Qnil; \
         | 
| 47 | 
            +
                }
         | 
| 15 48 |  | 
| 16 | 
            -
            void rb_czmq_free_frame( | 
| 49 | 
            +
            void rb_czmq_free_frame(zmq_frame_wrapper *frame);
         | 
| 17 50 | 
             
            void rb_czmq_free_frame_gc(void *ptr);
         | 
| 18 | 
            -
            void rb_czmq_frame_freed(zframe_t *frame);
         | 
| 19 51 |  | 
| 20 52 | 
             
            VALUE rb_czmq_alloc_frame(zframe_t *frame);
         | 
| 21 53 |  | 
    
        data/ext/rbczmq/message.c
    CHANGED
    
    | @@ -8,9 +8,12 @@ | |
| 8 8 | 
             
            void rb_czmq_free_message(zmq_message_wrapper *message)
         | 
| 9 9 | 
             
            {
         | 
| 10 10 | 
             
                errno = 0;
         | 
| 11 | 
            -
                 | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 11 | 
            +
                if (message != NULL && message->message != NULL && message->flags & ZMQ_MESSAGE_OWNED) {
         | 
| 12 | 
            +
                    zmsg_destroy(&message->message);
         | 
| 13 | 
            +
                    message->message = NULL;
         | 
| 14 | 
            +
                    message->flags &= ~ZMQ_MESSAGE_OWNED;
         | 
| 15 | 
            +
                    zlist_destroy(&message->frames);
         | 
| 16 | 
            +
                }
         | 
| 14 17 | 
             
            }
         | 
| 15 18 |  | 
| 16 19 | 
             
            /*
         | 
| @@ -22,11 +25,24 @@ static void rb_czmq_free_message_gc(void *ptr) | |
| 22 25 | 
             
            {
         | 
| 23 26 | 
             
                zmq_message_wrapper *msg = (zmq_message_wrapper *)ptr;
         | 
| 24 27 | 
             
                if (msg) {
         | 
| 25 | 
            -
                     | 
| 28 | 
            +
                    rb_czmq_free_message(msg);
         | 
| 26 29 | 
             
                    xfree(msg);
         | 
| 27 30 | 
             
                }
         | 
| 28 31 | 
             
            }
         | 
| 29 32 |  | 
| 33 | 
            +
            /*
         | 
| 34 | 
            +
             * :nodoc:
         | 
| 35 | 
            +
             * mark the owned ZMQ::Frame objects so that they are not collected.
         | 
| 36 | 
            +
            */
         | 
| 37 | 
            +
            void rb_czmq_mark_message(zmq_message_wrapper *message)
         | 
| 38 | 
            +
            {
         | 
| 39 | 
            +
                VALUE frame = (VALUE)zlist_first(message->frames);
         | 
| 40 | 
            +
                while (frame) {
         | 
| 41 | 
            +
                    rb_gc_mark(frame);
         | 
| 42 | 
            +
                    frame = (VALUE)zlist_next(message->frames);
         | 
| 43 | 
            +
                }
         | 
| 44 | 
            +
            }
         | 
| 45 | 
            +
             | 
| 30 46 | 
             
            /*
         | 
| 31 47 | 
             
             * :nodoc:
         | 
| 32 48 | 
             
             *  Coerce a zmsg instance to a native Ruby object.
         | 
| @@ -40,7 +56,22 @@ VALUE rb_czmq_alloc_message(zmsg_t *message) | |
| 40 56 | 
             
                message_obj = Data_Make_Struct(rb_cZmqMessage, zmq_message_wrapper, 0, rb_czmq_free_message_gc, m);
         | 
| 41 57 | 
             
                m->message = message;
         | 
| 42 58 | 
             
                ZmqAssertObjOnAlloc(m->message, m);
         | 
| 43 | 
            -
                m->flags =  | 
| 59 | 
            +
                m->flags = ZMQ_MESSAGE_OWNED;
         | 
| 60 | 
            +
                m->frames = zlist_new();
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                /* create ZMQ::Frame objects for all frames in the message and
         | 
| 63 | 
            +
                   link the ruby objects to this message. */
         | 
| 64 | 
            +
                zframe_t* zframe = zmsg_first(message);
         | 
| 65 | 
            +
                while (zframe) {
         | 
| 66 | 
            +
                    VALUE frame_object = rb_czmq_alloc_frame(zframe);
         | 
| 67 | 
            +
                    ZmqGetFrame(frame_object);
         | 
| 68 | 
            +
                    frame->flags &= ~ZMQ_FRAME_OWNED;
         | 
| 69 | 
            +
                    frame->message = m;
         | 
| 70 | 
            +
                    zlist_append(m->frames, (void*)frame_object);
         | 
| 71 | 
            +
                    
         | 
| 72 | 
            +
                    zframe = zmsg_next(message);
         | 
| 73 | 
            +
                }
         | 
| 74 | 
            +
             | 
| 44 75 | 
             
                rb_obj_call_init(message_obj, 0, NULL);
         | 
| 45 76 | 
             
                return message_obj;
         | 
| 46 77 | 
             
            }
         | 
| @@ -58,14 +89,11 @@ VALUE rb_czmq_alloc_message(zmsg_t *message) | |
| 58 89 |  | 
| 59 90 | 
             
            static VALUE rb_czmq_message_new(VALUE message)
         | 
| 60 91 | 
             
            {
         | 
| 61 | 
            -
                 | 
| 62 | 
            -
                 | 
| 63 | 
            -
             | 
| 64 | 
            -
                 | 
| 65 | 
            -
                 | 
| 66 | 
            -
                msg->flags = 0;
         | 
| 67 | 
            -
                rb_obj_call_init(message, 0, NULL);
         | 
| 68 | 
            -
                return message;
         | 
| 92 | 
            +
                zmsg_t* msg = zmsg_new();
         | 
| 93 | 
            +
                if (msg == NULL) {
         | 
| 94 | 
            +
                    rb_raise(rb_eZmqError, "Failed to allocate message object (zmsg_new).");
         | 
| 95 | 
            +
                }
         | 
| 96 | 
            +
                return rb_czmq_alloc_message(msg);
         | 
| 69 97 | 
             
            }
         | 
| 70 98 |  | 
| 71 99 | 
             
            /*
         | 
| @@ -85,6 +113,7 @@ static VALUE rb_czmq_message_new(VALUE message) | |
| 85 113 | 
             
            static VALUE rb_czmq_message_size(VALUE obj)
         | 
| 86 114 | 
             
            {
         | 
| 87 115 | 
             
                ZmqGetMessage(obj);
         | 
| 116 | 
            +
                ZmqReturnNilUnlessOwned(message);
         | 
| 88 117 | 
             
                return INT2NUM(zmsg_size(message->message));
         | 
| 89 118 | 
             
            }
         | 
| 90 119 |  | 
| @@ -105,6 +134,7 @@ static VALUE rb_czmq_message_size(VALUE obj) | |
| 105 134 | 
             
            static VALUE rb_czmq_message_content_size(VALUE obj)
         | 
| 106 135 | 
             
            {
         | 
| 107 136 | 
             
                ZmqGetMessage(obj);
         | 
| 137 | 
            +
                ZmqReturnNilUnlessOwned(message);
         | 
| 108 138 | 
             
                return INT2NUM(zmsg_content_size(message->message));
         | 
| 109 139 | 
             
            }
         | 
| 110 140 |  | 
| @@ -127,10 +157,15 @@ static VALUE rb_czmq_message_push(VALUE obj, VALUE frame_obj) | |
| 127 157 | 
             
                int rc = 0;
         | 
| 128 158 | 
             
                errno = 0;
         | 
| 129 159 | 
             
                ZmqGetMessage(obj);
         | 
| 160 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 130 161 | 
             
                ZmqGetFrame(frame_obj);
         | 
| 131 | 
            -
                 | 
| 162 | 
            +
                ZmqAssertFrameOwnedNoMessage(frame);
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                rc = zmsg_push(message->message, frame->frame);
         | 
| 132 165 | 
             
                ZmqAssert(rc);
         | 
| 133 | 
            -
                 | 
| 166 | 
            +
                frame->message = message;
         | 
| 167 | 
            +
                frame->flags &= ~ZMQ_FRAME_OWNED;
         | 
| 168 | 
            +
                zlist_push(message->frames, (void*)frame_obj);
         | 
| 134 169 | 
             
                return Qtrue;
         | 
| 135 170 | 
             
            }
         | 
| 136 171 |  | 
| @@ -153,10 +188,15 @@ static VALUE rb_czmq_message_add(VALUE obj, VALUE frame_obj) | |
| 153 188 | 
             
                int rc = 0;
         | 
| 154 189 | 
             
                errno = 0;
         | 
| 155 190 | 
             
                ZmqGetMessage(obj);
         | 
| 191 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 156 192 | 
             
                ZmqGetFrame(frame_obj);
         | 
| 157 | 
            -
                 | 
| 193 | 
            +
                ZmqAssertFrameOwnedNoMessage(frame);
         | 
| 194 | 
            +
             | 
| 195 | 
            +
                rc = zmsg_add(message->message, frame->frame);
         | 
| 158 196 | 
             
                ZmqAssert(rc);
         | 
| 159 | 
            -
                 | 
| 197 | 
            +
                frame->message = message;
         | 
| 198 | 
            +
                frame->flags &= ~ZMQ_FRAME_OWNED;
         | 
| 199 | 
            +
                zlist_append(message->frames, (void*)frame_obj);
         | 
| 160 200 | 
             
                return Qtrue;
         | 
| 161 201 | 
             
            }
         | 
| 162 202 |  | 
| @@ -179,9 +219,11 @@ static VALUE rb_czmq_message_pop(VALUE obj) | |
| 179 219 | 
             
            {
         | 
| 180 220 | 
             
                zframe_t *frame = NULL;
         | 
| 181 221 | 
             
                ZmqGetMessage(obj);
         | 
| 182 | 
            -
                 | 
| 222 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 223 | 
            +
                frame = zmsg_pop(message->message); /* we now own the frame */
         | 
| 183 224 | 
             
                if (frame == NULL) return Qnil;
         | 
| 184 | 
            -
                 | 
| 225 | 
            +
                VALUE frame_obj = (VALUE)zlist_pop(message->frames);
         | 
| 226 | 
            +
                return frame_obj ? frame_obj : Qnil;
         | 
| 185 227 | 
             
            }
         | 
| 186 228 |  | 
| 187 229 | 
             
            /*
         | 
| @@ -200,6 +242,7 @@ static VALUE rb_czmq_message_pop(VALUE obj) | |
| 200 242 | 
             
            static VALUE rb_czmq_message_print(VALUE obj)
         | 
| 201 243 | 
             
            {
         | 
| 202 244 | 
             
                ZmqGetMessage(obj);
         | 
| 245 | 
            +
                ZmqReturnNilUnlessOwned(message);
         | 
| 203 246 | 
             
                zmsg_dump(message->message);
         | 
| 204 247 | 
             
                return Qnil;
         | 
| 205 248 | 
             
            }
         | 
| @@ -220,11 +263,10 @@ static VALUE rb_czmq_message_print(VALUE obj) | |
| 220 263 |  | 
| 221 264 | 
             
            static VALUE rb_czmq_message_first(VALUE obj)
         | 
| 222 265 | 
             
            {
         | 
| 223 | 
            -
                zframe_t *frame = NULL;
         | 
| 224 266 | 
             
                ZmqGetMessage(obj);
         | 
| 225 | 
            -
                 | 
| 226 | 
            -
                 | 
| 227 | 
            -
                return  | 
| 267 | 
            +
                ZmqReturnNilUnlessOwned(message);
         | 
| 268 | 
            +
                VALUE frame_obj = (VALUE)zlist_first(message->frames);
         | 
| 269 | 
            +
                return frame_obj ? frame_obj : Qnil;
         | 
| 228 270 | 
             
            }
         | 
| 229 271 |  | 
| 230 272 | 
             
            /*
         | 
| @@ -244,11 +286,10 @@ static VALUE rb_czmq_message_first(VALUE obj) | |
| 244 286 |  | 
| 245 287 | 
             
            static VALUE rb_czmq_message_next(VALUE obj)
         | 
| 246 288 | 
             
            {
         | 
| 247 | 
            -
                zframe_t *frame = NULL;
         | 
| 248 289 | 
             
                ZmqGetMessage(obj);
         | 
| 249 | 
            -
                 | 
| 250 | 
            -
                 | 
| 251 | 
            -
                return  | 
| 290 | 
            +
                ZmqReturnNilUnlessOwned(message);
         | 
| 291 | 
            +
                VALUE frame_obj = (VALUE)zlist_next(message->frames);
         | 
| 292 | 
            +
                return frame_obj ? frame_obj : Qnil;
         | 
| 252 293 | 
             
            }
         | 
| 253 294 |  | 
| 254 295 | 
             
            /*
         | 
| @@ -267,11 +308,10 @@ static VALUE rb_czmq_message_next(VALUE obj) | |
| 267 308 |  | 
| 268 309 | 
             
            static VALUE rb_czmq_message_last(VALUE obj)
         | 
| 269 310 | 
             
            {
         | 
| 270 | 
            -
                zframe_t *frame = NULL;
         | 
| 271 311 | 
             
                ZmqGetMessage(obj);
         | 
| 272 | 
            -
                 | 
| 273 | 
            -
                 | 
| 274 | 
            -
                return  | 
| 312 | 
            +
                ZmqReturnNilUnlessOwned(message);
         | 
| 313 | 
            +
                VALUE frame_obj = (VALUE)zlist_last(message->frames);
         | 
| 314 | 
            +
                return frame_obj ? frame_obj : Qnil;
         | 
| 275 315 | 
             
            }
         | 
| 276 316 |  | 
| 277 317 | 
             
            /*
         | 
| @@ -293,10 +333,18 @@ static VALUE rb_czmq_message_last(VALUE obj) | |
| 293 333 | 
             
            static VALUE rb_czmq_message_remove(VALUE obj, VALUE frame_obj)
         | 
| 294 334 | 
             
            {
         | 
| 295 335 | 
             
                ZmqGetMessage(obj);
         | 
| 296 | 
            -
                 | 
| 297 | 
            -
                 | 
| 298 | 
            -
             | 
| 299 | 
            -
                 | 
| 336 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 337 | 
            +
                ZmqGetFrame(frame_obj);
         | 
| 338 | 
            +
             | 
| 339 | 
            +
                /* remove from message and our list of frame objects */
         | 
| 340 | 
            +
                zmsg_remove(message->message, frame->frame);
         | 
| 341 | 
            +
                zlist_remove(message->frames, (void*)frame_obj);
         | 
| 342 | 
            +
             | 
| 343 | 
            +
                /* removing from message does not destroy the frame,
         | 
| 344 | 
            +
                   therefore, we take ownership of the frame at this point */
         | 
| 345 | 
            +
                frame->message = NULL;
         | 
| 346 | 
            +
                frame->flags |= ZMQ_FRAME_OWNED;
         | 
| 347 | 
            +
             | 
| 300 348 | 
             
                return Qnil;
         | 
| 301 349 | 
             
            }
         | 
| 302 350 |  | 
| @@ -317,9 +365,19 @@ static VALUE rb_czmq_message_pushstr(VALUE obj, VALUE str) | |
| 317 365 | 
             
                int rc = 0;
         | 
| 318 366 | 
             
                errno = 0;
         | 
| 319 367 | 
             
                ZmqGetMessage(obj);
         | 
| 368 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 320 369 | 
             
                Check_Type(str, T_STRING);
         | 
| 321 370 | 
             
                rc = zmsg_pushmem(message->message, StringValueCStr(str), RSTRING_LEN(str));
         | 
| 322 371 | 
             
                ZmqAssert(rc);
         | 
| 372 | 
            +
             | 
| 373 | 
            +
                /* keep zlist of frame ruby objects in sync with message's frame list */
         | 
| 374 | 
            +
                zframe_t* zframe = zmsg_first(message->message);
         | 
| 375 | 
            +
                VALUE frame_object = rb_czmq_alloc_frame(zframe);
         | 
| 376 | 
            +
                ZmqGetFrame(frame_object);
         | 
| 377 | 
            +
                frame->flags &= ~ZMQ_FRAME_OWNED;
         | 
| 378 | 
            +
                frame->message = message;
         | 
| 379 | 
            +
                zlist_push(message->frames, (void*)frame_object);
         | 
| 380 | 
            +
             | 
| 323 381 | 
             
                return Qtrue;
         | 
| 324 382 | 
             
            }
         | 
| 325 383 |  | 
| @@ -340,9 +398,19 @@ static VALUE rb_czmq_message_addstr(VALUE obj, VALUE str) | |
| 340 398 | 
             
                int rc = 0;
         | 
| 341 399 | 
             
                errno = 0;
         | 
| 342 400 | 
             
                ZmqGetMessage(obj);
         | 
| 401 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 343 402 | 
             
                Check_Type(str, T_STRING);
         | 
| 344 403 | 
             
                rc = zmsg_addmem(message->message, StringValueCStr(str), RSTRING_LEN(str));
         | 
| 345 404 | 
             
                ZmqAssert(rc);
         | 
| 405 | 
            +
             | 
| 406 | 
            +
                /* keep zlist of frame ruby objects in sync with message's frame list */
         | 
| 407 | 
            +
                zframe_t* zframe = zmsg_last(message->message);
         | 
| 408 | 
            +
                VALUE frame_object = rb_czmq_alloc_frame(zframe);
         | 
| 409 | 
            +
                ZmqGetFrame(frame_object);
         | 
| 410 | 
            +
                frame->flags &= ~ZMQ_FRAME_OWNED;
         | 
| 411 | 
            +
                frame->message = message;
         | 
| 412 | 
            +
                zlist_append(message->frames, (void*)frame_object);
         | 
| 413 | 
            +
             | 
| 346 414 | 
             
                return Qtrue;
         | 
| 347 415 | 
             
            }
         | 
| 348 416 |  | 
| @@ -363,8 +431,13 @@ static VALUE rb_czmq_message_popstr(VALUE obj) | |
| 363 431 | 
             
            {
         | 
| 364 432 | 
             
                char *str = NULL;
         | 
| 365 433 | 
             
                ZmqGetMessage(obj);
         | 
| 434 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 366 435 | 
             
                str = zmsg_popstr(message->message);
         | 
| 367 436 | 
             
                if (str == NULL) return Qnil;
         | 
| 437 | 
            +
             | 
| 438 | 
            +
                /* destroys the frame, keep frame objects list in sync: */
         | 
| 439 | 
            +
                zlist_pop(message->frames);
         | 
| 440 | 
            +
             | 
| 368 441 | 
             
                return rb_str_new2(str);
         | 
| 369 442 | 
             
            }
         | 
| 370 443 |  | 
| @@ -386,9 +459,30 @@ static VALUE rb_czmq_message_wrap(VALUE obj, VALUE frame_obj) | |
| 386 459 | 
             
            {
         | 
| 387 460 | 
             
                errno = 0;
         | 
| 388 461 | 
             
                ZmqGetMessage(obj);
         | 
| 389 | 
            -
                 | 
| 390 | 
            -
             | 
| 391 | 
            -
                 | 
| 462 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 463 | 
            +
             | 
| 464 | 
            +
                {
         | 
| 465 | 
            +
                    ZmqGetFrame(frame_obj);
         | 
| 466 | 
            +
                    ZmqAssertFrameOwned(frame);
         | 
| 467 | 
            +
                    zmsg_wrap(message->message, frame->frame);
         | 
| 468 | 
            +
                    frame->flags &= ~ZMQ_FRAME_OWNED;
         | 
| 469 | 
            +
                    frame->message = message;
         | 
| 470 | 
            +
                }
         | 
| 471 | 
            +
             | 
| 472 | 
            +
                /* keep frame objects list in sync. Two frames have been added. frame_obj from above
         | 
| 473 | 
            +
                   and a new one for the empty frame. */
         | 
| 474 | 
            +
                {
         | 
| 475 | 
            +
                    zmsg_first(message->message);
         | 
| 476 | 
            +
                    zframe_t* empty_frame = zmsg_next(message->message);
         | 
| 477 | 
            +
             | 
| 478 | 
            +
                    VALUE empty_frame_object = rb_czmq_alloc_frame(empty_frame);
         | 
| 479 | 
            +
                    ZmqGetFrame(empty_frame_object);
         | 
| 480 | 
            +
                    frame->flags &= ~ZMQ_FRAME_OWNED;
         | 
| 481 | 
            +
                    frame->message = message;
         | 
| 482 | 
            +
             | 
| 483 | 
            +
                    zlist_push(message->frames, (void*)empty_frame_object);
         | 
| 484 | 
            +
                    zlist_push(message->frames, (void*)frame_obj);
         | 
| 485 | 
            +
                }
         | 
| 392 486 | 
             
                return Qnil;
         | 
| 393 487 | 
             
            }
         | 
| 394 488 |  | 
| @@ -410,11 +504,29 @@ static VALUE rb_czmq_message_wrap(VALUE obj, VALUE frame_obj) | |
| 410 504 |  | 
| 411 505 | 
             
            static VALUE rb_czmq_message_unwrap(VALUE obj)
         | 
| 412 506 | 
             
            {
         | 
| 413 | 
            -
                zframe_t *frame = NULL;
         | 
| 414 507 | 
             
                ZmqGetMessage(obj);
         | 
| 415 | 
            -
                 | 
| 416 | 
            -
             | 
| 417 | 
            -
                 | 
| 508 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 509 | 
            +
             | 
| 510 | 
            +
                /* reimplemented the zmsg_unwrap function for simpler logic: */
         | 
| 511 | 
            +
                zframe_t *zframe = zmsg_pop(message->message);
         | 
| 512 | 
            +
                VALUE frame_obj = 0;
         | 
| 513 | 
            +
                if (zframe != NULL) {
         | 
| 514 | 
            +
                    frame_obj = (VALUE)zlist_pop(message->frames);
         | 
| 515 | 
            +
                }
         | 
| 516 | 
            +
             | 
| 517 | 
            +
                zframe_t *empty = zmsg_first(message->message);
         | 
| 518 | 
            +
                if (zframe_size(empty) == 0) {
         | 
| 519 | 
            +
                    empty = zmsg_pop(message->message);
         | 
| 520 | 
            +
                    zframe_destroy (&empty);
         | 
| 521 | 
            +
                    zlist_pop(message->frames);
         | 
| 522 | 
            +
                }
         | 
| 523 | 
            +
                
         | 
| 524 | 
            +
                {
         | 
| 525 | 
            +
                    ZmqGetFrame(frame_obj);
         | 
| 526 | 
            +
                    frame->message = NULL;
         | 
| 527 | 
            +
                    frame->flags |= ZMQ_FRAME_OWNED;
         | 
| 528 | 
            +
                }
         | 
| 529 | 
            +
                return frame_obj ? frame_obj : Qnil;
         | 
| 418 530 | 
             
            }
         | 
| 419 531 |  | 
| 420 532 | 
             
            /*
         | 
| @@ -431,16 +543,11 @@ static VALUE rb_czmq_message_unwrap(VALUE obj) | |
| 431 543 |  | 
| 432 544 | 
             
            static VALUE rb_czmq_message_dup(VALUE obj)
         | 
| 433 545 | 
             
            {
         | 
| 434 | 
            -
                VALUE dup;
         | 
| 435 | 
            -
                zmq_message_wrapper *dup_msg = NULL;
         | 
| 436 | 
            -
                errno = 0;
         | 
| 437 546 | 
             
                ZmqGetMessage(obj);
         | 
| 438 | 
            -
                 | 
| 439 | 
            -
             | 
| 440 | 
            -
                 | 
| 441 | 
            -
                dup_msg | 
| 442 | 
            -
                rb_obj_call_init(dup, 0, NULL);
         | 
| 443 | 
            -
                return dup;
         | 
| 547 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 548 | 
            +
             | 
| 549 | 
            +
                zmsg_t* dup_msg = zmsg_dup(message->message);
         | 
| 550 | 
            +
                return rb_czmq_alloc_message(dup_msg);
         | 
| 444 551 | 
             
            }
         | 
| 445 552 |  | 
| 446 553 | 
             
            /*
         | 
| @@ -460,6 +567,7 @@ static VALUE rb_czmq_message_dup(VALUE obj) | |
| 460 567 | 
             
            static VALUE rb_czmq_message_destroy(VALUE obj)
         | 
| 461 568 | 
             
            {
         | 
| 462 569 | 
             
                ZmqGetMessage(obj);
         | 
| 570 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 463 571 | 
             
                rb_czmq_free_message(message);
         | 
| 464 572 | 
             
                return Qnil;
         | 
| 465 573 | 
             
            }
         | 
| @@ -483,6 +591,7 @@ static VALUE rb_czmq_message_encode(VALUE obj) | |
| 483 591 | 
             
                byte *buff;
         | 
| 484 592 | 
             
                size_t buff_size;
         | 
| 485 593 | 
             
                ZmqGetMessage(obj);
         | 
| 594 | 
            +
                ZmqReturnNilUnlessOwned(message);
         | 
| 486 595 | 
             
                buff_size = zmsg_encode(message->message, &buff);
         | 
| 487 596 | 
             
                return rb_str_new((char *)buff, buff_size);
         | 
| 488 597 | 
             
            }
         | 
| @@ -531,8 +640,10 @@ static VALUE rb_czmq_message_eql_p(VALUE obj, VALUE other_message) | |
| 531 640 | 
             
                size_t other_buff_size;
         | 
| 532 641 | 
             
                ZmqGetMessage(obj);
         | 
| 533 642 | 
             
                ZmqAssertMessage(other_message);
         | 
| 643 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 534 644 | 
             
                Data_Get_Struct(other_message, zmq_message_wrapper, other);
         | 
| 535 645 | 
             
                if (!other) rb_raise(rb_eTypeError, "uninitialized ZMQ message!");
         | 
| 646 | 
            +
                ZmqAssertMessageOwned(other);
         | 
| 536 647 |  | 
| 537 648 | 
             
                if (zmsg_size(message->message) != zmsg_size(other->message)) return Qfalse;
         | 
| 538 649 | 
             
                if (zmsg_content_size(message->message) != zmsg_content_size(other->message)) return Qfalse;
         | 
| @@ -580,15 +691,33 @@ static VALUE rb_czmq_message_to_a(VALUE obj) | |
| 580 691 | 
             
            {
         | 
| 581 692 | 
             
                VALUE ary;
         | 
| 582 693 | 
             
                ZmqGetMessage(obj);
         | 
| 583 | 
            -
                 | 
| 584 | 
            -
                 | 
| 585 | 
            -
                 | 
| 586 | 
            -
             | 
| 587 | 
            -
                     | 
| 694 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 695 | 
            +
                ary = rb_ary_new2(zlist_size(message->frames));
         | 
| 696 | 
            +
                VALUE frame_obj = (VALUE)zlist_first(message->frames);
         | 
| 697 | 
            +
                while (frame_obj) {
         | 
| 698 | 
            +
                    rb_ary_push(ary, frame_obj);
         | 
| 699 | 
            +
                    frame_obj = (VALUE)zlist_next(message->frames);
         | 
| 588 700 | 
             
                }
         | 
| 589 701 | 
             
                return ary;
         | 
| 590 702 | 
             
            }
         | 
| 591 703 |  | 
| 704 | 
            +
            /*
         | 
| 705 | 
            +
             * call-seq:
         | 
| 706 | 
            +
             *    msg.gone?   #=> false
         | 
| 707 | 
            +
             *    msg.destroy # or send
         | 
| 708 | 
            +
             *    msg.gone?   #=> true
         | 
| 709 | 
            +
             *
         | 
| 710 | 
            +
             * Return boolean indicating if the ZMQ::Message is gone (sent or destroyed). If the message is
         | 
| 711 | 
            +
             * gone, accessor methods will return nil and methods requiring data or methods that mutate
         | 
| 712 | 
            +
             * the message will raise an exception.
         | 
| 713 | 
            +
            */
         | 
| 714 | 
            +
             | 
| 715 | 
            +
            static VALUE rb_czmq_message_gone(VALUE obj)
         | 
| 716 | 
            +
            {
         | 
| 717 | 
            +
                ZmqGetMessage(obj);
         | 
| 718 | 
            +
                return (message->flags & ZMQ_MESSAGE_OWNED) ? Qfalse : Qtrue;
         | 
| 719 | 
            +
            }
         | 
| 720 | 
            +
             | 
| 592 721 | 
             
            void _init_rb_czmq_message()
         | 
| 593 722 | 
             
            {
         | 
| 594 723 | 
             
                rb_cZmqMessage = rb_define_class_under(rb_mZmq, "Message", rb_cObject);
         | 
| @@ -617,4 +746,5 @@ void _init_rb_czmq_message() | |
| 617 746 | 
             
                rb_define_method(rb_cZmqMessage, "eql?", rb_czmq_message_equals, 1);
         | 
| 618 747 | 
             
                rb_define_method(rb_cZmqMessage, "==", rb_czmq_message_equals, 1);
         | 
| 619 748 | 
             
                rb_define_method(rb_cZmqMessage, "to_a", rb_czmq_message_to_a, 0);
         | 
| 749 | 
            +
                rb_define_method(rb_cZmqMessage, "gone?", rb_czmq_message_gone, 0);
         | 
| 620 750 | 
             
            }
         | 
    
        data/ext/rbczmq/message.h
    CHANGED
    
    | @@ -1,11 +1,15 @@ | |
| 1 1 | 
             
            #ifndef RBCZMQ_MESSAGE_H
         | 
| 2 2 | 
             
            #define RBCZMQ_MESSAGE_H
         | 
| 3 3 |  | 
| 4 | 
            -
             | 
| 4 | 
            +
            /* This flag indicates that the wrapped zmsg_t is owned by ruby
         | 
| 5 | 
            +
               and can be freed when the ZMQ::Message object is garbage collected */
         | 
| 6 | 
            +
            #define ZMQ_MESSAGE_OWNED 0x01
         | 
| 5 7 |  | 
| 6 8 | 
             
            typedef struct {
         | 
| 7 9 | 
             
                zmsg_t  *message;
         | 
| 8 10 | 
             
                int flags;
         | 
| 11 | 
            +
                /* a zlist of frame wrapper objects for the frames in this message */
         | 
| 12 | 
            +
                zlist_t *frames;
         | 
| 9 13 | 
             
            } zmq_message_wrapper;
         | 
| 10 14 |  | 
| 11 15 | 
             
            #define ZmqAssertMessage(obj) ZmqAssertType(obj, rb_cZmqMessage, "ZMQ::Message")
         | 
| @@ -13,11 +17,23 @@ typedef struct { | |
| 13 17 | 
             
                zmq_message_wrapper *message = NULL; \
         | 
| 14 18 | 
             
                ZmqAssertMessage(obj); \
         | 
| 15 19 | 
             
                Data_Get_Struct(obj, zmq_message_wrapper, message); \
         | 
| 16 | 
            -
                if (!message) rb_raise(rb_eTypeError, "uninitialized ZMQ message!"); | 
| 20 | 
            +
                if (!message) rb_raise(rb_eTypeError, "uninitialized ZMQ message!");
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                /*
         | 
| 17 23 | 
             
                if (message->flags & ZMQ_MESSAGE_DESTROYED) rb_raise(rb_eZmqError, "ZMQ::Message instance %p has been destroyed by the ZMQ framework", (void *)obj);
         | 
| 24 | 
            +
                */
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            #define ZmqReturnNilUnlessOwned(wrapper) if (wrapper && (wrapper->flags & ZMQ_MESSAGE_OWNED) == 0) { \
         | 
| 27 | 
            +
                return Qnil; \
         | 
| 28 | 
            +
            }
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            #define ZmqAssertMessageOwned(wrapper) if (wrapper && (wrapper->flags & ZMQ_MESSAGE_OWNED) == 0) { \
         | 
| 31 | 
            +
                rb_raise(rb_eTypeError, "Cannot modify a message that is gone."); \
         | 
| 32 | 
            +
            }
         | 
| 18 33 |  | 
| 19 34 | 
             
            VALUE rb_czmq_alloc_message(zmsg_t *message);
         | 
| 20 35 | 
             
            void rb_czmq_free_message(zmq_message_wrapper *message);
         | 
| 36 | 
            +
            void rb_czmq_mark_message(zmq_message_wrapper *message);
         | 
| 21 37 |  | 
| 22 38 | 
             
            void _init_rb_czmq_message();
         | 
| 23 39 |  | 
    
        data/ext/rbczmq/pollitem.c
    CHANGED
    
    | @@ -250,4 +250,4 @@ void _init_rb_czmq_pollitem() | |
| 250 250 | 
             
                rb_define_method(rb_cZmqPollitem, "handler", rb_czmq_pollitem_handler, 0);
         | 
| 251 251 | 
             
                rb_define_method(rb_cZmqPollitem, "handler=", rb_czmq_pollitem_handler_equals, 1);
         | 
| 252 252 | 
             
                rb_define_method(rb_cZmqPollitem, "verbose=", rb_czmq_pollitem_set_verbose, 1);
         | 
| 253 | 
            -
            }
         | 
| 253 | 
            +
            }
         | 
    
        data/ext/rbczmq/rbczmq_ext.c
    CHANGED
    
    | @@ -25,8 +25,6 @@ VALUE rb_cZmqPoller; | |
| 25 25 | 
             
            VALUE rb_cZmqPollitem;
         | 
| 26 26 | 
             
            VALUE rb_cZmqBeacon;
         | 
| 27 27 |  | 
| 28 | 
            -
            st_table *frames_map = NULL;
         | 
| 29 | 
            -
             | 
| 30 28 | 
             
            VALUE intern_call;
         | 
| 31 29 | 
             
            VALUE intern_readable;
         | 
| 32 30 | 
             
            VALUE intern_writable;
         | 
| @@ -216,8 +214,6 @@ static VALUE rb_czmq_m_proxy(int argc, VALUE *argv, ZMQ_UNUSED VALUE klass) | |
| 216 214 |  | 
| 217 215 | 
             
            void Init_rbczmq_ext()
         | 
| 218 216 | 
             
            {
         | 
| 219 | 
            -
                frames_map = st_init_numtable();
         | 
| 220 | 
            -
             | 
| 221 217 | 
             
                intern_call = rb_intern("call");
         | 
| 222 218 | 
             
                intern_readable = rb_intern("on_readable");
         | 
| 223 219 | 
             
                intern_writable = rb_intern("on_writable");
         | 
    
        data/ext/rbczmq/rbczmq_ext.h
    CHANGED
    
    
    
        data/ext/rbczmq/socket.c
    CHANGED
    
    | @@ -229,7 +229,7 @@ static VALUE rb_czmq_socket_bind(VALUE obj, VALUE endpoint) | |
| 229 229 | 
             
                args.endpoint = StringValueCStr(endpoint);
         | 
| 230 230 | 
             
                rc = (int)rb_thread_blocking_region(rb_czmq_nogvl_socket_bind, (void *)&args, RUBY_UBF_IO, 0);
         | 
| 231 231 | 
             
                /* ZmqAssert will return false on any non-zero return code. Bind returns the port number */
         | 
| 232 | 
            -
                if (rc < 0) { | 
| 232 | 
            +
                if (rc < 0) {
         | 
| 233 233 | 
             
                    ZmqAssert(rc);
         | 
| 234 234 | 
             
                }
         | 
| 235 235 | 
             
                if (sock->verbose)
         | 
| @@ -562,6 +562,7 @@ static VALUE rb_czmq_socket_send_frame(int argc, VALUE *argv, VALUE obj) | |
| 562 562 | 
             
                ZmqSockGuardCrossThread(sock);
         | 
| 563 563 | 
             
                rb_scan_args(argc, argv, "11", &frame_obj, &flags);
         | 
| 564 564 | 
             
                ZmqGetFrame(frame_obj);
         | 
| 565 | 
            +
                ZmqAssertFrameOwnedNoMessage(frame);
         | 
| 565 566 |  | 
| 566 567 | 
             
                if (NIL_P(flags)) {
         | 
| 567 568 | 
             
                    flgs = 0;
         | 
| @@ -573,13 +574,17 @@ static VALUE rb_czmq_socket_send_frame(int argc, VALUE *argv, VALUE obj) | |
| 573 574 |  | 
| 574 575 | 
             
                if (sock->verbose) {
         | 
| 575 576 | 
             
                    cur_time = rb_czmq_formatted_current_time();
         | 
| 576 | 
            -
                    print_frame = (flgs & ZFRAME_REUSE) ? frame : zframe_dup(frame);
         | 
| 577 | 
            +
                    print_frame = (flgs & ZFRAME_REUSE) ? frame->frame : zframe_dup(frame->frame);
         | 
| 577 578 | 
             
                }
         | 
| 578 579 | 
             
                args.socket = sock;
         | 
| 579 | 
            -
                args.frame = frame;
         | 
| 580 | 
            +
                args.frame = frame->frame;
         | 
| 580 581 | 
             
                args.flags = flgs;
         | 
| 581 582 | 
             
                rc = (int)rb_thread_blocking_region(rb_czmq_nogvl_send_frame, (void *)&args, RUBY_UBF_IO, 0);
         | 
| 582 583 | 
             
                ZmqAssert(rc);
         | 
| 584 | 
            +
                if ((flgs & ZFRAME_REUSE) == 0) {
         | 
| 585 | 
            +
                    /* frame has been destroyed, clear the owns flag */
         | 
| 586 | 
            +
                    frame->flags &= ~ZMQ_FRAME_OWNED;
         | 
| 587 | 
            +
                }
         | 
| 583 588 | 
             
                if (sock->verbose) ZmqDumpFrame("send_frame", print_frame);
         | 
| 584 589 | 
             
                return Qtrue;
         | 
| 585 590 | 
             
            }
         | 
| @@ -623,11 +628,12 @@ static VALUE rb_czmq_socket_send_message(VALUE obj, VALUE message_obj) | |
| 623 628 | 
             
                ZmqAssertSocketNotPending(sock, "can only send on a bound or connected socket!");
         | 
| 624 629 | 
             
                ZmqSockGuardCrossThread(sock);
         | 
| 625 630 | 
             
                ZmqGetMessage(message_obj);
         | 
| 631 | 
            +
                ZmqAssertMessageOwned(message);
         | 
| 626 632 | 
             
                if (sock->verbose) print_message = zmsg_dup(message->message);
         | 
| 627 633 | 
             
                args.socket = sock;
         | 
| 628 634 | 
             
                args.message = message->message;
         | 
| 629 635 | 
             
                rb_thread_blocking_region(rb_czmq_nogvl_send_message, (void *)&args, RUBY_UBF_IO, 0);
         | 
| 630 | 
            -
                message->flags  | 
| 636 | 
            +
                message->flags &= ~ZMQ_MESSAGE_OWNED;
         | 
| 631 637 | 
             
                if (sock->verbose) ZmqDumpMessage("send_message", print_message);
         | 
| 632 638 | 
             
                return Qnil;
         | 
| 633 639 | 
             
            }
         | 
| @@ -1652,7 +1658,7 @@ static VALUE rb_czmq_socket_monitor_thread(void *arg) | |
| 1652 1658 |  | 
| 1653 1659 | 
             
                args.monitored_socket_wrapper = sock;
         | 
| 1654 1660 | 
             
                args.socket = s;
         | 
| 1655 | 
            -
             | 
| 1661 | 
            +
             | 
| 1656 1662 | 
             
                while (1) {
         | 
| 1657 1663 | 
             
                    zmq_msg_init (&args.msg);
         | 
| 1658 1664 | 
             
                    rc = (int)rb_thread_blocking_region(rb_czmq_nogvl_monitor_recv, (void *)&args, RUBY_UBF_IO, 0);
         | 
    
        data/lib/zmq.rb
    CHANGED
    
    
    
        data/lib/zmq/logger.rb
    ADDED
    
    | @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'logger'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module ZMQ
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              # A logging class that sends its output to a ZMQ socket. This allows log messages to be sent
         | 
| 8 | 
            +
              # asynchronously to another process and across a network if required. The receiving socket
         | 
| 9 | 
            +
              # will receive messages, each with text of one log message.
         | 
| 10 | 
            +
              #
         | 
| 11 | 
            +
              # Example usage:
         | 
| 12 | 
            +
              #
         | 
| 13 | 
            +
              #   socket = context.socket(ZMQ::PUSH)
         | 
| 14 | 
            +
              #   socket.connect("tcp://logserver:5555")
         | 
| 15 | 
            +
              #   logger = ZMQ::Logger.new(socket)
         | 
| 16 | 
            +
              #   logger.debug("Hello logger")
         | 
| 17 | 
            +
              #
         | 
| 18 | 
            +
              class Logger < ::Logger
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                class InvalidSocketError < ZMQ::Error ; end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                # only these socket classes are allowed to be used for sending
         | 
| 23 | 
            +
                VALID_SOCKET_CLASSES = [
         | 
| 24 | 
            +
                  Socket::Pub,
         | 
| 25 | 
            +
                  Socket::Push,
         | 
| 26 | 
            +
                  Socket::Pair
         | 
| 27 | 
            +
                ]
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                # Initialise a new logger object. The logger sends log messages to a socket.
         | 
| 30 | 
            +
                # The caller is responsible for connecting the socket before using the logger to
         | 
| 31 | 
            +
                # send log output to the socket.
         | 
| 32 | 
            +
                #
         | 
| 33 | 
            +
                # Supported socket types are a Socket::Pub, Socket::Push, and Socket::Pair
         | 
| 34 | 
            +
                def initialize(socket)
         | 
| 35 | 
            +
                  raise InvalidSocketError unless VALID_SOCKET_CLASSES.any? { |klass| socket.is_a?(klass) }
         | 
| 36 | 
            +
                  super(nil)
         | 
| 37 | 
            +
                  @logdev = LogDevice.new(socket)
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                # implements an interface similar to ::Logger::LogDevice. This is the recipient of the
         | 
| 41 | 
            +
                # formatted log messages
         | 
| 42 | 
            +
                class LogDevice
         | 
| 43 | 
            +
                  # :nodoc:
         | 
| 44 | 
            +
                  def initialize(socket)
         | 
| 45 | 
            +
                    @socket = socket
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  # write the formatted log message to the socket.
         | 
| 49 | 
            +
                  def write(message)
         | 
| 50 | 
            +
                    @socket.send(message)
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  def close
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
            end
         | 
    
        data/lib/zmq/version.rb
    CHANGED
    
    
    
        data/test/test_frame.rb
    CHANGED
    
    
    
        data/test/test_logger.rb
    ADDED
    
    | @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require File.join(File.dirname(__FILE__), 'helper')
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class TestZmqLogger < ZmqTestCase
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def setup
         | 
| 8 | 
            +
                @ctx = ZMQ::Context.new
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def teardown
         | 
| 12 | 
            +
                @ctx.destroy
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              def test_invalid_socket
         | 
| 16 | 
            +
                socket = @ctx.socket(ZMQ::REQ)
         | 
| 17 | 
            +
                assert_raises ZMQ::Logger::InvalidSocketError do
         | 
| 18 | 
            +
                  ZMQ::Logger.new(socket)
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def test_valid_socket
         | 
| 23 | 
            +
                socket = @ctx.socket(ZMQ::PUSH)
         | 
| 24 | 
            +
                assert_nothing_raised do
         | 
| 25 | 
            +
                  ZMQ::Logger.new(socket)
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              def test_send_message
         | 
| 30 | 
            +
                reader = @ctx.socket(ZMQ::PULL)
         | 
| 31 | 
            +
                port = reader.bind("tcp://*:*")
         | 
| 32 | 
            +
                assert port > 0
         | 
| 33 | 
            +
                writer = @ctx.socket(ZMQ::PUSH)
         | 
| 34 | 
            +
                writer.connect("tcp://localhost:#{port}")
         | 
| 35 | 
            +
                logger = ZMQ::Logger.new(writer)
         | 
| 36 | 
            +
                assert logger.debug("hellö world")
         | 
| 37 | 
            +
                message = reader.recv.force_encoding Encoding::UTF_8
         | 
| 38 | 
            +
                assert_not_nil message =~ /hellö world/
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            end
         | 
    
        data/test/test_message.rb
    CHANGED
    
    | @@ -11,10 +11,11 @@ class TestZmqMessage < ZmqTestCase | |
| 11 11 |  | 
| 12 12 | 
             
              def test_destroyed
         | 
| 13 13 | 
             
                msg = ZMQ::Message("one", "two")
         | 
| 14 | 
            +
                assert_not_nil msg.encode
         | 
| 15 | 
            +
                assert !msg.gone?
         | 
| 14 16 | 
             
                msg.destroy
         | 
| 15 | 
            -
                 | 
| 16 | 
            -
             | 
| 17 | 
            -
                end
         | 
| 17 | 
            +
                assert msg.gone?
         | 
| 18 | 
            +
                assert_nil msg.encode
         | 
| 18 19 | 
             
              end
         | 
| 19 20 |  | 
| 20 21 | 
             
              def test_message_sugar
         | 
| @@ -182,7 +183,7 @@ class TestZmqMessage < ZmqTestCase | |
| 182 183 | 
             
              end
         | 
| 183 184 |  | 
| 184 185 | 
             
              def test_equals
         | 
| 185 | 
            -
                msg = | 
| 186 | 
            +
                msg = ZMQ::Message.new
         | 
| 186 187 | 
             
                msg.pushstr "body"
         | 
| 187 188 | 
             
                msg.pushstr "header"
         | 
| 188 189 |  | 
| @@ -198,4 +199,96 @@ class TestZmqMessage < ZmqTestCase | |
| 198 199 | 
             
                assert !msg.eql?(other)
         | 
| 199 200 | 
             
                assert other.eql?(other)
         | 
| 200 201 | 
             
              end
         | 
| 201 | 
            -
             | 
| 202 | 
            +
             | 
| 203 | 
            +
              def test_message_with_frames
         | 
| 204 | 
            +
                msg = ZMQ::Message.new
         | 
| 205 | 
            +
                frame = ZMQ::Frame.new("hello")
         | 
| 206 | 
            +
                assert_equal "hello", frame.data
         | 
| 207 | 
            +
                msg.add frame
         | 
| 208 | 
            +
                # frame is owned by message, but message is still owned by ruby,
         | 
| 209 | 
            +
                # so the frame data should still be accessible:
         | 
| 210 | 
            +
                assert_equal "hello", frame.data
         | 
| 211 | 
            +
              end
         | 
| 212 | 
            +
             | 
| 213 | 
            +
              def test_messge_add_frame_twice
         | 
| 214 | 
            +
                msg = ZMQ::Message.new
         | 
| 215 | 
            +
                frame = ZMQ::Frame.new("hello")
         | 
| 216 | 
            +
                msg.add frame
         | 
| 217 | 
            +
                assert_raises ZMQ::Error do
         | 
| 218 | 
            +
                  msg.add frame
         | 
| 219 | 
            +
                end
         | 
| 220 | 
            +
              end
         | 
| 221 | 
            +
             | 
| 222 | 
            +
              def test_message_is_gone_after_send
         | 
| 223 | 
            +
                ctx = ZMQ::Context.new
         | 
| 224 | 
            +
                endpoint = "inproc://test.test_message_is_gone_after_send"
         | 
| 225 | 
            +
                push = ctx.bind(:PUSH, endpoint)
         | 
| 226 | 
            +
                pull = ctx.connect(:PULL, endpoint)
         | 
| 227 | 
            +
                msg = ZMQ::Message.new
         | 
| 228 | 
            +
                frame = ZMQ::Frame.new("hello")
         | 
| 229 | 
            +
                msg.add frame
         | 
| 230 | 
            +
                push.send_message(msg)
         | 
| 231 | 
            +
                assert msg.gone?
         | 
| 232 | 
            +
                assert frame.gone?
         | 
| 233 | 
            +
              ensure
         | 
| 234 | 
            +
                ctx.destroy
         | 
| 235 | 
            +
              end
         | 
| 236 | 
            +
             | 
| 237 | 
            +
              def test_message_has_frames_on_receive
         | 
| 238 | 
            +
                ctx = ZMQ::Context.new
         | 
| 239 | 
            +
                endpoint = "inproc://test.test_message_is_gone_after_send"
         | 
| 240 | 
            +
                push = ctx.bind(:PUSH, endpoint)
         | 
| 241 | 
            +
                pull = ctx.connect(:PULL, endpoint)
         | 
| 242 | 
            +
                msg = ZMQ::Message.new
         | 
| 243 | 
            +
                msg.add ZMQ::Frame.new("hello")
         | 
| 244 | 
            +
                msg.add ZMQ::Frame.new("world")
         | 
| 245 | 
            +
                push.send_message(msg)
         | 
| 246 | 
            +
                received = pull.recv_message
         | 
| 247 | 
            +
                assert_not_nil received
         | 
| 248 | 
            +
                assert_equal 2, received.size
         | 
| 249 | 
            +
                assert_equal "hello", received.first.data
         | 
| 250 | 
            +
                assert_equal "world", received.next.data
         | 
| 251 | 
            +
              ensure
         | 
| 252 | 
            +
                ctx.destroy
         | 
| 253 | 
            +
              end
         | 
| 254 | 
            +
             | 
| 255 | 
            +
              def test_message_remove_frame
         | 
| 256 | 
            +
                msg = ZMQ::Message.new
         | 
| 257 | 
            +
                frame = ZMQ::Frame.new("hello")
         | 
| 258 | 
            +
                msg.add frame
         | 
| 259 | 
            +
                assert_equal 1, msg.size
         | 
| 260 | 
            +
                # same object is returned
         | 
| 261 | 
            +
                assert_equal frame.object_id, msg.first.object_id
         | 
| 262 | 
            +
                msg.remove frame
         | 
| 263 | 
            +
                assert_equal 0, msg.size
         | 
| 264 | 
            +
              end
         | 
| 265 | 
            +
             | 
| 266 | 
            +
              def test_message_array_same_frame_objects
         | 
| 267 | 
            +
                msg = ZMQ::Message.new
         | 
| 268 | 
            +
                frame = ZMQ::Frame.new("hello")
         | 
| 269 | 
            +
                msg.add frame
         | 
| 270 | 
            +
                ary = msg.to_a
         | 
| 271 | 
            +
                assert_equal 1, ary.count
         | 
| 272 | 
            +
                assert_equal frame, ary.first
         | 
| 273 | 
            +
                assert_equal frame.object_id, ary.first.object_id
         | 
| 274 | 
            +
              end
         | 
| 275 | 
            +
             | 
| 276 | 
            +
              def test_message_unwrap_dup
         | 
| 277 | 
            +
                ctx = ZMQ::Context.new
         | 
| 278 | 
            +
                router = ctx.socket(ZMQ::ROUTER)
         | 
| 279 | 
            +
                port = router.bind("tcp://127.0.0.1:*")
         | 
| 280 | 
            +
                req = ctx.connect(ZMQ::REQ, "tcp://127.0.0.1:#{port}")
         | 
| 281 | 
            +
                msg = ZMQ::Message.new
         | 
| 282 | 
            +
                msg.addstr "hello world"
         | 
| 283 | 
            +
                req.send_message msg
         | 
| 284 | 
            +
                msg2 = router.recv_message
         | 
| 285 | 
            +
                identity = msg2.unwrap
         | 
| 286 | 
            +
                assert_equal "hello world", msg2.first.data
         | 
| 287 | 
            +
                msg3 = ZMQ::Message.new
         | 
| 288 | 
            +
                msg3.addstr "reply"
         | 
| 289 | 
            +
                msg3.wrap identity.dup
         | 
| 290 | 
            +
                assert_equal 3, msg3.size
         | 
| 291 | 
            +
              ensure
         | 
| 292 | 
            +
                ctx.destroy
         | 
| 293 | 
            +
              end
         | 
| 294 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,8 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rbczmq
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 5 | 
            -
              prerelease: 
         | 
| 4 | 
            +
              version: 1.7.0
         | 
| 6 5 | 
             
            platform: ruby
         | 
| 7 6 | 
             
            authors:
         | 
| 8 7 | 
             
            - Lourens Naudé
         | 
| @@ -11,12 +10,11 @@ authors: | |
| 11 10 | 
             
            autorequire: 
         | 
| 12 11 | 
             
            bindir: bin
         | 
| 13 12 | 
             
            cert_chain: []
         | 
| 14 | 
            -
            date: 2013-07- | 
| 13 | 
            +
            date: 2013-07-21 00:00:00.000000000 Z
         | 
| 15 14 | 
             
            dependencies:
         | 
| 16 15 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 17 16 | 
             
              name: rake-compiler
         | 
| 18 17 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 19 | 
            -
                none: false
         | 
| 20 18 | 
             
                requirements:
         | 
| 21 19 | 
             
                - - ~>
         | 
| 22 20 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -24,7 +22,6 @@ dependencies: | |
| 24 22 | 
             
              type: :development
         | 
| 25 23 | 
             
              prerelease: false
         | 
| 26 24 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 27 | 
            -
                none: false
         | 
| 28 25 | 
             
                requirements:
         | 
| 29 26 | 
             
                - - ~>
         | 
| 30 27 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -86,6 +83,7 @@ files: | |
| 86 83 | 
             
            - lib/zmq/default_handler.rb
         | 
| 87 84 | 
             
            - lib/zmq/frame.rb
         | 
| 88 85 | 
             
            - lib/zmq/handler.rb
         | 
| 86 | 
            +
            - lib/zmq/logger.rb
         | 
| 89 87 | 
             
            - lib/zmq/loop.rb
         | 
| 90 88 | 
             
            - lib/zmq/message.rb
         | 
| 91 89 | 
             
            - lib/zmq/monitor.rb
         | 
| @@ -136,6 +134,7 @@ files: | |
| 136 134 | 
             
            - test/test_context.rb
         | 
| 137 135 | 
             
            - test/test_frame.rb
         | 
| 138 136 | 
             
            - test/test_handler.rb
         | 
| 137 | 
            +
            - test/test_logger.rb
         | 
| 139 138 | 
             
            - test/test_loop.rb
         | 
| 140 139 | 
             
            - test/test_message.rb
         | 
| 141 140 | 
             
            - test/test_monitoring.rb
         | 
| @@ -529,28 +528,27 @@ files: | |
| 529 528 | 
             
            - ext/zeromq/version.sh
         | 
| 530 529 | 
             
            homepage: http://github.com/methodmissing/rbczmq
         | 
| 531 530 | 
             
            licenses: []
         | 
| 531 | 
            +
            metadata: {}
         | 
| 532 532 | 
             
            post_install_message: 
         | 
| 533 533 | 
             
            rdoc_options:
         | 
| 534 534 | 
             
            - --charset=UTF-8
         | 
| 535 535 | 
             
            require_paths:
         | 
| 536 536 | 
             
            - lib
         | 
| 537 537 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 538 | 
            -
              none: false
         | 
| 539 538 | 
             
              requirements:
         | 
| 540 539 | 
             
              - - ! '>='
         | 
| 541 540 | 
             
                - !ruby/object:Gem::Version
         | 
| 542 541 | 
             
                  version: '0'
         | 
| 543 542 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 544 | 
            -
              none: false
         | 
| 545 543 | 
             
              requirements:
         | 
| 546 544 | 
             
              - - ! '>='
         | 
| 547 545 | 
             
                - !ruby/object:Gem::Version
         | 
| 548 546 | 
             
                  version: '0'
         | 
| 549 547 | 
             
            requirements: []
         | 
| 550 548 | 
             
            rubyforge_project: 
         | 
| 551 | 
            -
            rubygems_version:  | 
| 549 | 
            +
            rubygems_version: 2.0.3
         | 
| 552 550 | 
             
            signing_key: 
         | 
| 553 | 
            -
            specification_version:  | 
| 551 | 
            +
            specification_version: 4
         | 
| 554 552 | 
             
            summary: Ruby extension for ZeroMQ (ZMQ) using CZMQ - High-level C Binding for ØMQ
         | 
| 555 553 | 
             
              (http://czmq.zeromq.org)
         | 
| 556 554 | 
             
            test_files:
         | 
| @@ -573,6 +571,7 @@ test_files: | |
| 573 571 | 
             
            - test/test_context.rb
         | 
| 574 572 | 
             
            - test/test_frame.rb
         | 
| 575 573 | 
             
            - test/test_handler.rb
         | 
| 574 | 
            +
            - test/test_logger.rb
         | 
| 576 575 | 
             
            - test/test_loop.rb
         | 
| 577 576 | 
             
            - test/test_message.rb
         | 
| 578 577 | 
             
            - test/test_monitoring.rb
         | 
| @@ -582,4 +581,3 @@ test_files: | |
| 582 581 | 
             
            - test/test_threading.rb
         | 
| 583 582 | 
             
            - test/test_timer.rb
         | 
| 584 583 | 
             
            - test/test_zmq.rb
         | 
| 585 | 
            -
            has_rdoc: true
         |