开发者

Are blocks and libdispatch available on linux?

开发者 https://www.devze.com 2023-02-24 22:10 出处:网络
I would love to try out grand central开发者_JS百科 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

I would love to try out grand central开发者_JS百科 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?


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:

  • linux + libdispatch + clang + blocks
  • libdispatch porting status update
  • Grand Central Dispatch available for Debian (archived link)


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/.


Use clang-3.4.

  • sudo apt-get install libdispatch-dev
  • sudo apt-get install libblocks-runtime-dev
  • Compile with -fblocks
  • Link with -lBlocksRuntime -ldispatch


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(); });
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号