TI_ET_User

10 Reputation

One Badge

12 years, 90 days

MaplePrimes Activity


These are replies submitted by TI_ET_User

@acer Understood. This isn't necessarily a simple question to just dive into.  :-)

@acer Understood. This isn't necessarily a simple question to just dive into.  :-)

queryInterrupt is a callback function - it isn't called by the driver code; OpenMaple should call the function.

Since there have been a number of views to this page, I'll provide a bit more information:

The driver program for an OpenMaple application creates a struct of type 'MCallBackVector' (as defined in '<Maple dir>/extern/include/maplec.h', and as described in the OpenMaple documentation).  This struct contains function pointers (with appropriate decorations, also as defined in the header file) that either point to functions defined in the driver or are set to NULL.  The only required non-NULL pointer corresponds to the 'textCallBack' field in this struct.  However, a given application may define functions for any of the other fields in the 'MCallBackVector' struct, provided they satsify the requirements for each callback function as defined in the OpenMaple documentation.

 

An OpenMaple session is started by calling 'StartMaple'.  One of the arguments that is passed to StartMaple is the 'MCallBackVector' struct defined above.  The return value from StartMaple is a handle of type 'MKernelVector'.  This handle must be passed to any subsequent OpenMaple function calls.  (A NULL 'MKernelVector' handle means that OpenMaple could not be launched successfully; the driver program should gracefully handle this state and [probably] exit.)

 

When a call is made to other OpenMaple functions (the call my code most commonly makes is to 'EvalMapleStatement'), OpenMaple responds by calling one or more of the 'callback' functions corresponding to the 'MCallBackVector' that was passed in when 'StartMaple' was initially called.  For example, if I make the call (in pseudocode... actual syntax will depend on the language used to wrap OpenMaple):

  EvalMapleStatement(kv, "2+2;3+3;")

OpenMaple will make two calls to the function corresponding to the 'textCallBack' element in the MCallBackVector' struct, one with text "4" and one with text "6".  (I'm skipping a few details for brevity here.)

Similarly, if I make the call

  EvalMapleStatement(kv, "1/;")

OpenMaple will call the function corresponding to the 'errorCallBack' element (if non-NULL) in 'MCallBackVector' or the 'textCallBack' element (if 'errorCallBack' is NULL in 'MCallBackVector').

If a calculation causes the garbage collector to fire, then OpenMaple will call the function corresponding to the 'statusCallBack' element (if non-NULL) in 'MCallBackVector' or the 'textCallBack' element (if 'statusCallBack' is NULL).

For testing purposes, I defined appropriate callback functions for each of the elements in 'MCallBackVector', and I've been able to verify that OpenMaple does indeed make appropriate calls to each of them... except for the 'queryInterrupt' callback.  For whatever reason, I cannot get OpenMaple to make calls to that callback function (neither in my own code nor in the example C application that ships with the Maple product).  Unless OpenMaple calls the 'queryInterrupt' callback there is no graceful way for my application to a) interrupt a calculation in progress and b) start a new calculation.

This is the source of the question in the original post.  There are a number of ways I can stop OpenMaple in the middle of a calculation and then restart it, though each of them is akin to dissecting a frog with a chainsaw... they get the job done, but they are incredibly messy.  It would be nice to be able to use the built-in mechanism for this purpose... but I can't get it to work.

 

... and that is the point of this question.  Has anyone ever seen OpenMaple make calls to the 'queryInterrupt' callback?  If so, was there anything special in the setup that wasn't obvious from reading the OpenMaple documentation?

queryInterrupt is a callback function - it isn't called by the driver code; OpenMaple should call the function.

Since there have been a number of views to this page, I'll provide a bit more information:

The driver program for an OpenMaple application creates a struct of type 'MCallBackVector' (as defined in '<Maple dir>/extern/include/maplec.h', and as described in the OpenMaple documentation).  This struct contains function pointers (with appropriate decorations, also as defined in the header file) that either point to functions defined in the driver or are set to NULL.  The only required non-NULL pointer corresponds to the 'textCallBack' field in this struct.  However, a given application may define functions for any of the other fields in the 'MCallBackVector' struct, provided they satsify the requirements for each callback function as defined in the OpenMaple documentation.

 

An OpenMaple session is started by calling 'StartMaple'.  One of the arguments that is passed to StartMaple is the 'MCallBackVector' struct defined above.  The return value from StartMaple is a handle of type 'MKernelVector'.  This handle must be passed to any subsequent OpenMaple function calls.  (A NULL 'MKernelVector' handle means that OpenMaple could not be launched successfully; the driver program should gracefully handle this state and [probably] exit.)

 

