Asynchronous threads, or “runloops” to monitor a “source”

Once I had the synchronous read, it was just a matter of continuing with the example and setting up an asynchronous read (which does not loose data the way the synchronous read does).

I will take out the declarations and error checks which are in the USB simple example code

To start with, I declared gbuffer to be of size 320000 instead of 8 (to capture 5 mn of data) and set that declaration at the head of the program (so it is global)

In the synchronous case, all the instructions execute one after the other. Nothing can be done while the data is read. In the asynchronous case, the data is read from the input pipe at the same time as the main program is executing its tasks (on a single processor, the two codes alternate)

One way to set up two pieces of code to execute simultaneously is to start a “thread”.

But if the thread needs to remain running so that it can process requests at a future time, one uses a thread’s run loop. The run loop monitors input sources attached to the thread and dispatches the events it receives to the thread’s installed handler functions. After the handlers finish processing the event, the run loop returns the thread to its idle state and waits for more events.

Event-driven applications receive their events in a run loop. A run loop monitors sources of input to the application and dispatches control when sources become ready for processing. When processing is complete, control passes back to the run loop which then waits for the next event.

with the command, CFrunlooprun control is passed to the run loop until CFRunLoopStop

And this is more or less what happens in the transferdata function: create a source, CreateInterfaceAsyncEventSource, add the source to the runloop, CFRunLoopAddSource, request the input of data for a certain number of bytes, ReadPipeAsync, and start the runloop so it can monitor the source and read the data as it becomes available.

next I need to read about the notion of a callbackfunction

MyCallBackFunction(void *dummy, IOReturn result, void *arg0)
printf(“MyCallbackfunction: %d, %d, %d\n”, (int)dummy, (int)result, (int)arg0);


void transferData(IOUSBInterfaceInterface **intf, UInt8 inPipeRef)

numBytesRead = sizeof(gBuffer);

err = (*intf)->CreateInterfaceAsyncEventSource(intf, &cfSource);

CFRunLoopAddSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);

err = (*intf)->ReadPipeAsync(intf, inPipeRef, gBuffer, numBytesRead, (IOAsyncCallback1)MyCallBackFunction, (void*)(UInt32)inPipeRef);


//when the program reaches this line of code
// the reading of the transmission of the data is over, and one can read
// the data in gbuffer



  1. Jerry

    January 27, 2011 @ 1:04 pm


    thanks very much for your document, I have the same question, and the last question is the Loop. The loop can not get the data every, just one time.

  2. Sing

    May 2, 2011 @ 11:07 pm


    Thanks, but the MyCallBackFunction is never called, is it having some problem?
    I have check the :
    err = (*intf)->ReadPipeAsync(intf, inPipeRef, gBuffer, numBytesRead, (IOAsyncCallback1)MyCallBackFunction, (void*)(UInt32)inPipeRef);

    But there is no error, MyCallBackFunction is never called.

  3. Sing

    May 2, 2011 @ 11:52 pm


    Now i try that the device cannot close, if close will not trigger.
    But i have the same problem like Jerry. The function only can call by one time. After that cannot trigger again. Do you know what is the happen?


Log in