-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 05/14/2014 09:37 PM, Gabriel Llamas wrote: > <http://img4.imagetitan.com/img4/fYptsdmGZ4vbijN/9/9_captura2.png> > > I'm developping a node.js native module and I need to emit buffers > with binary data (uint8_t) from C code. The thread architecture is > shown above. In my code I basically have this callback, this is the > start point from where I start receiving binary buffers: > > void bufferCallback (uint8_t* data, uint32_t length){ //Cannot > interact with V8 in this thread, so the data buffer must be sent > //to the main thread } > > The buffers contain video/image data, that is, they come from a > camera (the raspberry pi camera). My objective is to forward these > buffers to the javascript layer (yes, I know, this could suppose a > performance impact). Therefore I need to do 2 things: send the > arrays to the worker thread using uv_async_send() and then convert > the uint8_t array to a javascript Buffer object. This works but the > data that I receive after the uv_async_send() call is corrupted. > There's something between the "worker thread" and the "pthread" > that doesn't work as I expect. > > For example, if I save the data in a file, the video/image is not > corrupted: > > void bufferCallback (uint8_t* buffer, uint32_t length){ //Cannot > interact with V8 in this thread, so the data buffer must be sent > //to the main thread > > if (pwrite (fd, buffer, length, 0) == -1){ printf ("ERROR: > pwrite\n"); } } > > This is the code needed for inter-thread communication. For now, > let's ignore the V8 code needed for converting and sending the > buffer to the javascript layer. > > struct CHUNK { uint8_t* buffer; uint32_t length; }; > > void bufferCallback (uint8_t* buffer, uint32_t length){ //Cannot > interact with V8 in this thread, so the data buffer must be sent > //to the main thread > > CHUNK* chunk = (CHUNK*)malloc (sizeof (CHUNK)); > > //If it's an async communication then I need to memcpy the data in > a new buffer, //otherwise it could be freed before it is received > in the worker thread, right? uint8_t* dupBuffer = (uint8_t*)malloc > (sizeof (uint8_t)*length); memcpy (dupBuffer, buffer, length); > > chunk->buffer = dupBuffer; chunk->length = length; > > async.data = (void*)chunk; uv_async_send (&async); } > > void bufferCallbackSafe (uv_async_t* handle, int status){ CHUNK* > chunk = (CHUNK*)handle->data; > > if (pwrite (fd, chunk->buffer, chunk->length, 0) == -1){ printf > ("ERROR: pwrite\n"); } > > free (chunk->buffer); free (chunk); } > > As you can see, instead of saving the data chunks from the pthread, > I'm saving them from the worker thread after I receive them > asynchronously with uv_async_send. Well, the data that's stored in > the file is corrupted, I see weird artifacts, so there's something > about the async communication that I don't understand. > > Any hints? >
Calls to uv_async_send are coalesced, so X calls to uv_async_send don't yield X callbacks executed. Basically you are overriding the data. You need to store your buffers in a queue from your worker thread and then process the queue in the callback called after uv_async_send. Since you are appending to the queue from one thread and processing it from another, it needs to be thread-safe. Cheers, - -- Saúl Ibarra Corretgé bettercallsaghul.com -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 Comment: Using GnuPG with Icedove - http://www.enigmail.net/ iQIcBAEBAgAGBQJTc8eWAAoJEEEOVVOum8BZzn0P/2a+ATLgGAg0NEYeSJS2coI5 z6n0/mLfFs8Q80ICAgDaWYOdwvUubbJw+fAPqzcEobQxlNGYWwJZOJM4xs499hUL i5yQabOfTXwD8g4IZNH7WaofN0CyK+FsbF92wmZ73Q5x7qdLRIxrbT+EgMrBLPGN zoR0Jhe/Q4JC4FQO0JG0adBUZ5rcM2iUs2Og+WKsL3kACLCNTcu55p5oZ45rPtoM is77w9OfiiuOm1GHj4V/sgU5clcZPn/n+MgEgMLQN/wUUps22QVA7QLa2k3gvf0Z qOwPzEU9Uc7gnrhw9u9QI2GgDF1l5xNFZeh+dg4rWTBQmJQzi7/e8hxcrICdkfj+ 9AjVk5ViEufxdDGjcFnYZxLV0sSl2yfRjfPe5GNIo7TFiIIWunTmO86ErNfeUZMh 3B4S7c2vo4oyjhxPsvHKahVUtJjwuIRZ5bOfGi/NbFjCpkuNG2UMmsIDj5Tb3bt2 x0q7qREg4uld47HJ7PYnlzPJ9LDTIMsKTr/E8WgFW+DKalrK4O3IYqWMD53f1Yvn ecR2IZL/roU+i66Eurwx1fEWIb3A4EsY8HcGluB/VSvyiLdH6wKqTQ8lYI6QcKFQ hJhug3oV/Hlj6ZrQw0FN7tTxglFIzXtZwlbTWfOS4gx3UwFDv6g/dlUVU+lPmv/W B8d8sL6+YsFpCTC/V/ez =oq+A -----END PGP SIGNATURE----- -- You received this message because you are subscribed to the Google Groups "libuv" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/libuv. For more options, visit https://groups.google.com/d/optout.
