Asynchronous calls are made in a separate operating system thread. When the call is blocked waiting for a resource, only that thread blocks and not the thread that IBM Smalltalk is running in.
To support asynchronous callout, IBM Smalltalk manages both the thread and some additional resources in fixed space. The additional resources allow IBM Smalltalk and the asynchronous thread to interact.
To make asynchronous calls, the platform must support threads at the operating system level. On platforms that do not support threads at such a level, asynchronous calls are converted into synchronous calls.
To determine whether a platform supports asynchronous callout, the class EsAsynchronousCallout can be sent the message supported, which returns true if the platform supports asynchronous callout and false if it does not.
Additionally, the image must have adequate fixed space allocated to allow asynchronous calls to be made.
The resources (that is, the thread and fixed-space memory) are managed by the ACO resource manager (AcoResourceManager). The manager improves performance by caching resources that are expensive to create (the thread) or are not collectable by garbage collection (the fixed-space memory).
When using standard asynchronous protocols (asyncCall...) or resource future protocols (futureCall...), the resources are managed automatically through the resource manager. Static future protocols (staticFutureCall:...) permit the resources to be managed manually, but still require the resource manager.
The resource manager allows developers to control how operating system threads and fixed-space resources are managed. The resource manager allows you to control the resources using the following selectors:
An asynchronous call can have problems with resources by either:
If resources are lost during a call, an AcoError is returned from the asynchronous call indicating that the resources associated with the asynchronous call were lost.
Note: | If you save an image, all the calls proceed normally in the running image. However, when you load the saved image, the threads for the asynchronous calls have been terminated, and the asynchronous calls indicate that they have lost their resources. |
The three different types of asynchronous calls can fail to acquire resources if one of these conditions is true:
Depending on the type of asynchronous call, there are different responses to the failure to acquire resources. Calls using asyncCall or futureCall are automatically queued, on a first-come, first-serve basis, until the resources become available. As a result, standard asynchronous calls and resource future calls are delayed if there are not enough resources. Calls using the staticFutureCall: method answer an AcoError indicating that the resources cannot be allocated.
The AcoResourceManager and AcoStaticFutures let the developer maintain the thread an asynchronous call is made in. This is important for allowing more than one call to be made in the same thread. For example, getting the last error is thread-specific and must be guaranteed to occur in the same thread as the call that generated the error.
AcoResourceManager lets you specify a set of calls to be made in the same thread, using the lockThreadIn: aBlock protocol. All the calls using asyncCall performed in aBlock are made in the same thread. The resources are reserved exclusively for calls made in this block until the block finishes executing.
An AcoStaticFuture explicitly acquires and releases its threads. Between the time that an AcoStaticFuture acquires a thread and releases it, its thread is reserved for exclusive use by that future.
Instances of both AcoResourceFuture and AcoStaticFuture are unaffected by lockThreadIn: aBlock. The resources they acquire and release are independent of the resources held by the lock.