Thread::Apartment

SUMMARY: CONSTR | METHOD | DETAIL: CONSTR | METHOD

## Class Thread::Apartment

Provides apartment threading wrapper to encapsulate Perl objects in their own apartment thread.

Licensed under the Academic Free License version 2.1, as specified in the License.txt file included in this software package, or at OpenSource.org.

Author:
  D. Arnold
Version:
  0.50
Since:
  2005-12-01

Unless otherwise noted, `$self` is the object instance variable.

Exported Symbols
`start` | async method/closure request method
`rendezvous` | method to wait for completion of async method/closure calls
`rendezvous_any` | method to wait for completion of async method/closure calls
`rendezvous_until` | method to wait for completion of async method/closure calls
`rendezvous_any_until` | method to wait for completion of async method/closure calls

Constructor Summary
`new(AptClass => value, AptMaxPending => value, AptQueue => value, AptTimeout => value, AptParams => value, AptReentrant => value, AptAutoload => value, AptClosureCalls => value)` Factory method to create an instance of a class in an apartment thread

Method Summary
`CLONE()` ithreads CLONE() method to cleanup context when a new thread is spawned
`add_mapped_object($objid, $tac, $result, $isa, $methods)` (class method) Add an object to the object map
`add_object_reference($objid)` Increment the reference count for an object
`alloc_mapped_object()` (class method) Allocate a unique object ID
`create_pool(AptMaxPending => value, AptPoolSize => value)` (class method) Create a thread pool for apartment threaded objects
`destroy_object($objecid)` (class method) Destroy a mapped object
`destroy_pool()` (class method) Stop and remove all threads
`evict_objects()` (class method) Evict the current resident objects from the apartment thread
`free_thread()` (class method) Return a thread to the pool
`get_autoload()` (class method) Get current autoload setting
`get_closure($sig, $id)` (class method) Return the closure for a specified closure ID
`get_closure_behavior()` (class method) Get current closure call behaviors
`get_factory()` (class method) Factory constructor
`get_object_by_id($objid)` (class method) Return the object for a specified object ID
`get_object_methods($objid)` (class method) Return the hash map of method names to simplex/urgent flags for a specified object ID
`get_pending_request($tac)` (class method) Return the pending request ID for the input TAC
`get_reentrancy()` (class method) Get current re-entrancy setting
`get_tac_for_object($object)` (class method) Return the TAC for a mapped object
`install(AptClass => value, AptMaxPending => value, AptQueue => value, AptTimeout => value, AptParams => value, AptReentrant => value, AptAutoload => value, AptClosureCalls => value)` (class method) Install an object into the current thread
`map_async_request_id($key, $tac, $id)` (class method) Map a TAC to a async method/closure request ID
`register_closure($closure, $flags)` (class method) Registers a closure with the apartment thread before it is passed to another thread as either a parameter, or as a return value
`remove_thread()` (class method) Remove a thread from the pool
`rendezvous(@tac_list)` (class method) Wait for completion of pending method/closure requests on all of the specified TACs/closures
`rendezvous_any(@tac_list)` (class method) Wait for completion of pending method/closure requests on any of the specified TACs
`rendezvous_any_until($timeout, @tac_list)` (class method) Wait upto to $timeout seconds for completion of pending method/closure requests on any of the specified TACs
`rendezvous_until($timeout, @tac_list)` (class method) Wait upto to $timeout seconds for completion of pending method/closure requests on all of the specified TACs
`run()` (class method) Thread governor for installed objects
`run_wait($pendingq, $call_id, $timeout)` (class method) Intermediate thread governor for re-entrant method calls
`set_autoload($autoload)` (class method) Set autoload flag
`set_closure_behavior($behavior)` (class method) Set closure call behaviors
`set_reentrancy($reentrancy)` (class method) Set re-entrancy flag
`set_single_threaded()` (class method) Class method to force single threading
`start($tac_or_closure)` (class method) Starts an asynchronous method or closure call
`stop()` Stop and remove a thread

