Are blocks and libdispatch available on linux?
Asked Answered
N

4

16

I would love to try out grand central dispatch, but all I have to develop on is an Ubuntu workstation. Is libdispatch, and the blocks extension to c/obj-c etc... available on linux? If so, how do I get them?

Nellie answered 12/4, 2011 at 18:36 Comment(0)
S
15

You may need to use the LLVM Clang (available on Ubuntu) compiler to get blocks at this time (I don't think this is available in gcc yet, but I haven't been keeping up with gcc, so I could be wrong.)

There are efforts underway to port libdispatch (home for the open source libdispatch) to Linux. Most of the effort seems to be on Debian so far, but some on other distributions, too. See these discussion threads:

Salicaceous answered 12/4, 2011 at 18:52 Comment(3)
Thank you! Many google searches resulted in nothing but confusion for me.Nellie
You're welcome! It can be surprisingly difficult to find stuff like this with Google at times, particularly on a subject that isn't familiar.Salicaceous
As long as you're ok using clang, I'm using gcd quite happily on ubuntu natty.Febrifuge
H
7

I've done some work to get the OS X Mountain Lion version of libdispatch working on Linux; the result is up at Github: http://nickhutchinson.me/libdispatch/.

Hemi answered 11/12, 2012 at 0:31 Comment(0)
C
3

Use clang-3.4.

  • sudo apt-get install libdispatch-dev
  • sudo apt-get install libblocks-runtime-dev
  • Compile with -fblocks
  • Link with -lBlocksRuntime -ldispatch
Cristie answered 24/4, 2016 at 13:43 Comment(0)
G
-1

Rather than use blocks, use c++ lambdas. They play better with c++ and there is less hidden magic.

I do it like this:

/// Dispatch a function object to a queue.
template<class F>
static void dispatch_async_function(dispatch_queue_t queue, F f) {
    struct context_t {
        using function_type = F;

        context_t(function_type&& f) noexcept
        : _f(std::move(f))
        {}

        static void execute(void* p) noexcept {
            auto context = reinterpret_cast<context_t*>(p);
            if (context) {
                try {
                    context->_f();
                }
                catch(...) {
                    // error processing here
                }
                delete context;
            }
        }

    private:
        function_type _f;
    };

    dispatch_async_f(queue, new context_t<F>(std::move(f)), &context_t<F>::execute);
}

And if you need to ensure that some shared resource exists before the call takes place (such as a callback on an object that is kept alive by a shared pointer):

/// Dispatch a function object to a queue. Only execute the function if the tie
/// locks successfully.
template<class F>
static void dispatch_async_tied_function(dispatch_queue_t queue, std::weak_ptr<void> tie, F f) {
    struct context_t {
        using function_type = F;

        context_t(function_type&& f) noexcept
        : _f(std::move(f))
        {}

        static void execute(void* p) noexcept {
            auto context = reinterpret_cast<context_t*>(p);
            auto lock = _tie.lock();
            if (context && tie) {
                try {
                    context->_f();
                }
                catch(...) {
                    // error processing here
                }
                delete context;
            }
        }

    private:
        function_type _f;
        std::weak_ptr<void> _tie;
    };

    dispatch_async_f(queue, new context_t<F>(std::move(f)), &context_t<F>::execute);
}

call them like this

dispatch_function(queue, []() { something(); });

or...

dispatch_tied_function(_myQueue, shared_from_this(), [this]() { somethingOnThis(); });
Greek answered 22/4, 2014 at 15:22 Comment(1)
This is the reason I try to avoid C++ whenever I can. I have programmed C++ for some 25 years, but looking at your code I hardly get any mental image as to what it actually does. C++ used to be "C with classes" but this is a bit too weird.Dust

© 2022 - 2024 — McMap. All rights reserved.