[Boost-bugs] [Boost C++ Libraries] #7724: executing signals2::signal::connect creates many copies of the connected object

Subject: [Boost-bugs] [Boost C++ Libraries] #7724: executing signals2::signal::connect creates many copies of the connected object
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2012-11-22 13:31:06


#7724: executing signals2::signal::connect creates many copies of the connected
object
----------------------------------------------------+-----------------------
 Reporter: pszeptycki@… | Owner: fmhess
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: signals2
  Version: Boost 1.49.0 | Severity: Problem
 Keywords: signals2 connect multiple objects copy |
----------------------------------------------------+-----------------------
 I am trying to figure out where is the problem, maybe what I have
 implemented is incorrect or it is a bug.

 When trying to connect to a signal the passed object is copied many times
 and the final triggered signal executes a method on a copy of the passed
 object.

 Signal is the following type:
 {{{
 typedef signals2::signal<void (NotificationCenter::Notification)> Signal;
 }}}
 Following code (NotificationCenter creates a shared_ptr<> to the requested
 signals):
 {{{
 class NotificationReceived
 {
 public:
         int runCount;
         NotificationReceived()
         {
                 std::cout << "* Receiver CREATED" << std::endl;
                 runCount = 0;
         }

         NotificationReceived(const NotificationReceived &cSource)
         {
                 std::cout << "* Receiver COPIED" << std::endl;
                 runCount = cSource.runCount;
         }

         ~NotificationReceived()
         {
                 std::cout << "* Receiver DELETED" << std::endl;
         }

         void Receive(NotificationCenter::Notification notif)
         {
                 std::cout << std::endl << "Receive: Notification received:
 " + notif.m_information << std::endl << std::endl;
                 runCount++;
         }
 };

 BOOST_AUTO_TEST_CASE( test_notification_center_notify)
 {
         NotificationCenter nCenter(NotificationCenter::NCT_DELAYED);
         NotificationReceived receiver;
         NotificationCenter::Signal* sig =
 nCenter.RegisterForNotification(NotificationCenter::Notification::NT_BROADCAST);
         sig->connect(boost::bind(&NotificationReceived::Receive, receiver,
 _1));


 nCenter.BroadcastNotification(NotificationCenter::Notification(NotificationCenter::Notification::NT_BROADCAST,
 "Testing"));
         boost::this_thread::sleep(boost::posix_time::seconds(2));
         BOOST_REQUIRE_EQUAL(receiver.runCount, 1);
 }
 }}}
 Has following output:
 {{{
 * Receiver CREATED
 - Queue empty - sleeping 500ms
 * Receiver COPIED
 * Receiver COPIED
 * Receiver COPIED
 * Receiver COPIED
 * Receiver COPIED
 * Receiver DELETED
 * Receiver DELETED
 * Receiver DELETED
 * Receiver COPIED
 * Receiver DELETED
 * Receiver DELETED
 * Receiver COPIED
 * Receiver COPIED
 * Receiver COPIED
 * Receiver COPIED
 * Receiver COPIED
 * Receiver COPIED
 * Receiver COPIED
 * Receiver COPIED
 * Receiver DELETED
 * Receiver DELETED
 * Receiver DELETED
 * Receiver DELETED
 * Receiver DELETED
 * Receiver DELETED
 * Receiver COPIED
 * Receiver DELETED
 * Receiver COPIED
 * Receiver DELETED
 * Receiver DELETED
 * Receiver COPIED
 * Receiver DELETED
 * Receiver DELETED
 - Thread waked up
 - Queue not empty, searching receivers ...
 - Sending notification

 Receive: Notification received: Testing

 - Queue empty - sleeping 500ms
 - Thread waked up
 - Queue empty - sleeping 500ms
 - Thread waked up
 - Queue empty - sleeping 500ms
 * Receiver DELETED
 * Receiver DELETED

 *** 1 failure detected in test suite "FrameworkTests"
 }}}

 '''Why the "receiver" object has been copied many times and the final
 method has not been executed on the original object but on a copy which
 proves the check of the "runCount"?'''

 I have managed to go around this problem adding a shared_ptr<>

 Following code (classes the same):
 {{{
         NotificationCenter nCenter(NotificationCenter::NCT_DELAYED);
         boost::shared_ptr<NotificationReceived> receiver(new
 NotificationReceived);
         NotificationCenter::Signal* sig =
 nCenter.RegisterForNotification(NotificationCenter::Notification::NT_BROADCAST);
         sig->connect(boost::bind(&NotificationReceived::Receive, receiver,
 _1));


 nCenter.BroadcastNotification(NotificationCenter::Notification(NotificationCenter::Notification::NT_BROADCAST,
 "Testing"));
         boost::this_thread::sleep(boost::posix_time::seconds(2));
         BOOST_REQUIRE_EQUAL(receiver->runCount, 1);
 }}}

 Outputs what I expected also from the first example:
 {{{
 * Receiver CREATED
 - Queue empty - sleeping 500ms
 - Thread waked up
 - Queue not empty, searching receivers ...
 - Sending notification

 Receive: Notification received: Testing

 - Queue empty - sleeping 500ms
 - Thread waked up
 - Queue empty - sleeping 500ms
 - Thread waked up
 - Queue empty - sleeping 500ms
 * Receiver DELETED

 *** No errors detected
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/7724>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:11 UTC