When a call is made to other OpenMaple functions (the call my code most commonly makes is to 'EvalMapleStatement'), OpenMaple responds by calling one or more of the 'callback' functions corresponding to the 'MCallBackVector' that was passed in when 'StartMaple' was initially called.  For example, if I make the call (in pseudocode... actual syntax will depend on the language used to wrap OpenMaple):

  EvalMapleStatement(kv, "2+2;3+3;")

OpenMaple will make two calls to the function corresponding to the 'textCallBack' element in the MCallBackVector' struct, one with text "4" and one with text "6".  (I'm skipping a few details for brevity here.)

Similarly, if I make the call

  EvalMapleStatement(kv, "1/;")

OpenMaple will call the function corresponding to the 'errorCallBack' element (if non-NULL) in 'MCallBackVector' or the 'textCallBack' element (if 'errorCallBack' is NULL in 'MCallBackVector').

If a calculation causes the garbage collector to fire, then OpenMaple will call the function corresponding to the 'statusCallBack' element (if non-NULL) in 'MCallBackVector' or the 'textCallBack' element (if 'statusCallBack' is NULL).

For testing purposes, I defined appropriate callback functions for each of the elements in 'MCallBackVector', and I've been able to verify that OpenMaple does indeed make appropriate calls to each of them... except for the 'queryInterrupt' callback.  For whatever reason, I cannot get OpenMaple to make calls to that callback function (neither in my own code nor in the example C application that ships with the Maple product).  Unless OpenMaple calls the 'queryInterrupt' callback there is no graceful way for my application to a) interrupt a calculation in progress and b) start a new calculation.

This is the source of the question in the original post.  There are a number of ways I can stop OpenMaple in the middle of a calculation and then restart it, though each of them is akin to dissecting a frog with a chainsaw... they get the job done, but they are incredibly messy.  It would be nice to be able to use the built-in mechanism for this purpose... but I can't get it to work.

 

... and that is the point of this question.  Has anyone ever seen OpenMaple make calls to the 'queryInterrupt' callback?  If so, was there anything special in the setup that wasn't obvious from reading the OpenMaple documentation?

Er... queryInterrupt is part of the 'MCallBackVector' struct, not the MKernelVector struct.  My mistake...

Er... queryInterrupt is part of the 'MCallBackVector' struct, not the MKernelVector struct.  My mistake...

queryInterrupt is a callback function that is passed in to the Maple kernel (via StartMaple) as part of the MKernelVector struct.  The documentation for queryInterrupt states:

 

"This function is called before each Maple statement is executed. In general, this occurs hundreds of times per second. For some operations (notably large integer manipulations), the queryInterrupt function is called every few seconds."

 

My interpretation of this is that the Maple kernel is supposed to call queryInterrupt periodically to see whether the external program has asked for an interrupt.  In the 'omexample.c' example that ships with Maple, the external program sets up a signal handler for the 'SIGINT' (and 'SIGBREAK' on Windows) signal.  The signal handler sets a boolean constant to TRUE when the signal is received, and queryInterrupt checks the value of the constant when called.

 

So, it should be possible to interrupt that program by pressing CTRL-C (or CTRL-Break on Windows)... but the Maple kernel never calls the queryInterrupt callback, so calculations are never interrupted.  (At least, not on my machine.) 

That was the source of my question.  I've never been able to get this feature to work through OpenMaple.  (I don't see queryInterrupt being called at all, much less 'hundreds of times per second'...)

queryInterrupt is a callback function that is passed in to the Maple kernel (via StartMaple) as part of the MKernelVector struct.  The documentation for queryInterrupt states:

 

"This function is called before each Maple statement is executed. In general, this occurs hundreds of times per second. For some operations (notably large integer manipulations), the queryInterrupt function is called every few seconds."

 

My interpretation of this is that the Maple kernel is supposed to call queryInterrupt periodically to see whether the external program has asked for an interrupt.  In the 'omexample.c' example that ships with Maple, the external program sets up a signal handler for the 'SIGINT' (and 'SIGBREAK' on Windows) signal.  The signal handler sets a boolean constant to TRUE when the signal is received, and queryInterrupt checks the value of the constant when called.

 

So, it should be possible to interrupt that program by pressing CTRL-C (or CTRL-Break on Windows)... but the Maple kernel never calls the queryInterrupt callback, so calculations are never interrupted.  (At least, not on my machine.) 

That was the source of my question.  I've never been able to get this feature to work through OpenMaple.  (I don't see queryInterrupt being called at all, much less 'hundreds of times per second'...)

Page 1 of 1