Constructor Details

### new

    new(AptClass => value, AptMaxPending => value, AptQueue => value, AptTimeout => value, AptParams => value, AptReentrant => value, AptAutoload => value, AptClosureCalls => value)

  Factory method to create an instance of a class in an apartment thread. Produces a client proxy version as the return value. If set_single_threaded() has been called, then acts as a simple factory returning an instance of the class without installing in an apartment thread (useful for debugging purposes).

  The caller may supply a TQD ( and hence, the apartment thread) to be used as the communications channel between the apartment thread and client proxy instances. If not provided, either a thread and TQD are allocated from the existing pool (see create_pool()), or, if no pooled threads are available, a new apartment thread and TQD are created, in which to install the created object. By supplying a TQD, the application can create a pool of threads and TQDs as early as possible with the least context neccesary, and then allocate them to apartment threads as needed. However, the create_pool() method may be simpler for most applications.

  Some default behaviors of the object(s) created/installed in the apartment thread may be directed using the AptReentrant, AptAutoload, or AptClosureCalls parameters (see below).

  Parameters:
    `AptClass` => class to be instantiated into an apartment thread
    `AptMaxPending` => (optional) passed throught to any TQD created for the thread
    `AptQueue` => (optional) Thread::Queue::Duplex to be used to communicate to the proxied object(s)
    `AptTimeout` => (optional) timeout (in seconds) for responses to any non-simplex proxied method call.
    `AptParams` => (optional) arrayref or hashref of parameters required for the proxied class's constructor (if the object requires something other than a hash for constructor parameters)
    `AptReentrant` => (optional) boolean indicating whether the objects in the apartment thread should permit re-entrancy (i.e., handle inbound method calls) while waiting for the results of outbound calls to other T::A objects; default is undef (false).
    `AptAutoload` => (optional) boolean indicating whether the objects in the apartment thread should permit any method call, rather than be restricted to introspected, public methods. Default is undef (false).
    `AptClosureCalls` => (optional) scalar string, or arrayref of strings, indicating whether proxied closures called from objects in the apartment should be treated as 'Simplex', 'Urgent', or both. Default is undef (duplex, non-urgent). Valid (case-insensitive) values are 'Simplex', 'Urgent', or an arrayref containing either or both of those values.
  Returns:
    Thread::Apartment::Client object

Method Details

### CLONE

    CLONE()

  ithreads CLONE() method to cleanup context when a new thread is spawned.

### add_mapped_object

    add_mapped_object($objid, $tac, $result, $isa, $methods)

  (class method) Add an object to the object map

  Parameters:
    `$objid` - object ID
    `$tac` - the TAC (or possibly TACo) for the object
    `$result` - the object to map
    `$isa` - the class hierarchy of the object
    `$methods` - the method name map for the object
  Returns:
    TAC for the object

### add_object_reference

    add_object_reference($objid)

  Increment the reference count for an object.

  Parameters:
    `$objid` - object ID
  Returns:
    the object's new reference count

### alloc_mapped_object

    alloc_mapped_object()

  (class method) Allocate a unique object ID. ID's are indexes into the object ID map array; a scan of the array is performed to locate the first free entry. If no free entries remain, the array is extended.

  Returns:
    the object ID

### create_pool

    create_pool(AptMaxPending => value, AptPoolSize => value)

  (class method) Create a thread pool for apartment threaded objects. Useful for limiting the amount of context cloned into apartment threads. By creating a pool of threads before `require`'ing any modules, the threads will have minimal context before the apartment thread objects are installed into them.

  Parameters:
    `AptMaxPending` => used to set MaxPending on created TQD's.
    `AptPoolSize` => the number of threads to create in the pool
  Returns:
    number of threads created

