Managing resources
Asynchronous calls are made in a separate operating system thread. When the call is blocked waiting for a resource, only that thread is blocked, not the thread that VA Smalltalk is running in.
To support asynchronous callout, VA Smalltalk manages both the thread and some additional resources in fixed space. The additional resources allow VA Smalltalk and the asynchronous thread to interact.
Minimum required resources
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.
ACO resource manager
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:
cacheSize:, cacheSize
The number of resources to cache. The default is 10 threads.
maximumNumberOfResources:, maximumNumberOfResources
A maximum limit on the number of resources created. On some systems, all the processes compete for a limited set of threads. This value is used to limit the number of threads that Smalltalk acquires for itself. The default is no limit.
limitOfReclaimedFutures:, limitOfReclaimedFutures
The number of futures that are recovered from fixed space when the image starts up. The default is 10.
defaultStackSize:, defaultStackSize
The stack size that threads are created with. The default is 8192 bytes.
defaultPriority:, defaultPriority
The priority that operating system threads run at. This is a value between 1 (lowest priority ) and 7 (highest priority).
Resource limitations
An asynchronous call can have problems with resources by either:
• Losing a resource, for example, when a thread is killed
• Failing to acquire a resource
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:
• The AcoResourceManager has reached the limit set by maximumNumberOfResources:.
• The operating system cannot create additional threads.
• There is no more fixed space available.
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.
Maintaining a thread
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.