/* * call-seq: * socket.recv(flags=0) -> message | nil * * Receives a message from the _socket_. If there are no messages available * on the _socket_, the recv() function shall block until the request can be * satisfied. The _flags_ argument is a combination of the flags defined * below: * * [ZMQ::NOBLOCK] Specifies that the operation should be performed in non-blocking mode. If there are no messages available on the _socket_, the recv() function shall fail and return _nil_. * * == Multi-part messages * A 0MQ message is composed of 1 or more message parts. 0MQ ensures atomic * delivery of messages; peers shall receive either all <em>message parts</em> of a * message or none at all. * * The total number of message parts is unlimited. * * An application wishing to determine if a message is composed of multiple * parts does so by retrieving the value of the ZMQ::RCVMORE socket option on the * socket it is receiving the message from, using getsockopt(). If there are no * message parts to follow, or if the message is not composed of multiple parts, * ZMQ::RCVMORE shall report a value of false. Otherwise, ZMQ::RCVMORE shall * report a value of true, indicating that more message parts are to follow. */ static VALUE socket_recv (int argc_, VALUE* argv_, VALUE self_) { VALUE flags_; rb_scan_args (argc_, argv_, "01", &flags_); void * s; Data_Get_Struct (self_, void, s); Check_Socket (s); int flags = NIL_P (flags_) ? 0 : NUM2INT (flags_); zmq_msg_t msg; int rc = zmq_msg_init (&msg); assert (rc == 0); #ifdef HAVE_RUBY_INTERN_H if (!(flags & ZMQ_NOBLOCK)) { struct zmq_send_recv_args recv_args; recv_args.socket = s; recv_args.msg = &msg; recv_args.flags = flags; rb_thread_blocking_region (zmq_recv_blocking, (void*) &recv_args, NULL, NULL); rc = recv_args.rc; } else #endif rc = zmq_recv (s, &msg, flags); if (rc != 0 && zmq_errno () == EAGAIN) { rc = zmq_msg_close (&msg); assert (rc == 0); return Qnil; } if (rc != 0) { rb_raise (rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ())); rc = zmq_msg_close (&msg); assert (rc == 0); return Qnil; } VALUE message = rb_str_new ((char*) zmq_msg_data (&msg), zmq_msg_size (&msg)); rc = zmq_msg_close (&msg); assert (rc == 0); return message; }