[MacRuby] #1393: Invocation of blocks registered using -[NSNotificationCenter addObserverForName:object:queue:usingBlock:] is unreliable
#1393: Invocation of blocks registered using -[NSNotificationCenter addObserverForName:object:queue:usingBlock:] is unreliable --------------------------------+------------------------------------------- Reporter: sohocoke@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: --------------------------------+------------------------------------------- It seems that when a block / proc is registered for notification (cf. a selector), its invocation occasionally fails. Here is a program that, occasionally, reproduces the case. notification-test.rb {{{ # reduced case of block-based observation framework 'cocoa' require 'thread' class TestSender def send NSNotificationCenter.defaultCenter.postNotification NSNotification.notificationWithName(:kTestNotification, object:[1, 2, 3]) end end class ObjectWithCounter attr_reader :counter def initialize super @counter = 0 @mutex = Mutex.new end def increment @mutex.synchronize { @counter += 1 } end end class Observer1 < ObjectWithCounter def listen_with_block NSNotificationCenter.defaultCenter.addObserverForName :kTestNotification, object:nil, queue:nil, usingBlock:Proc.new { |notification| NSLog("#{self} notified - in block now.") self.increment } end end class Observer2 < ObjectWithCounter def listen_with_callback NSNotificationCenter.defaultCenter.addObserver self, selector:"handle_notification:", name: :kTestNotification, object:nil end def handle_notification(notification) NSLog("#{self} notified of #{notification} - in handler now.") self.increment end end mutex = Mutex.new o1_counter, o2_counter = 0, 0 30.times do sender = TestSender.new o1 = Observer1.new o1.listen_with_block sender.send o2 = Observer2.new o2.listen_with_callback sender.send mutex.synchronize do o1_counter += o1.counter o2_counter += o2.counter end end puts "o1 notified #{o1_counter} times." puts "o2 notified #{o2_counter} times." # expect to have o1 notified 60 times, o2 30 times. }}} I ran it thusly and observed the output: {{{ [~/dev/src/mac/macruby]$ while [ 0 ]; do ruby notification-test.rb >> notification-test.out done [~/dev/src/mac/macruby]$ grep 'notified' notification-test.out o1 notified 60 times. o2 notified 30 times. o1 notified 59 times. o2 notified 30 times. o1 notified 59 times. o2 notified 30 times. o1 notified 58 times. o2 notified 30 times. }}} i (hastily) threw in some mutexes after a first version of the test program on paranoia of there being a silly threading mistake, but documentation for the method on NSNotificationCenter suggests that the erroneous invocation should occur synchronously on the main thread of the program anyway. I tried macruby-0.10 and macruby-nightly installed via rvm. -- Ticket URL: <http://www.macruby.org/trac/ticket/1393> MacRuby <http://macruby.org/>
participants (1)
-
MacRuby