From 19c62b93fc813cce9beffc9ab5e3b05cc53230b0 Mon Sep 17 00:00:00 2001 From: Martin Hurton Date: Wed, 30 Apr 2014 14:17:38 +0200 Subject: [PATCH] Define i_properties interface - copy and move message operations are updated to maintain proper reference count of properties object - zmq_msg_gets updated to use i_properties interface to fetch property value - setter/getter added to msg_t class --- src/Makefile.am | 1 + src/i_properties.hpp | 45 ++++++++++++++++++++++++++++++++++++++++++++ src/msg.cpp | 28 ++++++++++++++++++++++++++- src/msg.hpp | 5 +++-- src/zmq.cpp | 8 ++++++-- 5 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 src/i_properties.hpp diff --git a/src/Makefile.am b/src/Makefile.am index c2288146..f5de3a69 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,6 +32,7 @@ libzmq_la_SOURCES = \ i_decoder.hpp \ i_engine.hpp \ i_poll_events.hpp \ + i_properties.hpp \ io_object.hpp \ io_thread.hpp \ ip.hpp \ diff --git a/src/i_properties.hpp b/src/i_properties.hpp new file mode 100644 index 00000000..043e671c --- /dev/null +++ b/src/i_properties.hpp @@ -0,0 +1,45 @@ +/* + Copyright (c) 2007-2014 Contributors as noted in the AUTHORS file + + This file is part of 0MQ. + + 0MQ is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 0MQ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef __ZMQ_I_PROPERTIES_HPP_INCLUDED__ +#define __ZMQ_I_PROPERTIES_HPP_INCLUDED__ + +namespace zmq +{ + // Interface for accessing message properties. + // Implementers are supposed to use reference counting to + // manage object's lifetime. + + struct i_properties + { + virtual ~i_properties () {} + + // Returns pointer to property value or NULL if + // property not found. + virtual const char *get (const char *property) const = 0; + + virtual void add_ref () = 0; + + // Drop reference. Returns true iff the reference + // counter drops to zero. + virtual bool drop_ref () = 0; + }; +} + +#endif diff --git a/src/msg.cpp b/src/msg.cpp index 03ca150c..6802d3c9 100644 --- a/src/msg.cpp +++ b/src/msg.cpp @@ -26,6 +26,7 @@ #include "stdint.hpp" #include "likely.hpp" +#include "i_properties.hpp" #include "err.hpp" // Check whether the sizes of public representation of the message (zmq_msg_t) @@ -149,11 +150,14 @@ int zmq::msg_t::close () } } + if (u.base.properties != NULL) + if (u.base.properties->drop_ref ()) + delete u.base.properties; + // Make the message invalid. u.base.type = 0; return 0; - } int zmq::msg_t::move (msg_t &src_) @@ -201,6 +205,9 @@ int zmq::msg_t::copy (msg_t &src_) } } + if (src_.u.base.properties != NULL) + src_.u.base.properties->add_ref (); + *this = src_; return 0; @@ -268,6 +275,19 @@ void zmq::msg_t::set_fd (int64_t fd_) file_desc = fd_; } +zmq::i_properties *zmq::msg_t::properties () const +{ + return u.base.properties; +} + +void zmq::msg_t::set_properties (zmq::i_properties *properties_) +{ + assert (properties_ != NULL); + assert (u.base.properties == NULL); + properties_->add_ref (); + u.base.properties = properties_; +} + bool zmq::msg_t::is_identity () const { return (u.base.flags & identity) == identity; @@ -297,6 +317,9 @@ void zmq::msg_t::add_refs (int refs_) { zmq_assert (refs_ >= 0); + // Operation not supported for messages with properties. + zmq_assert (u.base.properties == NULL); + // No copies required. if (!refs_) return; @@ -317,6 +340,9 @@ bool zmq::msg_t::rm_refs (int refs_) { zmq_assert (refs_ >= 0); + // Operation not supported for messages with properties. + zmq_assert (u.base.properties == NULL); + // No copies required. if (!refs_) return true; diff --git a/src/msg.hpp b/src/msg.hpp index bd0c09b9..efddae25 100644 --- a/src/msg.hpp +++ b/src/msg.hpp @@ -25,6 +25,7 @@ #include "config.hpp" #include "atomic_counter.hpp" +#include "i_properties.hpp" // Signature for free function to deallocate the message content. // Note that it has to be declared as "C" so that it is the same as @@ -70,6 +71,8 @@ namespace zmq void reset_flags (unsigned char flags_); int64_t fd (); void set_fd (int64_t fd_); + i_properties *properties () const; + void set_properties (i_properties *properties_); bool is_identity () const; bool is_credential () const; bool is_delimiter () const; @@ -86,8 +89,6 @@ namespace zmq private: - class i_properties; - // Size in bytes of the largest message that is still copied around // rather than being reference-counted. enum { msg_t_size = 48 }; diff --git a/src/zmq.cpp b/src/zmq.cpp index be863bbb..69a94d1d 100644 --- a/src/zmq.cpp +++ b/src/zmq.cpp @@ -63,6 +63,7 @@ struct iovec { #include "err.hpp" #include "msg.hpp" #include "fd.hpp" +#include "i_properties.hpp" #if !defined ZMQ_HAVE_WINDOWS #include @@ -646,8 +647,11 @@ int zmq_msg_set (zmq_msg_t *, int, int) const char *zmq_msg_gets (zmq_msg_t *msg_, const char *property_) { - // All unknown properties return NULL - return NULL; + zmq::i_properties *properties = ((zmq::msg_t*) msg_)->properties (); + if (properties) + return properties->get (property_); + else + return NULL; } // Polling.