joyent/libuv — pull request #858 by navaneeth (2013-07-21 06:22:02+00:00)
Title: unix, windows, darwin : Implemented uv channels

# Introduction

This commit attempts to implement channels (something very similar to what golang has) to `libuv`.

A channel provides a mechanism for two concurrently executing functions to communicate by passing any value. This value will be passed to all the receivers that the channel has. This simplifies message passing between worker threads.

Channel internally holds a mutex and synchronizes the messages it gets. Because of this, user don't have to acquire a lock when sending or receiving from channels.

# Example

```c
#include "include/uv.h"
#include
#include

static void worker(void* arg) {
int i;
char *string;
uv_chan_t* chan = arg;

for (i = 0; i < 10; i++) {
string = malloc(sizeof(char) * 2);
sprintf(string, "%d", i);
uv_chan_send (chan, string);
}

uv_chan_send (chan, NULL);
}

int main() {
uv_thread_t thread1, thread2;
uv_chan_t chan;
char *message;
int count = 0;

uv_chan_init (&chan);
uv_thread_create(&thread1, worker, &chan);
uv_thread_create(&thread2, worker, &chan);

while(count < 2) {
message = uv_chan_receive (&chan);
if (message == NULL)
count++;
printf ("%s\n", message);
free (message);
}

uv_thread_join(&thread1);
uv_thread_join(&thread2);
uv_chan_destroy (&chan);
return 0;
}
```

# Future work

This is just a first cut version of the channels. We could also implement the following,

* Specifying maximum size of elements that a channel can hold. If more elements that this is queued, `uv_chan_send` will block until someone reads from it.
* To avoid multiple threads updating same instance of data, data needs to be deep copied before sending to the channel. Currently everyone who uses `uv_chan_send` has to remember to deep copy the data. This can be simplified by adding a `copy_cb` to the `uv_chan_t` which gets called whenever `uv_chan_send` is called. This callback can deep copy data and return pointer to the new instance. This way, user has to configure it only while creating the channel and while sending, callback will take care of deep copying.

This idea is largely inspired from the golang's channels. I believe this simplifies communication between threads.

Let me know the feedback.