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
startasync method/closure request method
rendezvousmethod to wait for completion of async method/closure calls
rendezvous_anymethod to wait for completion of async method/closure calls
rendezvous_untilmethod to wait for completion of async method/closure calls
rendezvous_any_untilmethod 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