### destroy_object

    destroy_object($objecid)

  (class method) Destroy a mapped object. Decrements the object's external reference count. If the reference count drops to zero, removes the object from the object map.

  Parameters:
    `$objecid` - object ID
  Returns:
    1 if the ID is for the root object; undef otherwise

### destroy_pool

    destroy_pool()

  (class method) Stop and remove all threads

  Returns:
    1

### evict_objects

    evict_objects()

  (class method) Evict the current resident objects from the apartment thread.

  Returns:
    undef

### free_thread

    free_thread()

  (class method) Return a thread to the pool. Called within the thread to be returned.

  Returns:
    1

### get_autoload

    get_autoload()

  (class method) Get current autoload setting.

  Returns:
    autoload flag value

### get_closure

    get_closure($sig, $id)

  (class method) Return the closure for a specified closure ID.

  Parameters:
    `$sig` - closure signature (used to reject stale closures when an appartment thread is recycled)
    `$id` - closure ID
  Returns:
    if the signature and ID match, the closure; undef otherwise

### get_closure_behavior

    get_closure_behavior()

  (class method) Get current closure call behaviors

  Returns:
    closure call behaviors bitmask

### get_factory

    get_factory()

  (class method) Factory constructor. Creates a factory object for Thread::Apartment (useful for apps which may subclass T::A in future)

  Returns:
    T::A object

### get_object_by_id

    get_object_by_id($objid)

  (class method) Return the object for a specified object ID.

  Parameters:
    `$objid` - object ID
  Returns:
    the object

### get_object_methods

    get_object_methods($objid)

  (class method) Return the hash map of method names to simplex/urgent flags for a specified object ID.

  Parameters:
    `$objid` - object ID
  Returns:
    hashref mapping method names to behavior flags

### get_pending_request

    get_pending_request($tac)

  (class method) Return the pending request ID for the input TAC. Called from TAC::get_pending_results() to recover the pending request ID. Causes the TAC and request ID to be removed from the TAC map.

  Parameters:
    `$tac` - TAC for which the pending request ID is to be returned
  Returns:
    undef if the input TAC has no pending requests; otherwise, the request id

### get_reentrancy

    get_reentrancy()

  (class method) Get current re-entrancy setting.

  Returns:
    re-entrancy flag value

### get_tac_for_object

    get_tac_for_object($object)

  (class method) Return the TAC for a mapped object

  Parameters:
    `$object` - the object (not the object ID!)
  Returns:
    TAC for the object

### install

    install(AptClass => value, AptMaxPending => value, AptQueue => value, AptTimeout => value, AptParams => value, AptReentrant => value, AptAutoload => value, AptClosureCalls => value)

  (class method) Install an object into the current thread. Similar to new(), except that the current thread is converted to an apartment thread, rather than creating a new thread (or allocating one from a thread pool). Useful for some legacy packages (e.g., Perl/Tk).

  Whereas new() creates a new instance of a class and installs it in another thread, which immediately begins monitoring the TQD channel for proxied method calls, `install()` creates a new instance of a class and installs it in the current thread, returning a TACo, which references both the actual created object, and its TAC, so the installed object can be invoked within the current thread, yet still be distributed to other apartment threaded objects.

  When an application needs to pass an `install()`ed object to other threads, it has 2 options:

  1. The TAC objects to receive a reference to the installed object must be passed to the installed object constructor, and implement a known method which the installed object calls to supply its own TAC. The resulting tight coupling requires additional wrappers or subclassing for use by POPOs and legacy classes.

  2. Alternately, install() simply returns a TACo for the installed object (rather than its TAC, as for new()), and the main flow of the application can distribute the TACo object to the other apartment threaded objects as needed. Once the installed object is fully distributed, and any other initialization is completed, the main flow simply calls Thread::Apartment::run() method, which assumes control of the current thread. The resulting loosely coupled component based architecture simplifies the assembly of apartment threaded objects, and is more easily supported by POPO's and legacy objects.

  Parameters:
    `AptClass` => class to be instantiated into an apartment thread
    `AptMaxPending` => (optional) passed throught to any TQD created for the thread
    `AptQueue` => (optional) Thread::Queue::Duplex to be used to communicate to the proxied object(s)
    `AptTimeout` => (optional) timeout (in seconds) for responses to any non-simplex proxied method call.
    `AptParams` => (optional) arrayref or hashref of parameters required for the proxied class's constructor
    `AptReentrant` => (optional) boolean indicating whether the objects in the apartment thread should permit re-entrancy (i.e., handle inbound method calls) while waiting for the results of outbound calls to other T::A objects; default is undef (false).
    `AptAutoload` => (optional) boolean indicating whether the objects in the apartment thread should permit any method call, rather than be restricted to introspected, public methods. Default is undef (false).
    `AptClosureCalls` => (optional) scalar string, or arrayref of strings, indicating whether proxied closures called from objects in the apartment thread should be treated as 'Simplex', 'Urgent', or both. Default is undef (duplex, non-urgent). Valid (case-insensitive) values are 'Simplex', 'Urgent', or an arrayref containing either or both of those values.
  In scalar context, returns:
    nothing
  In list context, returns:
    (nothing )

