Arnaud -
Are you looking to have a multi-threaded application? One where the main process is running separately from the OTHER process, which is running utterly independently in a separate thread?
I have been working on such a module recently and it is FAR more difficult than I had expected, mainly becuase there is zero documentation on how to write such code, and no indication of what the rules and restriction are for multi-threaded code.
Here is what I have discovered so far:
Coding a multi-threaded object
1. The NVO can NOT declare any instance object that is AutoInstantiated (AI)
2. A multi-threaded (MT) NVO has no access to any object or variable in the
parent exe
3. The NVO can declare but cannot USE any object that includes an AI object
or that accesses a global variable
4. You cannot debug a MT NVO; you must use MessageBoxes
5. When any error occures in the NVO, the entire NVO fails silently and
instantly
6. Can only pass NVOs and primitives as parameters to NVO function from the
parent exe
7. When declared, variables are NOT set to NULL;
you must SetNull (x) manually if you want to use IsNull() in your code
8. Do not use objects from the PFC, use primitives;
example: use datastore, not n_ds
From the parent EXE:
A. You cannot DESTROY the MT NVO, you must use ShareObjectUnRegister
("MT_string_identifier")
B. After calling ShareObjectUnRegister, it takes at least 3 seconds for the
object to actually be destroyed.
C. Cannot use IsValid(), must use SharedObjectGet() to see if the NVO still
exists
Meanwhile, I'm still trying to figure out how to get the NVO to communicate with the parent EXE; i.e. how to do a callback.
Here's the function that invokes the multi-threaded module AutoRpts. The basics are:
// Instance variable in the calling module
CONSTANT STRING AUTORPTS_NAME = "AutoRpts"
//*********************************************************************
// Object : w_cabs_frame
// Function : of_get_autorpt_ptr()
//
// Ancestor : None
// Access : Public
// Arguments : None
//
// Returns : u_nv_autorpt The pointer to the Autorpt NVO
// Throws : None
//
// Description : This function returns the pointer to the AutoRpt
// NVO. It is this NVO that will be used for all
// AutoRpt processing.
//
// How we got here:
// ue_modules
// of_check_AutoRpt (FALSE)
// of_start_autorpt
// of_get_autorpt_ptr
//
//********************************************************************
// Revision History
//
// Developer Date Version Description
// --------- ----------- --------- -------------------------------
// O Knight 20-JAN-2020 4.0.5.181 #2666065: Initial version.
//
//********************************************************************
// COPYRIGHT © 2020 CSG SYSTEMS INTERNATIONAL, INC. AND/OR ITS
// AFFILIATES (“CSG”). ALL RIGHTS RESERVED.
//********************************************************************
errorReturn lret_rc
long ll_rc
string ls_hdr, ls_err
// Since someone is requesting a pointer to the NVO,
// create it if it does not yet exist
lret_rc = SharedObjectGet (AUTORPTS_NAME, inv_autorpt)
IF (lret_rc <> SUCCESS!) THEN
// Multi-threaded invocation
lret_rc = SharedObjectRegister ("u_nv_autorpt", AUTORPTS_NAME)
IF (lret_rc = SUCCESS!) THEN
lret_rc = SharedObjectGet (AUTORPTS_NAME, inv_autorpt)
IF (lret_rc = SUCCESS!) THEN
// The multi-threaded AutoRpts object has been created.
ELSE
ls_hdr = "Error Accessing AutoRpts"
ls_err = "An error occurred while getting a pointer to the " +
"multi-threaded object ~"INV_AUTORPT~". ~r~n~r~n"
IF (lret_rc <> SUCCESS!) THEN
IF (lret_rc = SharedObjectCreateInstanceError!) THEN
ls_err = ls_err + "SharedObjectCreateInstanceError! " + &
"- The local reference to the shared object " + &
"could not be created."
ELSEIF (lret_rc = SharedObjectNotExistsError!) THEN
ls_err = ls_err + "SharedObjectNotExistsError! " + &
" - The instance name has not been registered."
END IF
END IF
END IF
ELSE
ls_hdr = "Error Creating AutoRpts"
ls_err = "An error occurred attempting to create the " + &
"multi-threaded object ~"INV_AUTORPT~". ~r~n~r~n"
CHOOSE CASE lret_rc
CASE SharedObjectExistsError!
ls_err = ls_err + "SharedObjectExistsError! - The " + &
"instance name has already been used."
CASE SharedObjectCreateInstanceError!
ls_err = ls_err + "SharedObjectCreateInstanceError! - " + &
"The object could not be created."
CASE SharedObjectCreatePBSessionError!
ls_err = ls_err + "SharedObjectCreatePBSessionError! - " + &
"The shared object session could not be created."
CASE ELSE
END CHOOSE
END IF
END IF
IF (ls_err <> "") THEN
MessageBox (ls_hdr, ls_err, StopSign!)
gnv_app.of_logit (".")
gnv_app.of_logit (" ----- Error starting INV_AUTORPTS -----")
gnv_app.of_logit (ls_hdr)
gnv_app.of_logit (ls_err)
gnv_app.of_logit (".")
END IF
// Return the pointer to the AutoRpt NVO
RETURN inv_autorpt
Hope this helps,
Olan
https://www.topwizprogramming.com/freecode_runandwait.html
> This program shows how to execute other programs and wait for them to finish before continuing.
I don't want to execute OTHER programs but I want to execute THIS program and have the console wait for it to complete its job.