Handling Asynchronous Operations

As we will see in our later discussion of IOUSBLib classes, many methods perform operations that complete asynchronously. All such asynchronous methods take two parameters, a pointer to a callback function and a parameter named “refcon” that allows the application to pass an arbitrary context value to its callback. The callback function has the following signature:

void    MyCallbackFunction (void* refcon, IOReturn result, void* arg0);

The first parameter, refcon, is the application's arbitrary context parameter. The second parameter reports the overall result of the operation; a value of kIOReturnSuccess indicates the operation completed successfully. The final argument, arg0, is provided by the IOUSBLib and is dependent on the type of operation performed. In this chapter, when we describe an asynchronous method, we will also describe the value passed by IOUSBLib to the callback function through the arg0 parameter.

Just as a kernel driver uses a work loop to synchronize its completion routines against other driver code, a user-space application can synchronize completion callbacks from IOUSBLib against the rest of its code using a run loop.

To begin, an application must create a run loop source for the IOUSBLib class that will be performing asynchronous operations. The IOUSBLib classes contain methods for creating either a run loop source or a mach port to receive asynchronous notifications; however, most applications will need to work only with the run loop source.

It's important to note the IOUSBLib classes provide a method with the prefix “Create” and with the prefix “Get”(such as CreateDeviceAsyncEventSource and GetDeviceAsyncEventSource). However, the “Get” method will only return an object that has previously been initialized through the “Create” method. An example function to create and install a run loop source that will be used to receive asynchronous notifications from the IOUSBDeviceInterface class is shown in the following snippet.

IOReturn   InstallRunLoopSourceForUSBDevice (IOUSBDeviceInterface300** usbDevice)
{
     CFRunLoopSourceRef         runLoopSource;
     IOReturn                   error;
     
     error = (*usbDevice)->CreateDeviceAsyncEventSource(usbDevice, &runLoopSource);
     if (error == kIOReturnSuccess)
           CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
     
     return error;
}

An application is free to install the run loop source on the run loop of any particular thread it wishes, including the run loop for the application's main thread. The object ownership rules follow the same convention as all Core Foundation functions: If an application obtains an object from a “Create” method, it owns that object and is responsible for releasing it. If an application obtains an object from a “Get” method, it does not own a reference to that object, so if the application wishes to hold on to that object, it must explicitly retain the object first.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.205.214