[libdispatch-dev] Block not released after dispatch_source_set_event_handler

Daniel A. Steffen dsteffen at apple.com
Mon Feb 25 00:23:12 PST 2013


not sure, sorry, probably best to ask on objc-language at lists.apple.com about that one, and specify the exact linker line used (along with the os & tools versions).

Daniel

On Feb 25, 2013, at 0:13, Allan Odgaard <lists+libdispatch at simplit.com> wrote:

> Hi Daniel.
> 
> Thanks for the reply — as I was seeing the leak in code that did use the event handler, I spent some more time investigating, and it seems my issue is with linking C++ object files with -fobjc-link-runtime and setting -mmacosx-version-min=10.7.
> 
> I am not sure if this is a bug or I am violating some contract by linking with the obj-c run-time for non-obj-c code. Presumably it has to do with the 10.7 ARC-lite compatibility code that clang adds (though my code was pure C++ so did not use ARC).
> 
> Kind regards Allan
> 
> 
> On Feb 25, 2013, at 6:28 AM, "Daniel A. Steffen" <dsteffen at apple.com> wrote:
> 
>> Hi Allan,
>> 
>> dispatch sources are created in a suspended state and must be resumed after configuration, see the dispatch_source_create(3) manpage and the SUSPENSION section of dispatch_object(3) for details.
>> 
>> All setters of source configuration are asynchronous in nature and only take effect when the source is not suspended.
>> Once dispatch_resume(source) is called, the handler block retained by dispatch_source_set_event_handler() will be released when the subsequent dispatch_source_set_event_handler_f() takes effect.
>> 
>> Daniel 
>> 
>> On Feb 23, 2013, at 8:04, Allan Odgaard <lists+libdispatch at simplit.com> wrote:
>> 
>>> I am seeing an issue where the block given to dispatch_source_set_event_handler appear not to be released when a new handler is set.
>>> 
>>> If I build and run the code below:
>>> 
>>> xcrun clang++ -std=c++11 -stdlib=libc++ test.cc
>>> 
>>> It outputs the ‘create’ line, but never any ‘destroy’.
>>> 
>>> If I don’t call dispatch_source_set_event_handler then I see the expected ‘destroy’. Alternatively I can call an extra Block_release(), which also results in the shared pointer being destroyed.
>>> 
>>> This is on Mac OS X 10.8.2 Build 12C60 using Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn).
>>> 
>>> ----------8<----------
>>> 
>>> #include <dispatch/dispatch.h>
>>> #include <Block.h>
>>> #include <stdio.h>
>>> #include <memory>
>>> 
>>> void setup_dispatch_source ()
>>> {
>>> struct record_t
>>> {
>>>    record_t ()  { fprintf(stderr, "%p: create\n", this); }
>>>    ~record_t () { fprintf(stderr, "%p: destroy\n", this); }
>>> };
>>> 
>>> std::shared_ptr<record_t> record(new record_t);
>>> auto block = Block_copy(^(){ fprintf(stderr, "%p\n", record.get()); });
>>> 
>>> dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, open("/tmp", O_EVTONLY, 0), DISPATCH_VNODE_REVOKE, dispatch_get_main_queue());
>>> dispatch_source_set_event_handler(source, block);
>>> dispatch_source_set_event_handler_f(source, NULL);
>>> 
>>> Block_release(block);
>>> }
>>> 
>>> int main (int argc, char const* argv[])
>>> {
>>> setup_dispatch_source();
>>> return 0;
>>> }
>>> 
>>> _______________________________________________
>>> libdispatch-dev mailing list
>>> libdispatch-dev at lists.macosforge.org
>>> https://lists.macosforge.org/mailman/listinfo/libdispatch-dev
>> 
> 
> _______________________________________________
> libdispatch-dev mailing list
> libdispatch-dev at lists.macosforge.org
> https://lists.macosforge.org/mailman/listinfo/libdispatch-dev



More information about the libdispatch-dev mailing list