Dispatch Queue for Object Adapter in Swift

Ice creates a Swift concurrent dispatch queue for each thread pool:

  • the Swift dispatch queue labeled com.zeroc.ice.client is associated with the client thread pool, itself configured using properties with the Ice.ThreadPool.Client prefix.
  • the Swift dispatch queue labeled com.zeroc.ice.server is associated with the server thread pool, itself configured using properties with the Ice.ThreadPool.Server prefix.
  • a Swift dispatch queue labeled com.zeroc.ice.oa.name is associated with the thread pool of object adapter name when this object adapter uses its own thread pool.

This way, all Ice calls executes by Ice thread pools are performed on dispatch queues: request dispatches on your servants, and also various callbacks such as the close connection callback on Connection.

Since Ice uses synchronous dispatches onto dispatch queues, the thread that performs the synchronous dispatch becomes the dispatch queue thread that executes your code. This synchronous dispatch does not trigger extra copying or a context switch.

Retrieving the Client and Server Dispatch Queues in Swift

You can retrieve the Client and Dispatch queue through instance methods on Communicator:

Swift
protocol Communicator {
   func getClientDispatchQueue() throws -> DispatchQueue
   func getServerDispatchQueue() throws -> DispatchQueue
   ...
}

Retrieving an Object Adapter's Dispatch Queue in Swift

You can retrieve an object adapter's dispatch queue by calling getDispatchQueue on this object adapter. For example:

Swift
func op(current: Current) -> throws {
    // schedule async dispatch with barrier on the same dispatch queue
    try current.adapter!.getDispatchQueue().async(flags: .barrier) { ... }
}

This dispatch queue is always the dispatch queue associated with the thread pool used by this object adapter for server-side request dispatches. When an object adapter does not have its own thread pool, getDispatchQueue returns the Server dispatch queue.

For synchronous collocated dispatches, the thread making the invocation is the thread that performs the request dispatch, and Ice does not change the dispatch queue associated with that thread.

For bidirectional dispatches, where Ice dispatches requests using an Object Adapter associated with an outgoing connection (through setAdapter on Connection), the dispatches execute in the Client thread pool and on the Client dispatch queue.

Autorelease Pools in Swift

Ice for Swift is implemented using Ice for C++ through an Objective-C layer, and as a result some calls to Ice for Swift create autorelease objects. In most common situations, you do not need to create your own autorelease pools to cleanup these objects, as Ice automatically creates (and later drains) an autorelease pool when:

  • you call an Ice API that can throw an Ice runtime exception
  • an Object Adapter dispatches a request to your dispatcher/servant
  • you attach a handler to the promise returned by an asynchronous invocation, and configure the promise to execute this handler on the Ice client-thread pool thread (with on: nil)
  • Ice executes a callback you registered such as a heartbeat or close callback on a Connection, or a sent callback for an asynchronous invocation

Furthermore, all dispatch queues created by Ice are configured with the workItem autorelease frequency.