### map_async_request_id

    map_async_request_id($key, $tac, $id)

  (class method) Map a TAC to a async method/closure request ID. Called by a TAC when the async request has been initiated.

  Parameters:
    `$key` - TAC or closure being mapped
    `$tac` - TAC to map to async request id
    `$id` - request id
  Returns:
    The TAC object.

### register_closure

    register_closure($closure, $flags)

  (class method) Registers a closure with the apartment thread before it is passed to another thread as either a parameter, or as a return value. Unlike a closure, the returned Thread::Apartment::Closure aka TACl object is suitable for marshalling across threads.

  When another thread receives the TACl it will unmarshall it as a local closure that invokes a special method on the originating thread's TAC, which in turn will cause the originating thread to invoke the locally registered closure.

  Parameters:
    `$closure` - closure to be registered
    `$flags` - bitmask of flags indicating simplex and/or urgent behavior (see Thread::Apartment::Common for bitmask values)
  Returns:
    Thread::Apartment::Closure object.

### remove_thread

    remove_thread()

  (class method) Remove a thread from the pool. Called within the thread to be returned.

  Returns:
    1

### rendezvous

    rendezvous(@tac_list)

  (class method) Wait for completion of pending method/closure requests on all of the specified TACs/closures. If no TACs/closures are specified, waits for all TACs/closures currently in the async TAC map. Returns when the pending requests are completed, using the Thread::Queue::Duplex `wait_all()` class method.

  Note that the application is responsible for calling get_pending_results() on the appropriate TACs to get any method/closure return values.

  For closures, the input parameter is the closure

  Parameters:
    `@tac_list` - (optional) list of TACs or closures to wait for; default is all pending TACs
  Returns:
    list of TACs that have rendezvoused; note that closures will be replaced by an appropriate TAC

### rendezvous_any

    rendezvous_any(@tac_list)

  (class method) Wait for completion of pending method/closure requests on any of the specified TACs. If no TACs are specified, waits for any TACs currently in the async TAC map. Returns when the pending requests are completed, using the Thread::Queue::Duplex `wait_any()` class method.

  Note that the application is responsible for calling get_pending_results() on the appropriate TACs to get any method/closure return values.

  For closures, the input TAC parameter is the TAC returned by start().

  Parameters:
    `@tac_list` - (optional) list of TACs to wait for; default is all pending TACs
  Returns:
    list of TACs that have rendezvoused

