Queue-Specific Data
By: . Published: . Categories: poc gcd c oop.GCD has a queue-specific storage API accessed using
dispatch_queue_{set,get}_specific
. This replaces the thread-specific storage
provided by pthread_{set,get}_specific
that you cannot use with GCD blocks:
static void *sQueueKey_Client = “client”; struct my_client *client = calloc(1, sizeof(*client)); client = (struct my_client){ .val = 1 }; / use the unique static address as the key, * not the address of the string itself */ dispatch_queue_set_specific(q, &sQueueKey_Client, client, free); dispatch_async(q, ^{ struct my_client *client = dispatch_queue_get_specific(q, &sQueueKey_Client); DoStuffWith(client); });
Only there’s one new addition to the family: dispatch_get_specific
looks up
the value in the current context defined by the current queue. This context is
broader than the single queue that dispatch_queue_get_specific
will search.
If a key is not set on the current queue, it will check that queue’s target
queue. If it’s not found on that queue, it will move down the line to that
queue’s target queue:
dispatch_queue_t io_q = dispatch_queue_create("client_io_queue", 0);
dispatch_set_target_queue(io_q, q);
dispatch_async(io_q, ^{
/* This will check the current queue (io_q), fail to find
* the key, then check the target queue (q) and find it. */
struct my_client *client = dispatch_get_specific(&sQueueKey_Client);
SendMessage(client);
});
Queue-specific value lookup sounds a lot like chasing the prototype chain in a prototypal object system like JavaScript. In Obj-C, it echoes how method implementation search runs up the inheritance chain to find an implementation for a given message.
It turns out you can abuse this to transform dispatch queue value lookup into the heart of a prototypal object system embedded within Objective-C – where it’s not terribly useful, because Obj-C already has its own object system – or C, where it could be an improvement over hand-writing OOP in C.
I wrote a small, ugly demo of this. It’s available from GitHub as jeremy-w/demo-draft. As it stands, it’s certainly not an improvement over hand-written C OOP, but it did prove an interesting exercise.