The IDL_IDLBridge object class allows an IDL session to create and control other IDL sessions, each of which runs as a separate process. Each instantiation of an IDL_IDLBridge object corresponds to one such child process. Child processes are controlled by the parent IDL process - the IDL process that created the IDL_IDLBridge objects. IDL_IDLBridge objects support the following operations:
- Exchanging data between the parent IDL process and the child process by copying IDL variables between them using the SetVar and GetVar methods.
- Executing arbitrary IDL commands in the child process. In synchronous operation, the parent IDL session waits for the child to complete the specified task before continuing. In asynchronous operation, the parent IDL session does not wait, and the two processes run in parallel.
- Querying the current status of the child process while it asynchronously executes an IDL command.
- Registering a callback that is called when an asynchronous command finishes execution.
- Aborting a currently running asynchronous command in a child process.
Using these facilities, one or more IDL_IDLBridge child processes can be used to perform work in parallel with each other and with the parent IDL process that starts them.
In general, IDL_IDLBridge child processes do not inherit state information from the parent IDL process. This means that the child process will not have access to data, compiled routines, system variables, or the current working directory of the parent process. The exception to this rule is that IDL_IDLBridge child processes have the same garbage collection enabled/disabled setting as the parent session. For example, if garbage collection is disabled for the parent process, it will also be disabled for the child process.
Note: In IDL Virtual Machine mode, the Execute, GetVar, and SetVar methods to the IDL_IDLBridge object are disabled.
Note: If you have specified an IDL startup file in your preferences, by default it will automatically be executed when the child process is created. To avoid executing the IDL startup file for your bridge, you can simply undefine the IDL_STARTUP environment variable before starting your bridge. For example:
SETENV,'IDL_STARTUP=""'
oBridge = IDL_IDLBridge()
Superclasses
None
Creation
See IDL_IDLBridge::Init.
Properties
Objects of this class have the following properties.
Methods
This class has the following methods:
Examples
About Debugging Child Processes
Debugging a routine running in a child IDL process presents challenges not present when debugging routines running in the main IDL process. Child IDL processes have no direct connection to the parent IDL process. Because of this lack of connection, the following conditions exist:
- The IDL Workbench's debugging tools are not available
- Breakpoints are not honored
- Output from PRINT statements will not appear in the output log
To work around these issues, develop and debug routines in an interactive IDL process before running them in a child process. Once you are ready to test your routines in a child process, consider using one or more of the following approaches:
- Consider writing status and error information generated by the routines in the child process to a text file. This can be easily accomplished by setting the OUTPUT property.
- Display debugging output using DIALOG_MESSAGE rather than PRINT
- Use the IDL_IDLBridge::Status method to check for completion status of the entire routine
Note: For information on how to return HELP information for a child process, see the Examples section of IDL_IDLBridge::GetVar.
Note: On Windows, you can see debug output generated by the IDL_BRIDGE_DEBUG environment variable in the Debug Monitor (DBMON.exe), available with the Windows Platform SDK. Use the IDL_BRIDGE_DEBUG environment variable setting to control the level of debug output detail.
Multiple Child Processes Example
This example lets you create and interact with a number of child processes where each process executes an IDL command asynchronously. This means that multiple IDL child processes can be completing tasks while the main IDL process remains active. This demonstration of the IDL_IDLBridge functionality can be used as a guide when using the IDL_IDLBridge object in your own code.
Tip: You can also investigate the effect of executing commands synchronously by commenting out the NOWAIT keyword in the Execute method call.
This example idlbridge_demo.pro, is located in the examples/doc/bridges subdirectory of the IDL distribution. Run the example procedure by entering idlbridge_demo at the IDL command prompt or view the file in an IDL Editor window by entering .EDIT idlbridge_demo.pro.
Run the program and click Execute to launch an asynchronous child process that plots a surface in another window. Create additional IDL_IDLBridge objects by selecting File > New. Since these processes execute commands asynchronously, you can start and abort one or more processes at will, all while continuing to interact with the main IDL process.
Note that once a process is initiated, the Execute button is desensitized. If it were not desensitized and you clicked Execute a second time (while the initial request was still being processed), execution would halt with the error, “The object’s associated IDL process is currently busy.” All child processes must finish executing one command before the next command is accepted. However, you can continue to interact with the parent process or other child processes while a child process executes a command asynchronously.
Note: You can also check status before calling the Execute method as described in Avoiding Busy Execution Errors.
Note: A second version of this example, idlbridge_demo_object.pro, provides the same functionality without the use of a callback procedure. This requires using timer events to continuously check the IDL_IDLBridge::Status result. See Timer Events for more information on widget timers.
Tiling and Child Image Processing Example
This example displays a very large file (over 15 MB) and lets you explore the tiled image, zooming in or out and panning. It also includes a child process that applies the Roberts edge detection filter to the image data and creates a new 22 MB file. Since the filtering process occurs asynchronously in a child process, the tiling application can continue responding to requests for tile data and display the required tiles.
This example, idlbridge_tilingjp2_doc.pro, is located in the examples/doc/bridges subdirectory of the IDL distribution and calls idlbridge_img_processing.pro. Run the example procedure by entering idlbridge_tilingjp2 at the IDL command prompt or view the file in an IDL Editor window by entering .EDIT idlbridge_tilingjp2.pro.
In this example, the Execute method of the IDL_IDLBridge object is passed a string that contains:
- The name of a procedure (idlbridge_img_processing.pro), which contains the image filtering code
- The JP2 filename, which is a procedure argument
The following lines transfer the variable value using SetVar and launch the idlbridge_img_processing.pro procedure in a child process (oBridge). The command is executed asynchronously due to the NOWAIT keyword.
oBridge.SetVar, 'filename', (*pState).jp2filename
oBridge.Execute, 'idlbridge_img_processing, filename', /NOWAIT
When you run the tiling application (idlbridge_tilingjp2_doc.pro), click the Process Image button to begin filtering the data in the child process. When processing is complete, the filtered image is automatically displayed.
Note: This example relies on an image filename to determine what is to be filtered. If the image data were interactively updated through actions such as command line processing, you could pass the actual image data instead of the filename. You may pass scalar or array variables of numeric or string type to a child process.
Child Processing Distillation Example
This simple widget application (idlbridge_simple_doc.pro) launches the idlbridge_img_processing.pro procedure in a child process just as the previous tiling application does, but provides streamlined code and a simplified interface so that it is easier to follow execution and status retrieval for the IDL_IDLBridge object. Run the example and click Process Image to launch idlbridge_img_processing.pro in a child process.
This example, idlbridge_simple_doc.pro, is located in the examples/doc/bridges subdirectory of the IDL distribution and calls idlbridge_img_processing.pro. Run the example procedure by entering idlbridge_img_processing at the IDL command prompt or view the file in an IDL Editor window by entering .EDIT idlbridge_img_processing.pro.
In this simplified example, it is easier to see how the progress bar (created in the child process) can be controlled from the parent IDL session. Typically, the progress bar base is destroyed when the image processing program finishes. However, if the user aborts the process or if an error halts execution, the end of the image processing program is never reached.
To kill the widget in the child process, you need the widget ID. You could create and update a widget ID variable in the child process, and then destroy the specific widget from a call in the parent process. However, this ties the two programs together. The parent program must know information that is internal to the child process.
Instead of requiring such a connection, you can use a common block. When you assign the value of the widget ID to a common block variable in the child process, you can access this value without having to pass it in from anywhere (either from the parent process or from the child process pState variable). This compartmentalizes processing. The parent process calls a routine in the child process to tell it that its operation was terminated abruptly by the primary process and that it should clean up any state related to it. The child process routine accesses the progress bar widget ID from the common block and cleans up. In the specified programs, notice the following relevant lines:
(*pState).oIDLBridge.Execute, 'idlbridge_img_processing_abort_cleanup'
PRO idlbridge_img_processing_abort_cleanup
COMMON shareWidID, wChildBase
WIDGET_CONTROL, wChildBase, GET_UVALUE=pState
WIDGET_CONTROL, wChildBase, /DESTROY
PTR_FREE, pState
END
Image Processing Child Procedure
The image processing procedure (idlbridge_img_processing.pro), which is called from the tiling application and the simple widget interface, applies a Roberts filter to a given file. It also displays a progress bar to show the completion progress. While the IDL_IDLBridge object can return high level status (aborted, completed, halted with error, executing or idle) for a child process that is executing a command asynchronously, it does not give any indication of what percentage of a child process has been completed.
This image processing program updates the progress bar display throughout child process execution to provide more granular user feedback. Such a display could also provide feedback in a synchronous child process where status information is not available.
This example, idlbridge_img_processing.pro, is located in the examples/doc/bridges subdirectory of the IDL distribution. Run the example procedure by entering idlbridge_img_processing at the IDL command prompt or view the file in an IDL Editor window by entering .EDIT idlbridge_img_processing.pro. It is designed to be called from the previously mentioned tiling application or simple widget interface, but can be run independently once the required JP2 file has been created.
You can use a child process executing a command asynchronously much like a batch file—one that completes processing tasks without any interaction. In such cases, a user interface that relays progress isn’t needed. However, if your application completes background processing that you care about, status updates are useful. This example shows one option for displaying such information if needed.
IDL_IDLBridge Properties
IDL_IDLBridge objects have the following properties.
CALLBACK
The name of a user-defined callback procedure that is automatically called when an asynchronous command is completed. When an asynchronous command is done (completed, aborted, or halted due to an error) the procedure specified by the CALLBACK property is called.
This callback procedure must have the following signature:
PRO BridgeCallbackName, Status, Error, Objref [, Userdata]
where each argument of the BridgeCallbackName procedure is given the following values:
-
Status: An integer value that contains one of the following values:
Value
|
Description
|
ERROR Keyword Contents
|
2
|
Completed command
|
Empty string
|
3
|
Error halted execution
|
Descriptive error string
|
4
|
Aborted execution
|
Abort message
|
Note: Because the Callback is only called when a command ends, values of Status=0 (Idle) or Status=1 (Executing) will never be returned. (See IDL_IDLBridge::Status for a list of possible status values.)
- Error: A string corresponding to any error that may have occurred while executing the command in the child process. As shown in the table above, if Status contains an error status (3), the Error argument returns a descriptive error string. If Status indicates an aborted status (4), Error returns an abort message. Otherwise, the Error argument will be set to an empty string.
- Objref: The object reference to the IDL_IDLBridge object that is associated with the callback.
- Userdata: The value of the USERDATA property. If the USERDATA property has been set, then this argument is required for your callback procedure. If the USERDATA property has not been set, this Userdata argument is optional, and if provided, will be set to an undefined variable.
When the asynchronous command is completed, aborted, or halted due to an error, the child IDL process calls back into the main IDL process. The main IDL process puts a callback event into the callback event queue for the bridge object. The callback queue for this bridge object is flushed (and the CALLBACK procedure or OnCallback method is called) when one of the following occurs:
- The widget event queue is flushed by IDL’s widget event processing
- The user calls WIDGET_EVENT
- The user calls any IDL_IDLBridge method (except Abort)
- The user calls OBJ_DESTROY
OUTPUT
A string supplying the path and name of a file to which messages generated in the child process will be written. By default, any output written by the child process is quietly discarded by the IDL_IDLBridge object, and is not seen by the user. This is useful for debugged production quality code, but can be inconvenient when the code being executed by the child encounters errors, since you cannot see the text of the error messages.
Note: Under UNIX, but not Microsoft Windows, you may also set the OUTPUT keyword to a NULL file string (e.g. OUTPUT=''). In this case, the child process output is not diverted by the IDL_IDLBridge object, and is written by the operating system directly to stdout and stderr, which is usually the user’s tty.
Note: This property can only be set on initialization, not in SetProperty.
USERDATA
A value of any type containing any information you wish. If USERDATA is set, the value contained within the USERDATA property is passed to the CALLBACK procedure after completion of an asynchronous command.
Note: Object references or pointers contained in the USERDATA property are not automatically cleaned up when the IDL_IDLBridge object is destroyed.
IDL_IDLBridge::Init
The IDL_IDLBridge::Init method initializes an IDL_IDLBridge object, which provides a means of controlling the corresponding IDL child process.
Note: Init methods are special life cycle methods, and as such cannot be called outside the context of object creation. This means that in most cases you cannot call the Init method directly. There is one exception to this rule: If you write your own subclass of this class, you can call the Init method from within the Init method of the subclass.
Syntax
Obj = IDL_IDLBridge( PROPERTY=value] )
or
Result = Obj.[IDL_IDLBridge::]Init( [, PROPERTY=value] ) (In a subclass' Init method only)
Arguments
None
Keywords
IDL_IDLBridge::GetProperty
The IDL_IDLBridge::GetProperty procedure method retrieves a property or group of properties for this object.
Syntax
Obj.[IDL_IDLBridge::] GetProperty [, PROPERTY=variable]
Arguments
None
Keywords
IDL_IDLBridge::SetProperty
The IDL_IDLBridge::SetProperty procedure method sets the properties of an IDL_IDLBridge object.
Syntax
Obj.[IDL_IDLBridge::]SetProperty [, PROPERTY=variable]
Arguments
None
Keywords
IDL_IDLBridge::Cleanup
The IDL_IDLBridge::Cleanup procedure method performs all cleanup when the bridge object is destroyed.
Tip: Because of automatic garbage collection, you should not need to manually call the cleanup method. Once the last reference to the object goes away, the cleanup method will automatically be called. However, you may wish to call the cleanup method to force the child process to be destroyed.
When you call Cleanup, the following steps will occur:
- If there is a currently executing asynchronous command, then IDL_IDLBridge::Abort is called
- If there is a pending callback, then the CALLBACK procedure is called
- The child IDL process is destroyed
Syntax
Obj.Cleanup
or
Obj.[IDL_IDLBridge::]Cleanup
Arguments
None.
Keywords
None.
Examples
A program should ensure that a child process executing a command asynchronously has been completed or aborted before the associated IDL_IDLBridge object is destroyed. If you have started a process by calling the IDL_IDLBridge::Execute method with the NOWAIT keyword, you may want to either abort the current command or wait for the process to become idle. For example, for an IDL_IDLBridge object named oIDLBridge, use the following code to abort an executing process:
IF (oIDLBridge.Status() EQ 1) THEN oIDLBridge.Abort
oIDLBridge.Cleanup
If you prefer to wait for the process to reach an idle state before destroying the bridge object, you can use code similar to the following:
WHILE (oIDLBridge.Status() NE 0) DO WAIT, 0.5
oIDLBridge.Cleanup
Note: The IDL_IDLBridge::Status method returns status information for child processes executing commands asynchronously. A child process executing a command synchronously will only return a value of 0 (idle).
IDL_IDLBridge::Execute
The IDL_IDLBridge::Execute procedure method causes the child IDL process to execute a given IDL command. There are two possible modes in which this can be done:
- Synchronous: IDL waits until the child process completes the specified operation before IDL_IDLBridge::Execute returns. This is the default operation.
- Asynchronous: The call to IDL_IDLBridge::Execute returns immediately, and the caller can use the IDL_IDLBridge::Status method to track its progress. In addition, the CALLBACK procedure will be called automatically when the command is completed. Asynchronous operation is specified via the NOWAIT keyword.
Once Execute starts a command, only the IDL_IDLBridge::Status method can interact with the process. You can call IDL_IDLBridge::SetVar or IDL_IDLBridge::GetVar before or after, but not during command execution. Attempting to call ::Execute, ::SetVar or ::GetVar while executing a command will generate an error. For an example of how to avoid such an error, see Avoiding Busy Execution Errors, below.
Note: This method is disabled in IDL Virtual Machine mode.
Syntax
Obj.[IDL_IDLBridge::]Execute, IDLStmt [, /NOWAIT]
Arguments
IDLStmt
A string containing an IDL command to be executed by the child IDL process.
Keywords
NOWAIT
Set this keyword to cause IDL_IDLBridge::Execute to return immediately, rather than waiting for the child process to complete. When NOWAIT is set, the parent IDL process continues to execute in parallel with the child process.
Examples
The following example creates an IDL_IDLBridge object and executes a simple command to display data:
oBridge = IDL_IDLBridge()
oBridge.Execute, 'WINDOW, XSIZE=300, YSIZE=300'
oBridge.Execute, 'TV, DIST(300)'
Note that the argument to the Execute method is always a string containing an IDL command. This command is parsed and executed by the child IDL process in the usual way—much as if it had been entered at the IDL command line by an interactive user.
Avoiding Busy Execution Errors
Calling the Execute, GetVar or SetVar method on a currently executing child process causes the parent IDL process to throw an error. To avoid this condition, use the IDL_IDLBridge::Status method to make sure the child process is in the idle state (0) before calling the Execute method:
if (oBridge.Status() eq 0) then oBridge.Execute, 'IDLStmt'
IDL_IDLBridge::Abort
The IDL_IDLBridge::Abort procedure method causes the asynchronous operation currently being executed by the child IDL process to abort, returning the child to the idle state. This operation is similar to what happens when a user of interactive IDL presses Ctrl+C. If the child process is not currently executing an asynchronous command, the call to Abort is quietly ignored.
Calling Abort returns focus to the level of the calling IDL process, but does not perform any IDL_IDLBridge object cleanup or destruction. The corresponding child process remains responsive to requests for further processing.
Note: An actively executing process should always be aborted before the corresponding IDL_IDLBridge object is destroyed. See IDL_IDLBridge::Cleanup for details.
Note: The call to the Abort method will block IDL execution until it returns.
Syntax
Obj.[IDL_IDLBridge::]Abort
Arguments
None.
Keywords
None.
IDL_IDLBridge::GetVar
The IDL_IDLBridge::GetVar function copies the value of a variable from the child process to the parent process. IDL_IDLBridge::GetVar is subject to the following limitations:
- Only scalar or array variables of numeric or string type can be transferred. Structures, pointers, and object references cannot be transferred.
- The ::GetVar method makes a copy of the data, which may affect performance if the amount of data involved is large. In such cases, the use of shared data files or shared memory (SHMMAP and SHMVAR) may be more efficient.
Note: It is not possible to call GetVar or SetVar when a child process is actively executing a command .
Syntax
Result = Obj.[IDL_IDLBridge::]GetVar(VarName)
Return Value
Returns the value of the variable transferred from the child process.
Arguments
VarName
A string containing the name of the variable to be transferred.
Keywords
None
Examples
oBridge = IDL_IDLBridge()
mriFile= FILEPATH('pdthorax124.jpg', SUBDIRECTORY = ['examples', 'data'])
oBridge.Execute, "READ_JPEG,'" + mrifile + "', data"
imgData = oBridge.GetVar('data')
IIMAGE, imgData
You can also access information about a child process using the HELP procedure. For example:
oBridge.Execute, 'HELP, /FULL, OUTPUT=output'
PRINT, oBridge.GetVar('output')
IDL_IDLBridge::SetVar
The IDL_IDLBridge::SetVar procedure copies the value of a variable from the parent IDL process to the $MAIN$ level of the child process. IDL_IDLBridge::SetVar is subject to the following limitations:
- Only scalar or array variables of numeric or string type can be transferred. Structures, pointers, and object references cannot be transferred.
- The ::SetVar method makes a copy of the data, which may affect performance if the amount of data involved is large. In such cases, the use of shared data files or shared memory (SHMMAP and SHMVAR) may be more efficient.
Note: It is not possible to call GetVar or SetVar when a child process is actively executing a command (when IDL_IDLBridge::Status equals 1).
Syntax
Obj.[IDL_IDLBridge::]SetVar, Name, Value
Arguments
Name
A string containing the name of the variable to be set in the child process.
Value
A scalar or array variable of string or numeric type containing the data to be copied to the child process.
Keywords
None
Examples
The following example accesses image data from a JPEG file and passes it to a child process using SetVar.
mriFile= FILEPATH('pdthorax124.jpg', $
SUBDIRECTORY = ['examples', 'data'])
READ_JPEG, mriFile, mriImg
oBridge = IDL_IDLBridge()
oBridge.SetVar, "image", mriImg
oBridge.Execute, "TVSCL, image"
IDL_IDLBridge::Status
The IDL_IDLBridge::Status function method queries the state of an IDL_IDLBridge object. When the NOWAIT keyword is used with IDL_IDLBridge::Execute to execute IDL commands asynchronously, the ::Status method can track the state of the child process.
Syntax
Result = Obj.[IDL_IDLBridge::]Status([ERROR=ErrorString])
Return Value
Returns an integer value indicating the status of the bridge object’s corresponding child process. Descriptive error messages are returned in the ERROR keyword. Possible values are:
Return Value |
Description |
ERROR Keyword Returns
|
0 |
Idle |
Empty string |
1 |
Executing command
|
Empty string |
2 |
Completed command
|
Empty string |
3 |
Error halted execution
|
Descriptive error string
|
4 |
Aborted execution (IDL_IDLBridge::Abort)
|
Abort message |
Arguments
None
Keywords
ERROR
A named variable that will contain a string value corresponding to the error that occurred while executing the command, if any. As shown in the Return Value table above, if IDL_IDLBridge::Status returns an error state (3), the ERROR keyword returns a descriptive error string. If this method returns an aborted status (4), ERROR contains an abort message. If any other status is returned, the ERROR keyword sets its variable to an empty string.
Version History
6.3 |
Introduced |
9.2 |
Obsolete the OPS property
|
See Also