### rendezvous_any_until

    rendezvous_any_until($timeout, @tac_list)

  (class method) Wait upto to $timeout seconds for completion of pending method/closure requests on any of the specified TACs. If no TACs are specified, waits for any TACs currently in the async TAC map. Returns when the pending requests are completed, or the timeout has expired, using the Thread::Queue::Duplex `wait_all_until()` class method.

  Note that the application is responsible for calling get_pending_results() on the appropriate TACs to get any method/closure return values.

  For closures, the input TAC parameter is the TAC returned by start().

  Parameters:
    `$timeout` - timeout in seconds to wait for completion
    `@tac_list` - (optional) list of TACs to wait for; default is all pending TACs
  Returns:
    undef if $timeout expired; otherwise, the list of TACs that have rendezvoused

### rendezvous_until

    rendezvous_until($timeout, @tac_list)

  (class method) Wait upto to $timeout seconds for completion of pending method/closure requests on all of the specified TACs. If no TACs are specified, waits for any TACs currently in the async TAC map. Returns when the pending requests are completed, or the timeout has expired, using the Thread::Queue::Duplex `wait_all_until()` class method.

  Note that the application is responsible for calling get_pending_results() on the appropriate TACs to get any method/closure return values.

  For closures, the input TAC parameter is the TAC returned by start().

  Parameters:
    `$timeout` - timeout in seconds to wait for completion
    `@tac_list` - (optional) list of TACs to wait for; default is all pending TACs
  Returns:
    undef if $timeout expired; otherwise, the list of TACs that have rendezvoused

### run

    run()

  (class method) Thread governor for installed objects

  Returns:
    1

### run_wait

    run_wait($pendingq, $call_id, $timeout)

  (class method) Intermediate thread governor for re-entrant method calls. Used when an object has made a call on another proxied object, but needs to be able to service external calls to itself until the pending call completes.

  Relies on the threads::shared nature of the thread pool map to recover the TQD for the thread in which the re-entrant call is made, and the non-threads::shared nature of the proxied object map to recover the root object.

  Parameters:
    `$pendingq` - TQD of the proxied object with a pending call
    `$call_id` - request ID of the pending call
    `$timeout` - (optional) max. number of seconds to wait for an event
  Returns:
    undef if timeout expires before the pending call returns, or if a STOP, DESTROY on the root object, or evict() call is received. 1 otherwise.

### set_autoload

    set_autoload($autoload)

  (class method) Set autoload flag.

  Parameters:
    `$autoload` - the boolean value for the flag
  Returns:
    previous $autoload_all flag value

### set_closure_behavior

    set_closure_behavior($behavior)

  (class method) Set closure call behaviors

  Parameters:
    `$behavior` - the bitmask of TA_SIMPLEX and/or TA_URGENT values
  Returns:
    previous $closure_calls bitmask value

### set_reentrancy

    set_reentrancy($reentrancy)

  (class method) Set re-entrancy flag.

  Parameters:
    `$reentrancy` - the boolean value for the flag
  Returns:
    previous re-entrancy flag value

### set_single_threaded

    set_single_threaded()

  (class method) Class method to force single threading. Note that this behavior is irreversible.

  Returns:
    nothing

### start

    start($tac_or_closure)

  (class method) Starts an asynchronous method or closure call. Sets the thread-local TAC async flag class variable. When the next proxied TAC method/closure call is invoked within the thread, the TAC will
  1. add itself and the pending method/closure request identifier, to T::A's thread-local async TAC map class variable
  2. clear the TAC async flag
  3. return the TAC for the method/closure request.

  For async method calls, the parameter is the TAC object; for proxied closure calls, the closure is specified. The returned value is the provided TAC or closure, in order to support the following syntax

      my $tac = Thread::Apartment::start($tac)->someMethod(@params);
      my $tac = Thread::Apartment::start($closure)->(@params);

  Parameters:
    `$tac_or_closure` - TAC or closure to be invoked asynchronously
  Returns:
    the input TAC or closure parameter

### stop

    stop()

  Stop and remove a thread

  Simplex
  Returns:
    The object

Generated by psichedoc on Mon Mar 27 08:51:36 2006